Skip to content

Commit 0122a51

Browse files
msperlbroonie
authored andcommitted
spi: bcm2835: fix overflow in calculation of transfer time
This resulted in the use of polling mode when other approaches (dma or interrupts) would have been more appropriate. Happened for transfers longer than 477 bytes. Reported-by: Noralf Tronnes <[email protected]> Signed-off-by: Martin Sperl <[email protected]> Signed-off-by: Mark Brown <[email protected]>
1 parent acace73 commit 0122a51

File tree

1 file changed

+6
-4
lines changed

1 file changed

+6
-4
lines changed

drivers/spi/spi-bcm2835.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ static int bcm2835_spi_transfer_one_poll(struct spi_master *master,
480480
struct spi_device *spi,
481481
struct spi_transfer *tfr,
482482
u32 cs,
483-
unsigned long xfer_time_us)
483+
unsigned long long xfer_time_us)
484484
{
485485
struct bcm2835_spi *bs = spi_master_get_devdata(master);
486486
unsigned long timeout;
@@ -531,7 +531,8 @@ static int bcm2835_spi_transfer_one(struct spi_master *master,
531531
{
532532
struct bcm2835_spi *bs = spi_master_get_devdata(master);
533533
unsigned long spi_hz, clk_hz, cdiv;
534-
unsigned long spi_used_hz, xfer_time_us;
534+
unsigned long spi_used_hz;
535+
unsigned long long xfer_time_us;
535536
u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS);
536537

537538
/* set clock */
@@ -573,9 +574,10 @@ static int bcm2835_spi_transfer_one(struct spi_master *master,
573574
bs->rx_len = tfr->len;
574575

575576
/* calculate the estimated time in us the transfer runs */
576-
xfer_time_us = tfr->len
577+
xfer_time_us = (unsigned long long)tfr->len
577578
* 9 /* clocks/byte - SPI-HW waits 1 clock after each byte */
578-
* 1000000 / spi_used_hz;
579+
* 1000000;
580+
do_div(xfer_time_us, spi_used_hz);
579581

580582
/* for short requests run polling*/
581583
if (xfer_time_us <= BCM2835_SPI_POLLING_LIMIT_US)

0 commit comments

Comments
 (0)