[PATCH 1/5] spi: sifive: fix division by zero in clock divisor calculation
From: shao.mingyin
Date: Fri Nov 06 2026 - 11:00:08 EST
From: Shao Mingyin <shao.mingyin@xxxxxxxxxx>
A SPI device without a valid speed (no spi-max-frequency property, or
created through the spidev sysfs new_device interface without a speed)
gets max_speed_hz == 0. spi_setup() only clamps that to the controller
limit when host->max_speed_hz is set, and this driver does not set it, so
the zero reaches sifive_spi_prep_transfer() and DIV_ROUND_UP() divides
by it.
On RISC-V the divide instruction returns all ones instead of trapping,
so the controller is programmed with a bogus clock divider rather than
the rate the device asked for.
Clamp the divisor to 1 Hz so the divider calculation is well defined.
Fixes: 484a9a68d669 ("spi: sifive: Add driver for the SiFive SPI controller")
Signed-off-by: Shao Mingyin <shao.mingyin@xxxxxxxxxx>
---
diff --git a/drivers/spi/spi-sifive.c b/drivers/spi/spi-sifive.c
index cee4d92e46f4..9c1f674f5921 100644
--- a/drivers/spi/spi-sifive.c
+++ b/drivers/spi/spi-sifive.c
@@ -168,10 +168,14 @@ sifive_spi_prep_transfer(struct sifive_spi *spi, struct spi_device *device,
struct spi_transfer *t)
{
u32 cr;
+ u32 speed_hz;
unsigned int mode;
+ /* A device with max_speed_hz == 0 must not divide by zero */
+ speed_hz = max_t(u32, t->speed_hz, 1);
+
/* Calculate and program the clock rate */
- cr = DIV_ROUND_UP(clk_get_rate(spi->clk) >> 1, t->speed_hz) - 1;
+ cr = DIV_ROUND_UP(clk_get_rate(spi->clk) >> 1, speed_hz) - 1;
cr &= SIFIVE_SPI_SCKDIV_DIV_MASK;
sifive_spi_write(spi, SIFIVE_SPI_REG_SCKDIV, cr);