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
next prev 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®