Skip to content

Commit

Permalink
spi: dw: Fix wrong FIFO level setting for long xfers
Browse files Browse the repository at this point in the history
[ Upstream commit c63b8fd ]

Due to using the u16 type in the min_t() macros the SPI transfer length
will be cast to word before participating in the conditional statement
implied by the macro. Thus if the transfer length is greater than 64KB the
Tx/Rx FIFO threshold level value will be determined by the leftover of the
truncated after the type-case length. In the worst case it will cause the
dramatical performance drop due to the "Tx FIFO Empty" or "Rx FIFO Full"
interrupts triggered on each xfer word sent/received to/from the bus.

The problem can be easily fixed by specifying the unsigned int type in the
min_t() macros thus preventing the possible data loss.

Fixes: ea11370 ("spi: dw: get TX level without an additional variable")
Reported-by: Sergey Nazarov <[email protected]>
Signed-off-by: Serge Semin <[email protected]>
Reviewed-by: Andy Shevchenko <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
  • Loading branch information
fancer authored and Sasha Levin committed Feb 14, 2023
1 parent 4a2f1e9 commit 1b986b6
Showing 1 changed file with 1 addition and 1 deletion.
2 changes: 1 addition & 1 deletion drivers/spi/spi-dw-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ static void dw_spi_irq_setup(struct dw_spi *dws)
* will be adjusted at the final stage of the IRQ-based SPI transfer
* execution so not to lose the leftover of the incoming data.
*/
level = min_t(u16, dws->fifo_len / 2, dws->tx_len);
level = min_t(unsigned int, dws->fifo_len / 2, dws->tx_len);
dw_writel(dws, DW_SPI_TXFTLR, level);
dw_writel(dws, DW_SPI_RXFTLR, level - 1);

Expand Down

0 comments on commit 1b986b6

Please sign in to comment.