mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-25 05:34:00 +08:00
serial: omap: simplify IRQ handling
quite a few changes here, though they are pretty obvious. In summary we're making sure to detect which interrupt type we need to handle before calling the underlying interrupt handling procedure. Tested-by: Shubhrajyoti D <shubhrajyoti@ti.com> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Signed-off-by: Felipe Balbi <balbi@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
a0f38b87de
commit
81b75aef11
@ -351,33 +351,58 @@ static inline irqreturn_t serial_omap_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct uart_omap_port *up = dev_id;
|
||||
unsigned int iir, lsr;
|
||||
unsigned int type;
|
||||
unsigned long flags;
|
||||
|
||||
pm_runtime_get_sync(up->dev);
|
||||
iir = serial_in(up, UART_IIR);
|
||||
if (iir & UART_IIR_NO_INT) {
|
||||
pm_runtime_mark_last_busy(up->dev);
|
||||
pm_runtime_put_autosuspend(up->dev);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
irqreturn_t ret = IRQ_NONE;
|
||||
|
||||
spin_lock_irqsave(&up->port.lock, flags);
|
||||
pm_runtime_get_sync(up->dev);
|
||||
iir = serial_in(up, UART_IIR);
|
||||
again:
|
||||
if (iir & UART_IIR_NO_INT)
|
||||
goto out;
|
||||
|
||||
ret = IRQ_HANDLED;
|
||||
lsr = serial_in(up, UART_LSR);
|
||||
if (iir & UART_IIR_RLSI) {
|
||||
|
||||
/* extract IRQ type from IIR register */
|
||||
type = iir & 0x3e;
|
||||
|
||||
switch (type) {
|
||||
case UART_IIR_MSI:
|
||||
check_modem_status(up);
|
||||
break;
|
||||
case UART_IIR_THRI:
|
||||
if (lsr & UART_LSR_THRE)
|
||||
transmit_chars(up);
|
||||
break;
|
||||
case UART_IIR_RDI:
|
||||
if (lsr & UART_LSR_DR)
|
||||
receive_chars(up, &lsr);
|
||||
break;
|
||||
case UART_IIR_RLSI:
|
||||
if (lsr & UART_LSR_BRK_ERROR_BITS)
|
||||
receive_chars(up, &lsr);
|
||||
break;
|
||||
case UART_IIR_RX_TIMEOUT:
|
||||
receive_chars(up, &lsr);
|
||||
break;
|
||||
case UART_IIR_CTS_RTS_DSR:
|
||||
iir = serial_in(up, UART_IIR);
|
||||
goto again;
|
||||
case UART_IIR_XOFF:
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
check_modem_status(up);
|
||||
if ((lsr & UART_LSR_THRE) && (iir & UART_IIR_THRI))
|
||||
transmit_chars(up);
|
||||
|
||||
out:
|
||||
spin_unlock_irqrestore(&up->port.lock, flags);
|
||||
pm_runtime_mark_last_busy(up->dev);
|
||||
pm_runtime_put_autosuspend(up->dev);
|
||||
|
||||
up->port_activity = jiffies;
|
||||
return IRQ_HANDLED;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static unsigned int serial_omap_tx_empty(struct uart_port *port)
|
||||
|
Loading…
Reference in New Issue
Block a user