Beispiel #1
0
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);
}