lkml.org 
[lkml]   [2012]   [Apr]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[ 42/68] serial: PL011: clear pending interrupts
    3.2-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Linus Walleij <linus.walleij@linaro.org>

    commit 9b96fbacda34079dea0638ee1e92c56286f6114a upstream.

    Chanho Min reported that when the boot loader transfers
    control to the kernel, there may be pending interrupts
    causing the UART to lock up in an eternal loop trying to
    pick tokens from the FIFO (since the RX interrupt flag
    indicates there are tokens) while in practice there are
    no tokens - in fact there is only a pending IRQ flag.

    This patch address the issue with a combination of two
    patches suggested by Russell King that clears and mask
    all interrupts at probe() and clears any pending error
    and RX interrupts at port startup time.

    We suspect the spurious interrupts are a side-effect of
    switching the UART from FIFO to non-FIFO mode.

    Cc: Shreshtha Kumar Sahu <shreshthakumar.sahu@stericsson.com>
    Reported-by: Chanho Min <chanho0207@gmail.com>
    Suggested-by: Russell King <linux@arm.linux.org.uk>
    Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
    Reviewed-by: Jong-Sung Kim <neidhard.kim@lge.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/tty/serial/amba-pl011.c | 15 +++++++++++----
    1 file changed, 11 insertions(+), 4 deletions(-)

    --- a/drivers/tty/serial/amba-pl011.c
    +++ b/drivers/tty/serial/amba-pl011.c
    @@ -1380,6 +1380,10 @@ static int pl011_startup(struct uart_por

    uap->port.uartclk = clk_get_rate(uap->clk);

    + /* Clear pending error and receive interrupts */
    + writew(UART011_OEIS | UART011_BEIS | UART011_PEIS | UART011_FEIS |
    + UART011_RTIS | UART011_RXIS, uap->port.membase + UART011_ICR);
    +
    /*
    * Allocate the IRQ
    */
    @@ -1414,10 +1418,6 @@ static int pl011_startup(struct uart_por
    cr = UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE;
    writew(cr, uap->port.membase + UART011_CR);

    - /* Clear pending error interrupts */
    - writew(UART011_OEIS | UART011_BEIS | UART011_PEIS | UART011_FEIS,
    - uap->port.membase + UART011_ICR);
    -
    /*
    * initialise the old status of the modem signals
    */
    @@ -1432,6 +1432,9 @@ static int pl011_startup(struct uart_por
    * as well.
    */
    spin_lock_irq(&uap->port.lock);
    + /* Clear out any spuriously appearing RX interrupts */
    + writew(UART011_RTIS | UART011_RXIS,
    + uap->port.membase + UART011_ICR);
    uap->im = UART011_RTIM;
    if (!pl011_dma_rx_running(uap))
    uap->im |= UART011_RXIM;
    @@ -1916,6 +1919,10 @@ static int pl011_probe(struct amba_devic
    goto unmap;
    }

    + /* Ensure interrupts from this UART are masked and cleared */
    + writew(0, uap->port.membase + UART011_IMSC);
    + writew(0xffff, uap->port.membase + UART011_ICR);
    +
    uap->vendor = vendor;
    uap->lcrh_rx = vendor->lcrh_rx;
    uap->lcrh_tx = vendor->lcrh_tx;



    \
     
     \ /
      Last update: 2012-04-19 23:27    [W:2.879 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site