|
@@ -1727,10 +1727,26 @@ static int pl011_allocate_irq(struct uart_amba_port *uap)
|
|
|
*/
|
|
*/
|
|
|
static void pl011_enable_interrupts(struct uart_amba_port *uap)
|
|
static void pl011_enable_interrupts(struct uart_amba_port *uap)
|
|
|
{
|
|
{
|
|
|
|
|
+ unsigned int i;
|
|
|
|
|
+
|
|
|
spin_lock_irq(&uap->port.lock);
|
|
spin_lock_irq(&uap->port.lock);
|
|
|
|
|
|
|
|
/* Clear out any spuriously appearing RX interrupts */
|
|
/* Clear out any spuriously appearing RX interrupts */
|
|
|
pl011_write(UART011_RTIS | UART011_RXIS, uap, REG_ICR);
|
|
pl011_write(UART011_RTIS | UART011_RXIS, uap, REG_ICR);
|
|
|
|
|
+
|
|
|
|
|
+ /*
|
|
|
|
|
+ * RXIS is asserted only when the RX FIFO transitions from below
|
|
|
|
|
+ * to above the trigger threshold. If the RX FIFO is already
|
|
|
|
|
+ * full to the threshold this can't happen and RXIS will now be
|
|
|
|
|
+ * stuck off. Drain the RX FIFO explicitly to fix this:
|
|
|
|
|
+ */
|
|
|
|
|
+ for (i = 0; i < uap->fifosize * 2; ++i) {
|
|
|
|
|
+ if (pl011_read(uap, REG_FR) & UART01x_FR_RXFE)
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ pl011_read(uap, REG_DR);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
uap->im = UART011_RTIM;
|
|
uap->im = UART011_RTIM;
|
|
|
if (!pl011_dma_rx_running(uap))
|
|
if (!pl011_dma_rx_running(uap))
|
|
|
uap->im |= UART011_RXIM;
|
|
uap->im |= UART011_RXIM;
|