| Message ID | 20260902-spi-sun4i-fixes-v1-3-19985ef75673@pengutronix.de (mailing list archive) |
|---|---|
| State | New |
| Headers |
Return-Path: <linux-sunxi+bounces-25488-sunxi=pue.re@lists.linux.dev> X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sto.lore.kernel.org (sto.lore.kernel.org [172.232.135.74]) by mxe881.netcup.net (Postfix) with ESMTPS id 3326B1C2D12 for <noreply@patchwork.local>; Wed, 2 Sep 2026 17:44:36 +0200 (CEST) Authentication-Results: mxe881; spf=pass (sender IP is 172.232.135.74) smtp.mailfrom=linux-sunxi+bounces-25488-noreply=patchwork.local@lists.linux.dev smtp.helo=sto.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.232.135.74 as permitted sender) client-ip=172.232.135.74; envelope-from=linux-sunxi+bounces-25488-noreply=patchwork.local@lists.linux.dev; helo=sto.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sto.lore.kernel.org (Postfix) with ESMTP id B22EE60BDFD for <noreply@patchwork.local>; Wed, 2 Sep 2026 15:36:29 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 50BD44A92F5; Wed, 2 Sep 2026 15:36:15 +0000 (UTC) X-Original-To: linux-sunxi@lists.linux.dev Received: from mx1.white.stw.pengutronix.de (mx1.white.stw.pengutronix.de [185.203.200.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 407524A5EDE for <linux-sunxi@lists.linux.dev>; Wed, 2 Sep 2026 15:36:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.200.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788363373; cv=none; b=GbEucGcBKC/jK+HzBsKkbVVac66ft6mO/acGDVt8sGd+cqjxDYp9sIp7vUSf0LmTgK2x88ir7n684fa9CUev4raXMM4hKbQvqQSJV+sQvLLwRXsP3VW9Yr5D+fdPFpxq9Yag50fOkIklmADmteOCbUMzH2CBBAlaDSr5XY2/TIs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788363373; c=relaxed/simple; bh=b/Rj/w30fHVnh9RcrAMhwiWspO3Z6tlqTUeG/eapRKw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MCNUWDUbqwpqQvQGMLpPKacpjGCKgxKWZLk1Hb1969JOK++v9w3AMZ4Yzfu2wWgsCO3+NhBeCxdpIEwmOqzYzSI90wqQIdndGvendtF2R8T/9LbJX5rAUE7xJYaldTbPUI8hrUdkg0GtT/j82EnhLF53rvkW8cz6uSURUE6pQdk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.200.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de (drehscheibe.grey.stw.pengutronix.de [IPv6:2a0a:edc0:0:c01:1d::a2]) (Authenticated sender: relay-from-drehscheibe.grey.stw.pengutronix.de) by mx1.white.stw.pengutronix.de (Postfix) with ESMTPSA id 29CE52058E4; Wed, 02 Sep 2026 17:35:54 +0200 (CEST) Received: from dude04.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::ac]) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.96) (envelope-from <jre@pengutronix.de>) id 1x1n0E-004bxm-0B; Wed, 02 Sep 2026 17:35:54 +0200 From: Jonas Rebmann <jre@pengutronix.de> Date: Wed, 02 Sep 2026 17:35:45 +0200 Subject: [PATCH 3/5] spi: spi-sun4i: sun4i_spi_transfer_one(): fix setting of clock rate Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: <linux-sunxi.lists.linux.dev> List-Subscribe: <mailto:linux-sunxi+subscribe@lists.linux.dev> List-Unsubscribe: <mailto:linux-sunxi+unsubscribe@lists.linux.dev> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260902-spi-sun4i-fixes-v1-3-19985ef75673@pengutronix.de> References: <20260902-spi-sun4i-fixes-v1-0-19985ef75673@pengutronix.de> In-Reply-To: <20260902-spi-sun4i-fixes-v1-0-19985ef75673@pengutronix.de> To: Mark Brown <broonie@kernel.org>, Chen-Yu Tsai <wens@kernel.org>, Jernej Skrabec <jernej.skrabec@gmail.com>, Samuel Holland <samuel@sholland.org>, Maxime Ripard <mripard@kernel.org>, Alexandru Gagniuc <mr.nuke.me@gmail.com>, Olliver Schinagl <o.schinagl@ultimaker.com> Cc: linux-spi@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, Mark Brown <broonie@linaro.org>, kernel@pengutronix.de, Marc Kleine-Budde <mkl@pengutronix.de>, Jonas Rebmann <jre@pengutronix.de> X-Mailer: b4 0.16-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=2246; i=jre@pengutronix.de; h=from:subject:message-id; bh=D4FuL08gsiZzpVFVp+v7a+SBkIZ4CQD5SP5UhyKTC1I=; b=owGbwMvMwCV2ZcYT3onnbjcwnlZLYsia4RQhFhEmeFlzykKX4smLHheK8m+a+lhmxl250NV/L hh6Si/Z2lHKwiDGxSArpsgSqyanIGTsf92s0i4WZg4rE8gQBi5OAZiI8FZGhgd/fjievaUw619O 6SQ5blE338eqzbPleO7vPcHDe09DwJSRYeHfybn7s+foWHxs5l8QscrAr7vtROjeOQ0bDbt/zyr bwgkA X-Developer-Key: i=jre@pengutronix.de; a=openpgp; fpr=0B7B750D5D3CD21B3B130DE8B61515E135CD49B5 X-Rspamd-Server: rspamd-worker-8404 X-Spamd-Result: default: False [-2.16 / 15.00]; BAYES_HAM(-5.50)[100.00%]; RBL_SENDERSCORE(2.00)[172.232.135.74:from]; SUSPICIOUS_RECIPS(1.50)[]; MAILLIST(-0.15)[generic]; MIME_GOOD(-0.10)[text/plain]; BAD_REP_POLICIES(0.10)[]; HAS_LIST_UNSUB(-0.01)[]; TAGGED_RCPT(0.00)[]; ARC_ALLOW(0.00)[subspace.kernel.org:s=arc-20240116:i=1]; PRECEDENCE_BULK(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; RCPT_COUNT_TWELVE(0.00)[15]; DMARC_NA(0.00)[pengutronix.de]; FORGED_SENDER_MAILLIST(0.00)[]; DBL_BLOCKED_OPENRESOLVER(0.00)[sto.lore.kernel.org:rdns,sto.lore.kernel.org:helo]; FROM_HAS_DN(0.00)[]; MID_RHS_MATCH_FROM(0.00)[]; FROM_NEQ_ENVFROM(0.00)[jre@pengutronix.de,linux-sunxi@lists.linux.dev]; R_SPF_ALLOW(0.00)[+ip4:172.232.135.74:c]; FREEMAIL_TO(0.00)[kernel.org,gmail.com,sholland.org,ultimaker.com]; TO_DN_SOME(0.00)[]; RECEIVED_SPAMHAUS_BLOCKED_OPENRESOLVER(0.00)[185.203.200.13:received,100.90.174.1:received,2a0a:edc0:0:1101:1d::ac:received,2a0a:edc0:0:c01:1d::a2:received]; RCVD_COUNT_FIVE(0.00)[6]; FORGED_RECIPIENTS_MAILLIST(0.00)[]; R_DKIM_NA(0.00)[]; ASN(0.00)[asn:63949, ipnet:172.232.128.0/19, country:SG]; RCVD_TLS_LAST(0.00)[]; TAGGED_FROM(0.00)[bounces-25488-noreply=patchwork.local]; MIME_TRACE(0.00)[0:+]; RBL_SPAMHAUS_BLOCKED_OPENRESOLVER(0.00)[172.232.135.74:from] X-Rspamd-Queue-Id: 3326B1C2D12 X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= |
| Series |
spi: spi-sun4i: assorted fixes
|
|
Commit Message
Jonas Rebmann
Sept. 2, 2026, 3:35 p.m. UTC
From: Marc Kleine-Budde <mkl@pengutronix.de> A SPI transfer defines the _maximum_ speed of the SPI transfer. However the driver doesn't take into account that the clock divider is always rounded down (due to integer arithmetic). This results in a too high clock rate for the SPI transfer. E.g.: with an mclk_rate of 24 MHz and an SPI transfer speed of 10 MHz, the original code calculates a reg of "0", which results in an effective divider of "2" and a 12 MHz clock for the SPI transfer. Use DIV_ROUND_UP() instead of a plain integer division to fix the problem. While there simplify the divider calculation for the CDR1 case, use order_base_2() instead of two ilog2() calculations. Fixes: b5f6517948cc ("spi: sunxi: Add Allwinner A10 SPI controller driver") Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> Signed-off-by: Jonas Rebmann <jre@pengutronix.de> --- drivers/spi/spi-sun4i.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
Comments
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [High] Off-by-one in the CDR1 clock divider calculation omits a required '- 1', resulting in an SPI clock that runs at less than half the requested speed, which deterministically causes false transfer timeouts for large payloads. -- commit e08997f492b7dd1b9df03ec9d36b3a190b6b3325 Author: Marc Kleine-Budde <mkl@pengutronix.de> spi: spi-sun4i: sun4i_spi_transfer_one(): fix setting of clock rate This commit modifies sun4i_spi_transfer_one() to use DIV_ROUND_UP() for the clock rate calculation to prevent the SPI transfer clock from exceeding the requested maximum speed. It also simplifies the CDR1 divider calculation by using order_base_2(). > diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c > index 3649bcabcc9a7..ae009d5984505 100644 > --- a/drivers/spi/spi-sun4i.c > +++ b/drivers/spi/spi-sun4i.c [ ... ] > @@ -296,14 +296,12 @@ static int sun4i_spi_transfer_one(struct spi_controller *host, > * First try CDR2, and if we can't reach the expected > * frequency, fall back to CDR1. > */ > - div = mclk_rate / (2 * tfr->speed_hz); > - if (div <= (SUN4I_CLK_CTL_CDR2_MASK + 1)) { > - if (div > 0) > - div--; > - > - reg = SUN4I_CLK_CTL_CDR2(div) | SUN4I_CLK_CTL_DRS; > + div_cdr1 = DIV_ROUND_UP(mclk_rate, tfr->speed_hz); > + div_cdr2 = DIV_ROUND_UP(div_cdr1, 2); > + if (div_cdr2 <= (SUN4I_CLK_CTL_CDR2_MASK + 1)) { > + reg = SUN4I_CLK_CTL_CDR2(div_cdr2 - 1) | SUN4I_CLK_CTL_DRS; > } else { > - div = ilog2(mclk_rate) - ilog2(tfr->speed_hz); > + div = min(SUN4I_CLK_CTL_CDR1_MASK, order_base_2(div_cdr1)); > reg = SUN4I_CLK_CTL_CDR1(div); [Severity: High] Does this calculation in sun4i_spi_transfer_one() set the divider exponent one higher than required? The CDR1 formula is MOD_CLK / (2 ^ (div + 1)). By using order_base_2(div_cdr1) without subtracting 1, the actual divider becomes 2 * 2^ceil(...), dropping the clock speed below speed_hz / 2. Could this break the tx_time calculation for large payloads and result in spurious -ETIMEDOUT failures when a low speed_hz falls back to CDR1? Should this subtract 1 from the order_base_2() result? > } >
diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c index 3649bcabcc9a..ae009d598450 100644 --- a/drivers/spi/spi-sun4i.c +++ b/drivers/spi/spi-sun4i.c @@ -212,7 +212,7 @@ static int sun4i_spi_transfer_one(struct spi_controller *host, struct spi_transfer *tfr) { struct sun4i_spi *sspi = spi_controller_get_devdata(host); - unsigned int mclk_rate, div; + unsigned int mclk_rate, div, div_cdr1, div_cdr2; unsigned long time_left; unsigned int start, end, tx_time; unsigned int tx_len = 0; @@ -296,14 +296,12 @@ static int sun4i_spi_transfer_one(struct spi_controller *host, * First try CDR2, and if we can't reach the expected * frequency, fall back to CDR1. */ - div = mclk_rate / (2 * tfr->speed_hz); - if (div <= (SUN4I_CLK_CTL_CDR2_MASK + 1)) { - if (div > 0) - div--; - - reg = SUN4I_CLK_CTL_CDR2(div) | SUN4I_CLK_CTL_DRS; + div_cdr1 = DIV_ROUND_UP(mclk_rate, tfr->speed_hz); + div_cdr2 = DIV_ROUND_UP(div_cdr1, 2); + if (div_cdr2 <= (SUN4I_CLK_CTL_CDR2_MASK + 1)) { + reg = SUN4I_CLK_CTL_CDR2(div_cdr2 - 1) | SUN4I_CLK_CTL_DRS; } else { - div = ilog2(mclk_rate) - ilog2(tfr->speed_hz); + div = min(SUN4I_CLK_CTL_CDR1_MASK, order_base_2(div_cdr1)); reg = SUN4I_CLK_CTL_CDR1(div); }