lkml.org 
[lkml]   [2022]   [Aug]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.19 0899/1157] serial: 8250: Create serial_lsr_in()
    Date
    From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>

    [ Upstream commit bdb70c424df1543bc02ee2639aecebd20318c599 ]

    LSR register readers need to be careful in order to not lose bits that
    are not preserved across reads. Create a helper that takes care of
    storing the non-preserved bits into lsr_save_flags.

    Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
    Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
    Link: https://lore.kernel.org/r/20220608095431.18376-3-ilpo.jarvinen@linux.intel.com
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/tty/serial/8250/8250.h | 20 ++++++++++++++++++++
    drivers/tty/serial/8250/8250_core.c | 3 +--
    drivers/tty/serial/8250/8250_port.c | 15 ++++-----------
    3 files changed, 25 insertions(+), 13 deletions(-)

    diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
    index 696030cfcb09..c89cb881d9b0 100644
    --- a/drivers/tty/serial/8250/8250.h
    +++ b/drivers/tty/serial/8250/8250.h
    @@ -123,6 +123,26 @@ static inline void serial_out(struct uart_8250_port *up, int offset, int value)
    up->port.serial_out(&up->port, offset, value);
    }

    +/**
    + * serial_lsr_in - Read LSR register and preserve flags across reads
    + * @up: uart 8250 port
    + *
    + * Read LSR register and handle saving non-preserved flags across reads.
    + * The flags that are not preserved across reads are stored into
    + * up->lsr_saved_flags.
    + *
    + * Returns LSR value or'ed with the preserved flags (if any).
    + */
    +static inline unsigned int serial_lsr_in(struct uart_8250_port *up)
    +{
    + unsigned int lsr = up->lsr_saved_flags;
    +
    + lsr |= serial_in(up, UART_LSR);
    + up->lsr_saved_flags = lsr & LSR_SAVE_FLAGS;
    +
    + return lsr;
    +}
    +
    /*
    * For the 16C950
    */
    diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
    index 3f56dbc9432b..82726cda6066 100644
    --- a/drivers/tty/serial/8250/8250_core.c
    +++ b/drivers/tty/serial/8250/8250_core.c
    @@ -277,8 +277,7 @@ static void serial8250_backup_timeout(struct timer_list *t)
    * the "Diva" UART used on the management processor on many HP
    * ia64 and parisc boxes.
    */
    - lsr = serial_in(up, UART_LSR);
    - up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
    + lsr = serial_lsr_in(up);
    if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) &&
    (!uart_circ_empty(&up->port.state->xmit) || up->port.x_char) &&
    (lsr & UART_LSR_THRE)) {
    diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
    index 3c36a06a20b0..c9d8c0de56e5 100644
    --- a/drivers/tty/serial/8250/8250_port.c
    +++ b/drivers/tty/serial/8250/8250_port.c
    @@ -1514,11 +1514,9 @@ static inline void __stop_tx(struct uart_8250_port *p)
    struct uart_8250_em485 *em485 = p->em485;

    if (em485) {
    - unsigned char lsr = serial_in(p, UART_LSR);
    + unsigned char lsr = serial_lsr_in(p);
    u64 stop_delay = 0;

    - p->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
    -
    if (!(lsr & UART_LSR_THRE))
    return;
    /*
    @@ -1573,10 +1571,8 @@ static inline void __start_tx(struct uart_port *port)

    if (serial8250_set_THRI(up)) {
    if (up->bugs & UART_BUG_TXEN) {
    - unsigned char lsr;
    + unsigned char lsr = serial_lsr_in(up);

    - lsr = serial_in(up, UART_LSR);
    - up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
    if (lsr & UART_LSR_THRE)
    serial8250_tx_chars(up);
    }
    @@ -2007,8 +2003,7 @@ static unsigned int serial8250_tx_empty(struct uart_port *port)
    serial8250_rpm_get(up);

    spin_lock_irqsave(&port->lock, flags);
    - lsr = serial_port_in(port, UART_LSR);
    - up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
    + lsr = serial_lsr_in(up);
    spin_unlock_irqrestore(&port->lock, flags);

    serial8250_rpm_put(up);
    @@ -2084,9 +2079,7 @@ static void wait_for_lsr(struct uart_8250_port *up, int bits)

    /* Wait up to 10ms for the character(s) to be sent. */
    for (;;) {
    - status = serial_in(up, UART_LSR);
    -
    - up->lsr_saved_flags |= status & LSR_SAVE_FLAGS;
    + status = serial_lsr_in(up);

    if ((status & bits) == bits)
    break;
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-08-16 02:42    [W:2.725 / U:1.644 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site