On 04/12/2016 08:30 AM, Sebastian Andrzej Siewior wrote: > On 04/10/2016 07:14 AM, Peter Hurley wrote: >> --- a/drivers/tty/serial/8250/8250_omap.c >> +++ b/drivers/tty/serial/8250/8250_omap.c >> @@ -812,35 +818,6 @@ static int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir) >> struct dma_async_tx_descriptor *desc; >> unsigned long flags; >> >> - switch (iir & 0x3f) { >> - case UART_IIR_RLSI: >> - /* 8250_core handles errors and break interrupts */ >> - omap_8250_rx_dma_flush(p); >> - return -EIO; >> - case UART_IIR_RX_TIMEOUT: >> - /* >> - * If RCVR FIFO trigger level was not reached, complete the >> - * transfer and let 8250_core copy the remaining data. >> - */ >> - omap_8250_rx_dma_flush(p); >> - return -ETIMEDOUT; >> - case UART_IIR_RDI: >> - /* >> - * The OMAP UART is a special BEAST. If we receive RDI we _have_ >> - * a DMA transfer programmed but it didn't work. One reason is >> - * that we were too slow and there were too many bytes in the >> - * FIFO, the UART counted wrong and never kicked the DMA engine >> - * to do anything. That means once we receive RDI on OMAP then >> - * the DMA won't do anything soon so we have to cancel the DMA >> - * transfer and purge the FIFO manually. >> - */ >> - omap_8250_rx_dma_flush(p); >> - return -ETIMEDOUT; >> - >> - default: >> - break; >> - } >> - >> if (priv->rx_dma_broken) >> return -EINVAL; >> >> @@ -1014,6 +991,18 @@ err: >> return ret; >> } >> >> +static bool handle_rx_dma(struct uart_8250_port *up, unsigned int iir) >> +{ >> + switch (iir & 0x3f) { >> + case UART_IIR_RLSI: >> + case UART_IIR_RX_TIMEOUT: >> + case UART_IIR_RDI: > > So you think that it is not worth to preserve the comments we had here? Well, the UART_IIR_RDI comment is wrong so I didn't want to preserve that, and the UART_IIR_RX_TIMEOUT is the same thing that happens with the base 8250 dma handling as well, so I didn't see the point. The UART_IIR_RDI interrupt happens because: 1) The programmed DMA transfer has completed 2) But the DMA completion handler hasn't run yet because the virt-dma tasklet hasn't run yet because of the softirq priority inversion http://www.gossamer-threads.com/lists/engine?do=post_view_flat;post=2381467;page=1;sb=post_latest_reply;so=ASC;mh=25;list=linux 3) in the meantime, data has continued to arrive until the fifo is refilled which triggers the UART_IIR_RDI Which is ironic because the UART_IIR_RDI is normally what we want to actually happen because that is the dma transaction flow expected by the base 8250 dma handling. > >> + omap_8250_rx_dma_flush(up); >> + return true; >> + } >> + return omap_8250_rx_dma(up); >> +} >> + >> /* >> * This is mostly serial8250_handle_irq(). We have a slightly different DMA >> * hoook for RX/TX and need different logic for them in the ISR. Therefore we > > Sebastian > -- To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html