mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Peng Fan <peng.fan@linux.dev>
To: Mark Brown <broonie@kernel.org>,
	 Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	 "Rafael J. Wysocki" <rafael@kernel.org>,
	Danilo Krummrich <dakr@kernel.org>,
	 Johan Hovold <johan@kernel.org>,
	 Lucas Tanure <tanureal@opensource.cirrus.com>
Cc: linux-kernel@vger.kernel.org, driver-core@lists.linux.dev,
	 Peng Fan <peng.fan@nxp.com>
Subject: [PATCH v2 03/10] regmap-i2c: fix write limit clamping for adapter quirks
Date: Fri, 13 Nov 2026 23:31:51 +0800	[thread overview]
Message-ID: <20261113-regmap-improve-v2-3-5dfd6a89078f@nxp.com> (raw)
In-Reply-To: <20261113-regmap-improve-v2-0-5dfd6a89078f@nxp.com>

From: Peng Fan <peng.fan@nxp.com>

The adapter max_write_len quirk covers the whole write message, including
the register address, while max_raw_write is the payload limit. Calculate
the payload limit before comparing it with max_raw_write, otherwise a bus
limit that fits in the message but not in the quirk payload is left
unchanged and the transfer fails in i2c_check_for_quirks().

Also avoid installing a payload limit smaller than one value.
_regmap_raw_write() splits transfers using max_raw_write / val_bytes, so a
limit below val_bytes results in a zero chunk size and a division by zero.
If the adapter cannot fit a single value after the register address, no
raw write can succeed, so keep the existing limit.

The subtraction must not underflow when max_write_len does not exceed the
register address size, so only calculate the payload limit when the quirk
leaves room for it. Apply the same minimum-size check to the read quirk
because max_raw_read is used as a divisor too.

Fixes: 611b7eb19d0a ("regmap-i2c: Subtract reg size from max_write")
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/base/regmap/regmap-i2c.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/base/regmap/regmap-i2c.c b/drivers/base/regmap/regmap-i2c.c
index 8663a4ec0a3d..a4a259232980 100644
--- a/drivers/base/regmap/regmap-i2c.c
+++ b/drivers/base/regmap/regmap-i2c.c
@@ -8,6 +8,7 @@
 
 #include <linux/regmap.h>
 #include <linux/i2c.h>
+#include <linux/bitops.h>
 #include <linux/module.h>
 
 #include "internal.h"
@@ -353,6 +354,7 @@ static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c,
 	const struct i2c_adapter_quirks *quirks;
 	const struct regmap_bus *bus = NULL;
 	struct regmap_bus *ret_bus;
+	size_t val_bytes;
 	u16 max_read, max_write;
 
 	if (i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C))
@@ -393,17 +395,28 @@ static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c,
 
 	max_read = bus->max_raw_read;
 	max_write = bus->max_raw_write;
+	val_bytes = BITS_TO_BYTES(config->val_bits);
 
 	quirks = i2c->adapter->quirks;
 	if (quirks) {
 		if (quirks->max_read_len &&
+		    quirks->max_read_len >= val_bytes &&
 		    (max_read == 0 || max_read > quirks->max_read_len))
 			max_read = quirks->max_read_len;
 
-		if (quirks->max_write_len &&
-		    (max_write == 0 || max_write > quirks->max_write_len))
-			max_write = quirks->max_write_len -
-				(config->reg_bits + config->pad_bits) / BITS_PER_BYTE;
+		if (quirks->max_write_len) {
+			size_t reg_reserve_size, max_payload;
+
+			reg_reserve_size = (config->reg_bits + config->pad_bits) /
+					   BITS_PER_BYTE;
+			if (quirks->max_write_len > reg_reserve_size) {
+				max_payload = quirks->max_write_len -
+					      reg_reserve_size;
+				if (max_payload >= val_bytes &&
+				    (max_write == 0 || max_write > max_payload))
+					max_write = max_payload;
+			}
+		}
 
 		if (max_read != bus->max_raw_read ||
 		    max_write != bus->max_raw_write) {

-- 
2.56.0


  parent reply	other threads:[~2026-11-13 15:32 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-13 15:31 [PATCH v2 00/10] regmap: clean up and improve __regmap_init() Peng Fan
2026-11-13 15:31 ` [PATCH v2 01/10] regmap: fix reinit cache failure handling Peng Fan
2026-11-13 15:31 ` [PATCH v2 02/10] regmap-i2c: keep bus raw write limit when applying read quirk Peng Fan
2026-11-13 15:31 ` Peng Fan [this message]
2026-11-13 15:31 ` [PATCH v2 04/10] regmap: deduplicate fast_io checks Peng Fan
2026-11-13 15:31 ` [PATCH v2 05/10] regmap: factor out regmap_set_lock() Peng Fan
2026-11-13 15:31 ` [PATCH v2 06/10] regmap: factor out regmap_init_ranges() Peng Fan
2026-11-13 15:31 ` [PATCH v2 07/10] regmap: factor out format initialisation into helpers Peng Fan
2026-11-13 15:31 ` [PATCH v2 08/10] regmap: drop regmap_bus::free_on_exit Peng Fan
2026-11-13 15:31 ` [PATCH v2 09/10] regmap: use cleanup API in __regmap_init() Peng Fan
2026-11-13 15:31 ` [PATCH v2 10/10] regmap: kunit: add test for regmap_bus::init_limits Peng Fan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261113-regmap-improve-v2-3-5dfd6a89078f@nxp.com \
    --to=peng.fan@linux.dev \
    --cc=broonie@kernel.org \
    --cc=dakr@kernel.org \
    --cc=driver-core@lists.linux.dev \
    --cc=gregkh@linuxfoundation.org \
    --cc=johan@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=peng.fan@nxp.com \
    --cc=rafael@kernel.org \
    --cc=tanureal@opensource.cirrus.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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®