struct tasklet_struct tasklet;
unsigned int irq_status;
unsigned int irq_status_prev;
+ unsigned int status_change;
struct circ_buf rx_ring;
if (pending & (ATMEL_US_RIIC | ATMEL_US_DSRIC | ATMEL_US_DCDIC
| ATMEL_US_CTSIC)) {
atmel_port->irq_status = status;
+ atmel_port->status_change = atmel_port->irq_status ^
+ atmel_port->irq_status_prev;
+ atmel_port->irq_status_prev = status;
tasklet_schedule(&atmel_port->tasklet);
}
}
{
struct uart_port *port = (struct uart_port *)data;
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
- unsigned int status;
- unsigned int status_change;
+ unsigned int status = atmel_port->irq_status;
+ unsigned int status_change = atmel_port->status_change;
/* The interrupt handler does not take the lock */
spin_lock(&port->lock);
atmel_port->schedule_tx(port);
- status = atmel_port->irq_status;
- status_change = status ^ atmel_port->irq_status_prev;
-
if (status_change & (ATMEL_US_RI | ATMEL_US_DSR
| ATMEL_US_DCD | ATMEL_US_CTS)) {
/* TODO: All reads to CSR will clear these interrupts! */
wake_up_interruptible(&port->state->port.delta_msr_wait);
- atmel_port->irq_status_prev = status;
+ atmel_port->status_change = 0;
}
atmel_port->schedule_rx(port);