• Dave Martin's avatar
    tty: pl011: Avoid spuriously stuck-off interrupts · 4a7e625c
    Dave Martin authored
    Commit 9b96fbac ("serial: PL011: clear pending interrupts")
    clears the RX and receive timeout interrupts on pl011 startup, to
    avoid a screaming-interrupt scenario that can occur when the
    firmware or bootloader leaves these interrupts asserted.
    
    This has been noted as an issue when running Linux on qemu [1].
    
    Unfortunately, the above fix seems to lead to potential
    misbehaviour if the RX FIFO interrupt is asserted _non_ spuriously
    on driver startup, if the RX FIFO is also already full to the
    trigger level.
    
    Clearing the RX FIFO interrupt does not change the FIFO fill level.
    In this scenario, because the interrupt is now clear and because
    the FIFO is already full to the trigger level, no new assertion of
    the RX FIFO interrupt can occur unless the FIFO is drained back
    below the trigger level.  This never occurs because the pl011
    driver is waiting for an RX FIFO interrupt to tell it that there is
    something to read, and does not read the FIFO at all until that
    interrupt occurs.
    
    Thus, simply clearing "spurious" interrupts on startup may be
    misguided, since there is no way to be sure that the interrupts are
    truly spurious, and things can go wrong if they are not.
    
    This patch instead clears the interrupt condition by draining the
    RX FIFO during UART startup, after clearing any potentially
    spurious interrupt.  This should ensure that an interrupt will
    definitely be asserted if the RX FIFO subsequently becomes
    sufficiently full.
    
    The drain is done at the point of enabling interrupts only.  This
    means that it will occur any time the UART is newly opened through
    the tty layer.  It will not apply to polled-mode use of the UART by
    kgdboc: since that scenario cannot use interrupts by design, this
    should not matter.  kgdboc will interact badly with "normal" use of
    the UART in any case: this patch makes no attempt to paper over
    such issues.
    
    This patch does not attempt to address the case where the RX FIFO
    fills faster than it can be drained: that is a pathological
    hardware design problem that is beyond the scope of the driver to
    work around.  As a failsafe, the number of poll iterations for
    draining the FIFO is limited to twice the FIFO size.  This will
    ensure that the kernel at least boots even if it is impossible to
    drain the FIFO for some reason.
    
    [1] [Qemu-devel] [Qemu-arm] [PATCH] pl011: do not put into fifo
    before enabled the interruption
    https://lists.gnu.org/archive/html/qemu-devel/2018-01/msg06446.htmlReported-by: default avatarWei Xu <xuwei5@hisilicon.com>
    Cc: Russell King <linux@armlinux.org.uk>
    Cc: Linus Walleij <linus.walleij@linaro.org>
    Cc: Peter Maydell <peter.maydell@linaro.org>
    Fixes: 9b96fbac ("serial: PL011: clear pending interrupts")
    Signed-off-by: default avatarDave Martin <Dave.Martin@arm.com>
    Cc: stable <stable@vger.kernel.org>
    Tested-by: default avatarWei Xu <xuwei5@hisilicon.com>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    4a7e625c
amba-pl011.c 71 KB