summaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2021-01-07 12:21:32 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2021-01-07 12:21:32 -0800
commitf5e6c330254ae691f6d7befe61c786eb5056007e (patch)
tree2eace6e55f1c19656941734f390396d1326e4073 /drivers/spi/spi.c
parenta1a7b4f32433e91f0fff32cde534eadc67242298 (diff)
parent6170d077bf92c5b3dfbe1021688d3c0404f7c9e9 (diff)
downloadlinux-f5e6c330254ae691f6d7befe61c786eb5056007e.tar.bz2
Merge tag 'spi-fix-v5.11-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi fixes from Mark Brown: "A couple of core fixes here, both to do with handling of drivers which don't report their maximum speed since we factored some of the handling for transfer speeds out into the core in the previous release. There's also some driver specific fixes, including a relatively large set for some races around timeouts in spi-geni-qcom" * tag 'spi-fix-v5.11-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: spi: fix the divide by 0 error when calculating xfer waiting time spi: Fix the clamping of spi->max_speed_hz spi: altera: fix return value for altera_spi_txrx() spi: stm32: FIFO threshold level - fix align packet size spi: spi-geni-qcom: Print an error when we timeout setting the CS spi: spi-geni-qcom: Don't try to set CS if an xfer is pending spi: spi-geni-qcom: Fail new xfers if xfer/cancel/abort pending spi: spi-geni-qcom: Fix geni_spi_isr() NULL dereference in timeout case
Diffstat (limited to 'drivers/spi/spi.c')
-rw-r--r--drivers/spi/spi.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 51d7c004fbab..720ab34784c1 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1108,6 +1108,7 @@ static int spi_transfer_wait(struct spi_controller *ctlr,
{
struct spi_statistics *statm = &ctlr->statistics;
struct spi_statistics *stats = &msg->spi->statistics;
+ u32 speed_hz = xfer->speed_hz;
unsigned long long ms;
if (spi_controller_is_slave(ctlr)) {
@@ -1116,8 +1117,11 @@ static int spi_transfer_wait(struct spi_controller *ctlr,
return -EINTR;
}
} else {
+ if (!speed_hz)
+ speed_hz = 100000;
+
ms = 8LL * 1000LL * xfer->len;
- do_div(ms, xfer->speed_hz);
+ do_div(ms, speed_hz);
ms += ms + 200; /* some tolerance */
if (ms > UINT_MAX)
@@ -3378,8 +3382,9 @@ int spi_setup(struct spi_device *spi)
if (status)
return status;
- if (!spi->max_speed_hz ||
- spi->max_speed_hz > spi->controller->max_speed_hz)
+ if (spi->controller->max_speed_hz &&
+ (!spi->max_speed_hz ||
+ spi->max_speed_hz > spi->controller->max_speed_hz))
spi->max_speed_hz = spi->controller->max_speed_hz;
mutex_lock(&spi->controller->io_mutex);