• Vignesh R's avatar
    spi: ti-qspi: Fix data corruption seen on r/w stress test · 6fcb802e
    Vignesh R authored
    commit bc27a539 upstream.
    
    Writing invalid command to QSPI_SPI_CMD_REG will terminate current
    transfer and de-assert the chip select. This has to be done before
    calling spi_finalize_current_message(). Because
    spi_finalize_current_message() will mark the end of current message
    transfer and schedule the next transfer. If the chipselect is not
    de-asserted before calling spi_finalize_current_message() then the next
    transfer will overlap with the previous transfer leading to data
    corruption.
    __spi_pump_message() can be called either from kthread worker context or
    directly from the calling process's context. It is possible that these
    two calls can race against each other. But race is serialized by
    checking whether master->cur_msg == NULL (pointer to msg being handled
    by transfer_one() at present). The master->cur_msg is set to NULL when
    spi_finalize_current_message() is called on that message, which means
    calling spi_finalize_current_message() allows __spi_sync() to pump next
    message in calling process context.
    Now if spi-ti-qspi calls spi_finalize_current_message() before we
    terminate transfer at hardware side, if __spi_pump_message() is called
    from process context then the successive transactions can overlap.
    
    Fix this by moving writing invalid command to QSPI_SPI_CMD_REG to
    before calling spi_finalize_current_message() call.
    Signed-off-by: default avatarVignesh R <vigneshr@ti.com>
    Signed-off-by: default avatarMark Brown <broonie@kernel.org>
    Signed-off-by: default avatarLuis Henriques <luis.henriques@canonical.com>
    6fcb802e
spi-ti-qspi.c 13.6 KB