mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2] spi: sifive: clamp the clock divider to the register range
@ 2026-11-10 14:57 shao.mingyin
  2026-11-10 16:04 ` Mark Brown
  0 siblings, 1 reply; 2+ messages in thread
From: shao.mingyin @ 2026-11-10 14:57 UTC (permalink / raw)
  To: broonie, linux-spi; +Cc: linux-kernel, linux-riscv, pjw, samuel.holland

From: Shao Mingyin <shao.mingyin@zte.com.cn>

sifive_spi_prep_transfer() divides by t->speed_hz, which can remain
zero when neither the device nor the controller provides a maximum
speed. For a nonzero but very low speed, masking the divider to 12 bits
can also wrap it to a small value and program a much faster clock.

Use the maximum divider when no speed is supplied, and saturate an
out-of-range divider to the same value. Keep the calculation in an
unsigned long until it has been clamped, so it is not truncated to u32
before the range check.

Fixes: 484a9a68d669 ("spi: sifive: Add driver for the SiFive SPI controller")
Suggested-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Shao Mingyin <shao.mingyin@zte.com.cn>
---
This patch supersedes 1/5 of the v1 series; 2/5, 3/5 and 4/5 are
unchanged, and 5/5 is posted separately.

v2:
  - use the maximum SCKDIV directly for a zero speed, and saturate an
    excessive divider instead of masking away high bits (Mark Brown)
  - keep the divider wide until after the range check
v1: https://lore.kernel.org/all/20261106234756882V9wUQNCEZAYUGTAbexMSL@zte.com.cn/

Validation on x86-64 with GCC 13 and UBSAN: the verbatim preparation
function ran with clock/register stubs over all representable SCKDIV
values and the first overflow. A zero speed bypassed division and
programmed 0xfff. A 1 Hz request needing divider 4096 programmed 0xfff
instead of wrapping to zero; a divider exceeding u32 also saturated.
In-range requests retained their original register values.

 drivers/spi/spi-sifive.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-sifive.c b/drivers/spi/spi-sifive.c
index cee4d92e46f437319fa40f6377e5511e692d12c7..ca7b04520a682c3fffb070169ab0e3c485e323de 100644
--- a/drivers/spi/spi-sifive.c
+++ b/drivers/spi/spi-sifive.c
@@ -167,12 +167,15 @@ static int
 sifive_spi_prep_transfer(struct sifive_spi *spi, struct spi_device *device,
 			 struct spi_transfer *t)
 {
+	unsigned long div = SIFIVE_SPI_SCKDIV_DIV_MASK;
 	u32 cr;
 	unsigned int mode;
 
-	/* Calculate and program the clock rate */
-	cr = DIV_ROUND_UP(clk_get_rate(spi->clk) >> 1, t->speed_hz) - 1;
-	cr &= SIFIVE_SPI_SCKDIV_DIV_MASK;
+	/* Use the slowest clock if no speed is specified. */
+	if (t->speed_hz)
+		div = DIV_ROUND_UP(clk_get_rate(spi->clk) >> 1,
+				   t->speed_hz) - 1;
+	cr = min_t(unsigned long, div, SIFIVE_SPI_SCKDIV_DIV_MASK);
 	sifive_spi_write(spi, SIFIVE_SPI_REG_SCKDIV, cr);
 
 	mode = max_t(unsigned int, t->rx_nbits, t->tx_nbits);

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH v2] spi: sifive: clamp the clock divider to the register range
  2026-11-10 14:57 [PATCH v2] spi: sifive: clamp the clock divider to the register range shao.mingyin
@ 2026-11-10 16:04 ` Mark Brown
  0 siblings, 0 replies; 2+ messages in thread
From: Mark Brown @ 2026-11-10 16:04 UTC (permalink / raw)
  To: shao.mingyin; +Cc: linux-spi, linux-kernel, linux-riscv, pjw, samuel.holland

[-- Attachment #1: Type: text/plain, Size: 702 bytes --]

On Tue, Nov 10, 2026 at 10:57:41PM +0800, shao.mingyin@zte.com.cn wrote:
> From: Shao Mingyin <shao.mingyin@zte.com.cn>
> 
> sifive_spi_prep_transfer() divides by t->speed_hz, which can remain
> zero when neither the device nor the controller provides a maximum
> speed. For a nonzero but very low speed, masking the divider to 12 bits
> can also wrap it to a small value and program a much faster clock.

This was previously part of a series of five patches, I see you've
resent two of them as independent patches when I was expecting the
standard workflow which would be to revise the series.  This makes
things difficult to track, I'd discarded the old version waiting for the
new one.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-11-10 16:04 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-10 14:57 [PATCH v2] spi: sifive: clamp the clock divider to the register range shao.mingyin
2026-11-10 16:04 ` Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®