• Lukas Wunner's avatar
    spi: bcm2835: Avoid finishing transfer prematurely in IRQ mode · 56c17234
    Lukas Wunner authored
    The IRQ handler bcm2835_spi_interrupt() first reads as much as possible
    from the RX FIFO, then writes as much as possible to the TX FIFO.
    Afterwards it decides whether the transfer is finished by checking if
    the TX FIFO is empty.
    
    If very few bytes were written to the TX FIFO, they may already have
    been transmitted by the time the FIFO's emptiness is checked.  As a
    result, the transfer will be declared finished and the chip will be
    reset without reading the corresponding received bytes from the RX FIFO.
    
    The odds of this happening increase with a high clock frequency (such
    that the TX FIFO drains quickly) and either passing "threadirqs" on the
    command line or enabling CONFIG_PREEMPT_RT_BASE (such that the IRQ
    handler may be preempted between filling the TX FIFO and checking its
    emptiness).
    
    Fix by instead checking whether rx_len has reached zero, which means
    that the transfer has been received in full.  This is also more
    efficient as it avoids one bus read access per interrupt.  Note that
    bcm2835_spi_transfer_one_poll() likewise uses rx_len to determine
    whether the transfer has finished.
    Signed-off-by: default avatarLukas Wunner <lukas@wunner.de>
    Fixes: e34ff011 ("spi: bcm2835: move to the transfer_one driver model")
    Cc: stable@vger.kernel.org # v4.1+
    Cc: Mathias Duckeck <m.duckeck@kunbus.de>
    Cc: Frank Pavlic <f.pavlic@kunbus.de>
    Cc: Martin Sperl <kernel@martin.sperl.org>
    Cc: Noralf Trønnes <noralf@tronnes.org>
    Signed-off-by: default avatarMark Brown <broonie@kernel.org>
    56c17234
spi-bcm2835.c 22.9 KB