This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

PROCESSOR-SDK-AM335X: Possible bug in 8250_omap UART driver

Part Number: PROCESSOR-SDK-AM335X

Hi everyone,

I'm working with ti-linux-kernel 6.1.46 on AM335x (BeagleBone Black) and I'd like to understand if the following is a bug or not:

When calling serdev_device_open, then serdev_device_close several times relatively back-to-back I see a warning from omap_8250_rx_dma_flush when pausing the DMA. Looking deeper I see that edma_dma_pause returns -EINVAL  as there is no active descriptor (as far as I can tell). Digging some more I think what happens is that flag dma->rx_running in 8250_omap is being left high when omap_8250_shutdown returns:

omap_8250_shutdown()
    omap_8250_rx_dma_flush()
        __dma_rx_do_complete()
            ...
            dma->rx_running = 0;
    ....
    pm_runtime_get_sync()
        omap8250_runtime_resume()   /* Might get called depending on driver state */
            omap_8250_rx_dma()
                dma->rx_running = 1;
    ...
    /* more shutdown code */

   
When omap_8250_rx_dma will be called then next time the UART is opened, it will terminate early without actually submitting the DMA request and subsequent flush will fail as mentioned above.

Is this a real issue or am I missing something?

Thanks and regards,
Michael.

  • Hi Michael,

    Let me review the driver and get back to you. I will likely get into this mid next week.

  • Hi Bin,

    Have you by any chance had time to look at this?

    Thanks and regards,
    Michael.

  • Hi Michael,

    omap_8250_shutdown()
            omap8250_runtime_resume()   /* Might get called depending on driver state */
                dma->rx_running = 1;

    Have you confirmed that dma->rx_running is set to 1 in omap8250_runtime_resume() by omap_8250_shutdown()?

    If so, can you please try if the follow patch resolves the problem?

    diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
    index adc85e250822..8ae32c63d5eb 100644
    --- a/drivers/tty/serial/8250/8250_omap.c
    +++ b/drivers/tty/serial/8250/8250_omap.c
    @@ -731,12 +731,12 @@ static void omap_8250_shutdown(struct uart_port *port)
            struct uart_8250_port *up = up_to_u8250p(port);
            struct omap8250_priv *priv = port->private_data;
     
    +       pm_runtime_get_sync(port->dev);
    +
            flush_work(&priv->qos_work);
            if (up->dma)
                    omap_8250_rx_dma_flush(up);
     
    -       pm_runtime_get_sync(port->dev);
    -
            serial_out(up, UART_OMAP_WER, 0);
            if (priv->habit & UART_HAS_EFR2)
                    serial_out(up, UART_OMAP_EFR2, 0x0);

  • Hi Bin,

    Yes, I've confirmed that dma->rx_running is set and yes, the above patch seems to resolve the issue.

    Thanks!
    Michael.

  • Hi Michael,

    Thanks for the confirmation. I will report the problem to our sw dev team with the proposed solution.