lkml.org 
[lkml]   [2019]   [Dec]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.3 009/105] tty: serial: msm_serial: Fix flow control
    Date
    From: Jeffrey Hugo <jeffrey.l.hugo@gmail.com>

    commit b027ce258369cbfa88401a691c23dad01deb9f9b upstream.

    hci_qca interfaces to the wcn3990 via a uart_dm on the msm8998 mtp and
    Lenovo Miix 630 laptop. As part of initializing the wcn3990, hci_qca
    disables flow, configures the uart baudrate, and then reenables flow - at
    which point an event is expected to be received over the uart from the
    wcn3990. It is observed that this event comes after the baudrate change
    but before hci_qca re-enables flow. This is unexpected, and is a result of
    msm_reset() being broken.

    According to the uart_dm hardware documentation, it is recommended that
    automatic hardware flow control be enabled by setting RX_RDY_CTL. Auto
    hw flow control will manage RFR based on the configured watermark. When
    there is space to receive data, the hw will assert RFR. When the watermark
    is hit, the hw will de-assert RFR.

    The hardware documentation indicates that RFR can me manually managed via
    CR when RX_RDY_CTL is not set. SET_RFR asserts RFR, and RESET_RFR
    de-asserts RFR.

    msm_reset() is broken because after resetting the hardware, it
    unconditionally asserts RFR via SET_RFR. This enables flow regardless of
    the current configuration, and would undo a previous flow disable
    operation. It should instead de-assert RFR via RESET_RFR to block flow
    until the hardware is reconfigured. msm_serial should rely on the client
    to specify that flow should be enabled, either via mctrl() or the termios
    structure, and only assert RFR in response to those triggers.

    Fixes: 04896a77a97b ("msm_serial: serial driver for MSM7K onboard serial peripheral.")
    Signed-off-by: Jeffrey Hugo <jeffrey.l.hugo@gmail.com>
    Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
    Cc: stable <stable@vger.kernel.org>
    Reviewed-by: Andy Gross <agross@kernel.org>
    Link: https://lore.kernel.org/r/20191021154616.25457-1-jeffrey.l.hugo@gmail.com
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/tty/serial/msm_serial.c | 6 +++++-
    1 file changed, 5 insertions(+), 1 deletion(-)

    --- a/drivers/tty/serial/msm_serial.c
    +++ b/drivers/tty/serial/msm_serial.c
    @@ -980,6 +980,7 @@ static unsigned int msm_get_mctrl(struct
    static void msm_reset(struct uart_port *port)
    {
    struct msm_port *msm_port = UART_TO_MSM(port);
    + unsigned int mr;

    /* reset everything */
    msm_write(port, UART_CR_CMD_RESET_RX, UART_CR);
    @@ -987,7 +988,10 @@ static void msm_reset(struct uart_port *
    msm_write(port, UART_CR_CMD_RESET_ERR, UART_CR);
    msm_write(port, UART_CR_CMD_RESET_BREAK_INT, UART_CR);
    msm_write(port, UART_CR_CMD_RESET_CTS, UART_CR);
    - msm_write(port, UART_CR_CMD_SET_RFR, UART_CR);
    + msm_write(port, UART_CR_CMD_RESET_RFR, UART_CR);
    + mr = msm_read(port, UART_MR1);
    + mr &= ~UART_MR1_RX_RDY_CTL;
    + msm_write(port, mr, UART_MR1);

    /* Disable DM modes */
    if (msm_port->is_uartdm)

    \
     
     \ /
      Last update: 2019-12-11 17:07    [W:3.474 / U:0.232 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site