lkml.org 
[lkml]   [2020]   [Jan]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 392/639] serial: stm32: Add support of TC bit status check
    Date
    From: Erwan Le Ray <erwan.leray@st.com>

    [ Upstream commit 64c32eab660386f9904bb295a104c9c425e9f8b2 ]

    Adds a check on the Transmission Complete bit status before closing the
    com port. Prevents the port closure before the end of the transmission.
    TC poll loop is moved from stm32_tx_dma_complete to stm32_shutdown
    routine, in order to check TC before shutdown in both dma and
    PIO tx modes.
    TC clear is added in stm32_transmit_char routine, in order to be cleared
    before transmitting in both dma and PIO tx modes.

    Fixes: 3489187204eb ("serial: stm32: adding dma support")
    Signed-off-by: Erwan Le Ray <erwan.leray@st.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/tty/serial/stm32-usart.c | 32 +++++++++++++++-----------------
    1 file changed, 15 insertions(+), 17 deletions(-)

    diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
    index 2e7757d5e5d83..d603be9669a96 100644
    --- a/drivers/tty/serial/stm32-usart.c
    +++ b/drivers/tty/serial/stm32-usart.c
    @@ -290,21 +290,6 @@ static void stm32_tx_dma_complete(void *arg)
    struct uart_port *port = arg;
    struct stm32_port *stm32port = to_stm32_port(port);
    struct stm32_usart_offsets *ofs = &stm32port->info->ofs;
    - unsigned int isr;
    - int ret;
    -
    - ret = readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr,
    - isr,
    - (isr & USART_SR_TC),
    - 10, 100000);
    -
    - if (ret)
    - dev_err(port->dev, "terminal count not set\n");
    -
    - if (ofs->icr == UNDEF_REG)
    - stm32_clr_bits(port, ofs->isr, USART_SR_TC);
    - else
    - stm32_set_bits(port, ofs->icr, USART_CR_TC);

    stm32_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
    stm32port->tx_dma_busy = false;
    @@ -396,7 +381,6 @@ static void stm32_transmit_chars_dma(struct uart_port *port)
    /* Issue pending DMA TX requests */
    dma_async_issue_pending(stm32port->tx_ch);

    - stm32_clr_bits(port, ofs->isr, USART_SR_TC);
    stm32_set_bits(port, ofs->cr3, USART_CR3_DMAT);

    xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1);
    @@ -425,6 +409,11 @@ static void stm32_transmit_chars(struct uart_port *port)
    return;
    }

    + if (ofs->icr == UNDEF_REG)
    + stm32_clr_bits(port, ofs->isr, USART_SR_TC);
    + else
    + stm32_set_bits(port, ofs->icr, USART_ICR_TCCF);
    +
    if (stm32_port->tx_ch)
    stm32_transmit_chars_dma(port);
    else
    @@ -601,12 +590,21 @@ static void stm32_shutdown(struct uart_port *port)
    struct stm32_port *stm32_port = to_stm32_port(port);
    struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
    struct stm32_usart_config *cfg = &stm32_port->info->cfg;
    - u32 val;
    + u32 val, isr;
    + int ret;

    val = USART_CR1_TXEIE | USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;
    val |= BIT(cfg->uart_enable_bit);
    if (stm32_port->fifoen)
    val |= USART_CR1_FIFOEN;
    +
    + ret = readl_relaxed_poll_timeout(port->membase + ofs->isr,
    + isr, (isr & USART_SR_TC),
    + 10, 100000);
    +
    + if (ret)
    + dev_err(port->dev, "transmission complete not set\n");
    +
    stm32_clr_bits(port, ofs->cr1, val);

    dev_pm_clear_wake_irq(port->dev);
    --
    2.20.1


    \
     
     \ /
      Last update: 2020-01-24 12:41    [W:3.114 / U:0.124 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site