[PATCH 4/5] spi: apple: fix division by zero in clock divisor calculation
From: shao.mingyin
Date: Fri Nov 06 2026 - 11:00:18 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 apple_spi_prep_transfer() and DIV_ROUND_UP() divides by
it.
On arm64 the divide instruction returns zero instead of trapping, so
CLKDIV is programmed as zero. That selects the fastest clock and can
exceed the rate the attached device supports.
Clamp the divisor to 1 Hz so the divider calculation is well defined.
Fixes: c36212b2610d ("spi: apple: Add driver for Apple SPI controller")
Signed-off-by: Shao Mingyin <shao.mingyin@xxxxxxxxxx>
---
diff --git a/drivers/spi/spi-apple.c b/drivers/spi/spi-apple.c
index 61eefb08d2a7..8dbf05936db1 100644
--- a/drivers/spi/spi-apple.c
+++ b/drivers/spi/spi-apple.c
@@ -196,9 +196,13 @@ static void apple_spi_set_cs(struct spi_device *device, bool is_high)
static bool apple_spi_prep_transfer(struct apple_spi *spi, struct spi_transfer *t)
{
u32 cr, fifo_threshold;
+ u32 speed_hz;
+
+ /* 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), t->speed_hz);
+ cr = DIV_ROUND_UP(clk_get_rate(spi->clk), speed_hz);
reg_write(spi, APPLE_SPI_CLKDIV, min_t(u32, cr, APPLE_SPI_CLKDIV_MAX));
/* Update bits per word */