static void ambauart_int(int irq, void *dev_id, struct pt_regs *regs) { struct uart_info *info = dev_id; unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT; status = UART_GET_INT_STATUS(info->port); do { if (status & (AMBA_UARTIIR_RTIS | AMBA_UARTIIR_RIS)) #ifdef SUPPORT_SYSRQ ambauart_rx_chars(info, regs); #else ambauart_rx_chars(info); #endif if (status & AMBA_UARTIIR_TIS) ambauart_tx_chars(info); if (status & AMBA_UARTIIR_MIS) ambauart_modem_status(info); if (pass_counter-- == 0) break; status = UART_GET_INT_STATUS(info->port); } while (status & (AMBA_UARTIIR_RTIS | AMBA_UARTIIR_RIS | AMBA_UARTIIR_TIS)); }
static void ambauart_int(int irq, void *dev_id, struct pt_regs *regs) { struct uart_port *port = dev_id; struct uart_info *info = port->info; unsigned int status, ier, old_ier, count, lsr; old_ier = UART_GET_IER(port); UART_PUT_IER(port, (old_ier & 0xFFFFF0FF)); status = UART_GET_INT_STATUS(port); lsr = UART_GET_LSR(port); /* KS8695_INTMASK_UART_RX is not set during breakpoint as it should (looks * like a HW bug), so we specifically check for a breakpoint condition in * the UART line status register. * Some bits from the UART line status register are cleared only when they * are read by CPU. That is why we cannot read the line status register * twice, and should pass the first read as argument to ambauart_rx_chars. * Refer to CENTAUR KS8695PX's Register Description document: * KS8695PX_REG_DESCP_v1.0.pdf, page 58: "UART Line Status Register". */ if (status & KS8695_INTMASK_UART_RX || lsr & KS8695_UART_LINES_BE) { #ifdef SUPPORT_SYSRQ ambauart_rx_chars(port, regs, lsr); #else ambauart_rx_chars(port, lsr); #endif } if (status & KS8695_INTMASK_UART_TX) { if (port->x_char) { UART_CLR_INT_STATUS(port, KS8695_INTMASK_UART_TX); UART_PUT_CHAR(port, (u_int) port->x_char); port->icount.tx++; port->x_char = 0; ier = UART_GET_IER(port); ier &= 0xFFFFFEFF; UART_PUT_IER(port, ier); printk("XOn/Off sent\n"); return; } for ( count = 0; count < 16; count++) { if (info->xmit.head == info->xmit.tail) { /*ier = UART_GET_IER(port); ier &= 0xFFFFFEFF; UART_PUT_IER(port, ier);*/ break; } UART_CLR_INT_STATUS(port, KS8695_INTMASK_UART_TX); UART_PUT_CHAR(port, (u_int) (info->xmit.buf[info->xmit.tail])); info->xmit.tail = (info->xmit.tail + 1) & (UART_XMIT_SIZE - 1); port->icount.tx++; }; if (CIRC_CNT(info->xmit.head, info->xmit.tail, UART_XMIT_SIZE) < WAKEUP_CHARS) uart_write_wakeup(port); if (info->xmit.head == info->xmit.tail) { ier = UART_GET_IER(port); ier &= 0xFFFFFEFF; UART_PUT_IER(port, ier); } } if (status & KS8695_INTMASK_UART_MODEMS) { ambauart_modem_status(port); } if (status & KS8695_INTMASK_UART_MODEMS) { ambauart_modem_status(port); } if ( status & KS8695_INTMASK_UART_LINE_ERR) { UART_GET_LSR(port); } if (info->xmit.head == info->xmit.tail) UART_PUT_IER(port, (old_ier & 0xFFFFFEFF)); else UART_PUT_IER(port, old_ier | KS8695_INTMASK_UART_TX); }