* [PATCH 0/3] i2c: designware: Misc small fixes
@ 2025-09-18 14:03 Jean Delvare
2025-09-18 14:09 ` [PATCH 1/3] i2c: designware: Use msgs[0] to validate the slave address Jean Delvare
` (3 more replies)
0 siblings, 4 replies; 10+ messages in thread
From: Jean Delvare @ 2025-09-18 14:03 UTC (permalink / raw)
To: Linux I2C
Cc: Jarkko Nikula, Andy Shevchenko, Mika Westerberg, Jan Dabros,
Andi Shyti
Hi all,
While working on CVE-2025-38380, I noticed a few issues in the
i2c-designware driver, which I think are worth fixing now to make
future driver development safer and easier.
[PATCH 1/3] i2c: designware: Use msgs[0] to validate the slave address
[PATCH 2/3] i2c: designware: Extend check for mixed slave addresses
[PATCH 3/3] i2c: designware: Turn models back to enumerated values
Note that I do not own any supported device so I can't test these
changes. Even though the fixes are rather straightforward, I would
appreciate if someone can test them on actual hardware, to be on the
safe side.
Thanks,
--
Jean Delvare
SUSE L3 Support
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/3] i2c: designware: Use msgs[0] to validate the slave address
2025-09-18 14:03 [PATCH 0/3] i2c: designware: Misc small fixes Jean Delvare
@ 2025-09-18 14:09 ` Jean Delvare
2025-09-18 14:10 ` [PATCH 2/3] i2c: designware: Extend check for mixed slave addresses Jean Delvare
` (2 subsequent siblings)
3 siblings, 0 replies; 10+ messages in thread
From: Jean Delvare @ 2025-09-18 14:09 UTC (permalink / raw)
To: Linux I2C
Cc: Jarkko Nikula, Andy Shevchenko, Mika Westerberg, Jan Dabros,
Andi Shyti
Function i2c_dw_xfer_init() makes use of dev->msg_write_idx to index
into the array of messages. The purpose is to program the controller
with the slave address.
However, this driver only supports transfers where all messages have
the same address. Therefore checking the first message leads to the
same result, without depending on dev->msg_write_idx having been
initialized elsewhere before.
This function was always called with dev->msg_write_idx == 0 anyway,
so this does not change anything, only makes the intentions clearer
and the code more simple.
Signed-off-by: Jean Delvare <jdelvare@suse.de>
---
drivers/i2c/busses/i2c-designware-master.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
--- linux-6.16.orig/drivers/i2c/busses/i2c-designware-master.c
+++ linux-6.16/drivers/i2c/busses/i2c-designware-master.c
@@ -254,7 +254,7 @@ static void i2c_dw_xfer_init(struct dw_i
__i2c_dw_disable(dev);
/* If the slave address is ten bit address, enable 10BITADDR */
- if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) {
+ if (msgs[0].flags & I2C_M_TEN) {
ic_con = DW_IC_CON_10BITADDR_MASTER;
/*
* If I2C_DYNAMIC_TAR_UPDATE is set, the 10-bit addressing
@@ -272,8 +272,7 @@ static void i2c_dw_xfer_init(struct dw_i
* Set the slave (target) address and enable 10-bit addressing mode
* if applicable.
*/
- regmap_write(dev->map, DW_IC_TAR,
- msgs[dev->msg_write_idx].addr | ic_tar);
+ regmap_write(dev->map, DW_IC_TAR, msgs[0].addr | ic_tar);
/* Enforce disabled interrupts (due to HW issues) */
__i2c_dw_write_intr_mask(dev, 0);
@@ -363,7 +362,6 @@ static int amd_i2c_dw_xfer_quirk(struct
dev->msgs = msgs;
dev->msgs_num = num_msgs;
- dev->msg_write_idx = 0;
i2c_dw_xfer_init(dev);
/* Initiate messages read/write transaction */
--
Jean Delvare
SUSE L3 Support
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/3] i2c: designware: Extend check for mixed slave addresses
2025-09-18 14:03 [PATCH 0/3] i2c: designware: Misc small fixes Jean Delvare
2025-09-18 14:09 ` [PATCH 1/3] i2c: designware: Use msgs[0] to validate the slave address Jean Delvare
@ 2025-09-18 14:10 ` Jean Delvare
2025-09-19 17:14 ` Jean Delvare
2025-09-18 14:13 ` [PATCH 3/3] i2c: designware: Turn models back to enumerated values Jean Delvare
2025-09-19 12:13 ` [PATCH 0/3] i2c: designware: Misc small fixes Jarkko Nikula
3 siblings, 1 reply; 10+ messages in thread
From: Jean Delvare @ 2025-09-18 14:10 UTC (permalink / raw)
To: Linux I2C
Cc: Jarkko Nikula, Andy Shevchenko, Mika Westerberg, Jan Dabros,
Andi Shyti
The i2c-designware driver only supports transfers where all messages
use the same slave address. This condition is currently tested in
i2c_dw_xfer_msg(), with 2 limitations:
* The code only checks the address value, not the 10-bit address
flag, so it could miss an address change.
* For the AMD Navi GPU devices, the driver uses a dedicated function
instead of i2c_dw_xfer_msg(), so the check is not performed.
Move the check to the common code path, and add the 10-bit address
flag comparison, to catch and report early if a given transfer is not
supported.
Signed-off-by: Jean Delvare <jdelvare@suse.de>
---
drivers/i2c/busses/i2c-designware-master.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
--- linux-6.16.orig/drivers/i2c/busses/i2c-designware-master.c
+++ linux-6.16/drivers/i2c/busses/i2c-designware-master.c
@@ -429,7 +429,6 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
struct i2c_msg *msgs = dev->msgs;
u32 intr_mask;
int tx_limit, rx_limit;
- u32 addr = msgs[dev->msg_write_idx].addr;
u32 buf_len = dev->tx_buf_len;
u8 *buf = dev->tx_buf;
bool need_restart = false;
@@ -440,18 +439,6 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
for (; dev->msg_write_idx < dev->msgs_num; dev->msg_write_idx++) {
u32 flags = msgs[dev->msg_write_idx].flags;
- /*
- * If target address has changed, we need to
- * reprogram the target address in the I2C
- * adapter when we are done with this transfer.
- */
- if (msgs[dev->msg_write_idx].addr != addr) {
- dev_err(dev->dev,
- "%s: invalid target address\n", __func__);
- dev->msg_err = -EINVAL;
- break;
- }
-
if (!(dev->status & STATUS_WRITE_IN_PROGRESS)) {
/* new i2c_msg */
buf = msgs[dev->msg_write_idx].buf;
@@ -806,10 +793,23 @@ static int
i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
{
struct dw_i2c_dev *dev = i2c_get_adapdata(adap);
- int ret;
+ int ret, i;
dev_dbg(dev->dev, "%s: msgs: %d\n", __func__, num);
+ /*
+ * This driver only supports I2C transfers where all the messages
+ * use the same address.
+ */
+ for (i = 1; i < num; i++) {
+ if (msgs[i].addr != msgs[0].addr ||
+ (msgs[i].flags & I2C_M_TEN) != (msgs[0].flags & I2C_M_TEN)) {
+ dev_err(dev->dev,
+ "Mixed slave addresses not supported\n");
+ return -EOPNOTSUPP;
+ }
+ }
+
pm_runtime_get_sync(dev->dev);
switch (dev->flags & MODEL_MASK) {
--
Jean Delvare
SUSE L3 Support
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 3/3] i2c: designware: Turn models back to enumerated values
2025-09-18 14:03 [PATCH 0/3] i2c: designware: Misc small fixes Jean Delvare
2025-09-18 14:09 ` [PATCH 1/3] i2c: designware: Use msgs[0] to validate the slave address Jean Delvare
2025-09-18 14:10 ` [PATCH 2/3] i2c: designware: Extend check for mixed slave addresses Jean Delvare
@ 2025-09-18 14:13 ` Jean Delvare
2025-09-18 18:50 ` Andy Shevchenko
2025-09-19 12:13 ` [PATCH 0/3] i2c: designware: Misc small fixes Jarkko Nikula
3 siblings, 1 reply; 10+ messages in thread
From: Jean Delvare @ 2025-09-18 14:13 UTC (permalink / raw)
To: Linux I2C
Cc: Jarkko Nikula, Andy Shevchenko, Mika Westerberg, Jan Dabros,
Andi Shyti
There are 4 flag bits reserved to store the device model. All
accesses to this information is properly masked with MODEL_MASK to
extract only these bits and compare them with a given model value.
However the model definitions isn't an enumeration as you would
expect. Instead each model uses a separate flag, meaning that the
reserved space is already exhausted with the 4 models which have been
defined so far.
The error seems to originate from commit a5df4c14b9a9 ("i2c:
designware: Switch header to use BIT() and GENMASK()") where:
define MODEL_MSCC_OCELOT 0x00000100
define MODEL_BAIKAL_BT1 0x00000200
was erroneously converted to:
define MODEL_MSCC_OCELOT BIT(8)
define MODEL_BAIKAL_BT1 BIT(9)
While numerically equivalent, conceptually it wasn't, and it caused
the models added later to get bit-based definitions instead of
continuing with the next enumerated value (0x00000300).
Turn back these definitions to enumerated values to clear the
confusion, avoid future mistakes, and free some space for more models
to be supported in the future.
Signed-off-by: Jean Delvare <jdelvare@suse.de>
---
drivers/i2c/busses/i2c-designware-core.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- linux-6.16.orig/drivers/i2c/busses/i2c-designware-core.h
+++ linux-6.16/drivers/i2c/busses/i2c-designware-core.h
@@ -312,10 +312,10 @@ struct dw_i2c_dev {
#define ARBITRATION_SEMAPHORE BIT(2)
#define ACCESS_POLLING BIT(3)
-#define MODEL_MSCC_OCELOT BIT(8)
-#define MODEL_BAIKAL_BT1 BIT(9)
-#define MODEL_AMD_NAVI_GPU BIT(10)
-#define MODEL_WANGXUN_SP BIT(11)
+#define MODEL_MSCC_OCELOT (1 << 8)
+#define MODEL_BAIKAL_BT1 (2 << 8)
+#define MODEL_AMD_NAVI_GPU (3 << 8)
+#define MODEL_WANGXUN_SP (4 << 8)
#define MODEL_MASK GENMASK(11, 8)
/*
--
Jean Delvare
SUSE L3 Support
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] i2c: designware: Turn models back to enumerated values
2025-09-18 14:13 ` [PATCH 3/3] i2c: designware: Turn models back to enumerated values Jean Delvare
@ 2025-09-18 18:50 ` Andy Shevchenko
2025-09-19 8:38 ` Jean Delvare
0 siblings, 1 reply; 10+ messages in thread
From: Andy Shevchenko @ 2025-09-18 18:50 UTC (permalink / raw)
To: Jean Delvare
Cc: Linux I2C, Jarkko Nikula, Mika Westerberg, Jan Dabros, Andi Shyti
On Thu, Sep 18, 2025 at 04:13:01PM +0200, Jean Delvare wrote:
> There are 4 flag bits reserved to store the device model. All
> accesses to this information is properly masked with MODEL_MASK to
> extract only these bits and compare them with a given model value.
>
> However the model definitions isn't an enumeration as you would
> expect. Instead each model uses a separate flag, meaning that the
> reserved space is already exhausted with the 4 models which have been
> defined so far.
>
> The error seems to originate from commit a5df4c14b9a9 ("i2c:
> designware: Switch header to use BIT() and GENMASK()") where:
>
> define MODEL_MSCC_OCELOT 0x00000100
> define MODEL_BAIKAL_BT1 0x00000200
>
> was erroneously converted to:
I don't think "erroneously" is correct word here. The code before that commit
as you mentioned starts with a bit set, rather than from 0. I would argue that
the intention was to use a bitmask instead of plain number.
> define MODEL_MSCC_OCELOT BIT(8)
> define MODEL_BAIKAL_BT1 BIT(9)
>
> While numerically equivalent, conceptually it wasn't, and it caused
> the models added later to get bit-based definitions instead of
> continuing with the next enumerated value (0x00000300).
>
> Turn back these definitions to enumerated values to clear the
> confusion, avoid future mistakes, and free some space for more models
> to be supported in the future.
...
> -#define MODEL_MSCC_OCELOT BIT(8)
> -#define MODEL_BAIKAL_BT1 BIT(9)
> -#define MODEL_AMD_NAVI_GPU BIT(10)
> -#define MODEL_WANGXUN_SP BIT(11)
> +#define MODEL_MSCC_OCELOT (1 << 8)
> +#define MODEL_BAIKAL_BT1 (2 << 8)
> +#define MODEL_AMD_NAVI_GPU (3 << 8)
> +#define MODEL_WANGXUN_SP (4 << 8)
> #define MODEL_MASK GENMASK(11, 8)
Taking above into consideration, why can't we start them from 0?
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] i2c: designware: Turn models back to enumerated values
2025-09-18 18:50 ` Andy Shevchenko
@ 2025-09-19 8:38 ` Jean Delvare
0 siblings, 0 replies; 10+ messages in thread
From: Jean Delvare @ 2025-09-19 8:38 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Linux I2C, Jarkko Nikula, Mika Westerberg, Jan Dabros, Andi Shyti
Hi Andy,
On Thu, 18 Sep 2025 21:50:55 +0300, Andy Shevchenko wrote:
> On Thu, Sep 18, 2025 at 04:13:01PM +0200, Jean Delvare wrote:
> > There are 4 flag bits reserved to store the device model. All
> > accesses to this information is properly masked with MODEL_MASK to
> > extract only these bits and compare them with a given model value.
> >
> > However the model definitions isn't an enumeration as you would
> > expect. Instead each model uses a separate flag, meaning that the
> > reserved space is already exhausted with the 4 models which have been
> > defined so far.
> >
> > The error seems to originate from commit a5df4c14b9a9 ("i2c:
> > designware: Switch header to use BIT() and GENMASK()") where:
> >
> > define MODEL_MSCC_OCELOT 0x00000100
> > define MODEL_BAIKAL_BT1 0x00000200
> >
> > was erroneously converted to:
>
> I don't think "erroneously" is correct word here. The code before that commit
> as you mentioned starts with a bit set, rather than from 0. I would argue that
> the intention was to use a bitmask instead of plain number.
Models are mutually exclusive, so using a bit array to store that
information doesn't make sense. As a matter of fact, the driver code
which makes use of these values clearly assumes that they can't be
combined:
switch (dev->flags & MODEL_MASK) {
case MODEL_BAIKAL_BT1:
ret = bt1_i2c_request_regs(dev);
break;
case MODEL_WANGXUN_SP:
ret = txgbe_i2c_request_regs(dev);
break;
(...)
}
> > define MODEL_MSCC_OCELOT BIT(8)
> > define MODEL_BAIKAL_BT1 BIT(9)
> >
> > While numerically equivalent, conceptually it wasn't, and it caused
> > the models added later to get bit-based definitions instead of
> > continuing with the next enumerated value (0x00000300).
> >
> > Turn back these definitions to enumerated values to clear the
> > confusion, avoid future mistakes, and free some space for more models
> > to be supported in the future.
>
> ...
>
> > -#define MODEL_MSCC_OCELOT BIT(8)
> > -#define MODEL_BAIKAL_BT1 BIT(9)
> > -#define MODEL_AMD_NAVI_GPU BIT(10)
> > -#define MODEL_WANGXUN_SP BIT(11)
> > +#define MODEL_MSCC_OCELOT (1 << 8)
> > +#define MODEL_BAIKAL_BT1 (2 << 8)
> > +#define MODEL_AMD_NAVI_GPU (3 << 8)
> > +#define MODEL_WANGXUN_SP (4 << 8)
> > #define MODEL_MASK GENMASK(11, 8)
>
> Taking above into consideration, why can't we start them from 0?
Because model 0 is every other device which is neither MSCC Ocelot nor
Baikal BT1 nor AMD Navi nor Wangxun SP. We could define MODEL_OTHER as
(0 << 8), but there's not reason to ever use it in the code
(switch/case statements simply use default if something needs to be
done for standard devices), which is why nobody bothered defining it so
far.
--
Jean Delvare
SUSE L3 Support
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/3] i2c: designware: Misc small fixes
2025-09-18 14:03 [PATCH 0/3] i2c: designware: Misc small fixes Jean Delvare
` (2 preceding siblings ...)
2025-09-18 14:13 ` [PATCH 3/3] i2c: designware: Turn models back to enumerated values Jean Delvare
@ 2025-09-19 12:13 ` Jarkko Nikula
3 siblings, 0 replies; 10+ messages in thread
From: Jarkko Nikula @ 2025-09-19 12:13 UTC (permalink / raw)
To: Jean Delvare, Linux I2C
Cc: Andy Shevchenko, Mika Westerberg, Jan Dabros, Andi Shyti
Hi
On 9/18/25 5:03 PM, Jean Delvare wrote:
> Hi all,
>
> While working on CVE-2025-38380, I noticed a few issues in the
> i2c-designware driver, which I think are worth fixing now to make
> future driver development safer and easier.
>
> [PATCH 1/3] i2c: designware: Use msgs[0] to validate the slave address
> [PATCH 2/3] i2c: designware: Extend check for mixed slave addresses
> [PATCH 3/3] i2c: designware: Turn models back to enumerated values
>
> Note that I do not own any supported device so I can't test these
> changes. Even though the fixes are rather straightforward, I would
> appreciate if someone can test them on actual hardware, to be on the
> safe side.
>
I'm fine with the whole set.
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Tested-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] i2c: designware: Extend check for mixed slave addresses
2025-09-18 14:10 ` [PATCH 2/3] i2c: designware: Extend check for mixed slave addresses Jean Delvare
@ 2025-09-19 17:14 ` Jean Delvare
2025-09-22 8:14 ` [PATCH 2/3 v2] " Jean Delvare
0 siblings, 1 reply; 10+ messages in thread
From: Jean Delvare @ 2025-09-19 17:14 UTC (permalink / raw)
To: Linux I2C
Cc: Jarkko Nikula, Andy Shevchenko, Mika Westerberg, Jan Dabros,
Andi Shyti
On Thu, 18 Sep 2025 16:10:54 +0200, Jean Delvare wrote:
> The i2c-designware driver only supports transfers where all messages
> use the same slave address. This condition is currently tested in
> i2c_dw_xfer_msg(), with 2 limitations:
> * The code only checks the address value, not the 10-bit address
> flag, so it could miss an address change.
> * For the AMD Navi GPU devices, the driver uses a dedicated function
> instead of i2c_dw_xfer_msg(), so the check is not performed.
>
> Move the check to the common code path, and add the 10-bit address
> flag comparison, to catch and report early if a given transfer is not
> supported.
>
> Signed-off-by: Jean Delvare <jdelvare@suse.de>
> ---
> drivers/i2c/busses/i2c-designware-master.c | 28 ++++++++++++++--------------
> 1 file changed, 14 insertions(+), 14 deletions(-)
>
> --- linux-6.16.orig/drivers/i2c/busses/i2c-designware-master.c
> +++ linux-6.16/drivers/i2c/busses/i2c-designware-master.c
> @@ -429,7 +429,6 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
> struct i2c_msg *msgs = dev->msgs;
> u32 intr_mask;
> int tx_limit, rx_limit;
> - u32 addr = msgs[dev->msg_write_idx].addr;
> u32 buf_len = dev->tx_buf_len;
> u8 *buf = dev->tx_buf;
> bool need_restart = false;
> @@ -440,18 +439,6 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
> for (; dev->msg_write_idx < dev->msgs_num; dev->msg_write_idx++) {
> u32 flags = msgs[dev->msg_write_idx].flags;
>
> - /*
> - * If target address has changed, we need to
> - * reprogram the target address in the I2C
> - * adapter when we are done with this transfer.
> - */
> - if (msgs[dev->msg_write_idx].addr != addr) {
> - dev_err(dev->dev,
> - "%s: invalid target address\n", __func__);
> - dev->msg_err = -EINVAL;
> - break;
> - }
> -
> if (!(dev->status & STATUS_WRITE_IN_PROGRESS)) {
> /* new i2c_msg */
> buf = msgs[dev->msg_write_idx].buf;
> @@ -806,10 +793,23 @@ static int
> i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
> {
> struct dw_i2c_dev *dev = i2c_get_adapdata(adap);
> - int ret;
> + int ret, i;
>
> dev_dbg(dev->dev, "%s: msgs: %d\n", __func__, num);
>
> + /*
> + * This driver only supports I2C transfers where all the messages
> + * use the same address.
> + */
> + for (i = 1; i < num; i++) {
> + if (msgs[i].addr != msgs[0].addr ||
Note, I found meanwhile that some drivers (i2c-amd-mp2, i2c-mlxcpld)
use unlikely() to limit the performance penalty incurred by these
tests. Sounds like a good idea?
> + (msgs[i].flags & I2C_M_TEN) != (msgs[0].flags & I2C_M_TEN)) {
> + dev_err(dev->dev,
> + "Mixed slave addresses not supported\n");
> + return -EOPNOTSUPP;
> + }
> + }
> +
> pm_runtime_get_sync(dev->dev);
>
> switch (dev->flags & MODEL_MASK) {
>
--
Jean Delvare
SUSE L3 Support
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/3 v2] i2c: designware: Extend check for mixed slave addresses
2025-09-19 17:14 ` Jean Delvare
@ 2025-09-22 8:14 ` Jean Delvare
2025-09-22 10:22 ` Jarkko Nikula
0 siblings, 1 reply; 10+ messages in thread
From: Jean Delvare @ 2025-09-22 8:14 UTC (permalink / raw)
To: Linux I2C
Cc: Jarkko Nikula, Andy Shevchenko, Mika Westerberg, Jan Dabros,
Andi Shyti
The i2c-designware driver only supports transfers where all messages
use the same slave address. This condition is currently tested in
i2c_dw_xfer_msg(), with 2 limitations:
* The code only checks the address value, not the 10-bit address
flag, so it could miss an address change.
* For the AMD Navi GPU devices, the driver uses a dedicated function
instead of i2c_dw_xfer_msg(), so the check is not performed.
Move the check to the common code path, and add the 10-bit address
flag comparison, to catch and report early if a given transfer is not
supported.
Signed-off-by: Jean Delvare <jdelvare@suse.de>
---
Changes since v1:
* Use unlikely() to help the compiler minimize the performance penalty.
drivers/i2c/busses/i2c-designware-master.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
--- linux-6.16.orig/drivers/i2c/busses/i2c-designware-master.c
+++ linux-6.16/drivers/i2c/busses/i2c-designware-master.c
@@ -429,7 +429,6 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
struct i2c_msg *msgs = dev->msgs;
u32 intr_mask;
int tx_limit, rx_limit;
- u32 addr = msgs[dev->msg_write_idx].addr;
u32 buf_len = dev->tx_buf_len;
u8 *buf = dev->tx_buf;
bool need_restart = false;
@@ -440,18 +439,6 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
for (; dev->msg_write_idx < dev->msgs_num; dev->msg_write_idx++) {
u32 flags = msgs[dev->msg_write_idx].flags;
- /*
- * If target address has changed, we need to
- * reprogram the target address in the I2C
- * adapter when we are done with this transfer.
- */
- if (msgs[dev->msg_write_idx].addr != addr) {
- dev_err(dev->dev,
- "%s: invalid target address\n", __func__);
- dev->msg_err = -EINVAL;
- break;
- }
-
if (!(dev->status & STATUS_WRITE_IN_PROGRESS)) {
/* new i2c_msg */
buf = msgs[dev->msg_write_idx].buf;
@@ -806,10 +793,23 @@ static int
i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
{
struct dw_i2c_dev *dev = i2c_get_adapdata(adap);
- int ret;
+ int ret, i;
dev_dbg(dev->dev, "%s: msgs: %d\n", __func__, num);
+ /*
+ * This driver only supports I2C transfers where all the messages
+ * use the same address.
+ */
+ for (i = 1; i < num; i++) {
+ if (unlikely(msgs[i].addr != msgs[0].addr ||
+ (msgs[i].flags & I2C_M_TEN) != (msgs[0].flags & I2C_M_TEN))) {
+ dev_err(dev->dev,
+ "Mixed slave addresses not supported\n");
+ return -EOPNOTSUPP;
+ }
+ }
+
pm_runtime_get_sync(dev->dev);
switch (dev->flags & MODEL_MASK) {
--
Jean Delvare
SUSE L3 Support
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3 v2] i2c: designware: Extend check for mixed slave addresses
2025-09-22 8:14 ` [PATCH 2/3 v2] " Jean Delvare
@ 2025-09-22 10:22 ` Jarkko Nikula
0 siblings, 0 replies; 10+ messages in thread
From: Jarkko Nikula @ 2025-09-22 10:22 UTC (permalink / raw)
To: Jean Delvare, Linux I2C
Cc: Andy Shevchenko, Mika Westerberg, Jan Dabros, Andi Shyti
On 9/22/25 11:14 AM, Jean Delvare wrote:
> The i2c-designware driver only supports transfers where all messages
> use the same slave address. This condition is currently tested in
> i2c_dw_xfer_msg(), with 2 limitations:
> * The code only checks the address value, not the 10-bit address
> flag, so it could miss an address change.
> * For the AMD Navi GPU devices, the driver uses a dedicated function
> instead of i2c_dw_xfer_msg(), so the check is not performed.
>
> Move the check to the common code path, and add the 10-bit address
> flag comparison, to catch and report early if a given transfer is not
> supported.
>
> Signed-off-by: Jean Delvare <jdelvare@suse.de>
> ---
> Changes since v1:
> * Use unlikely() to help the compiler minimize the performance penalty.
>
> drivers/i2c/busses/i2c-designware-master.c | 28 ++++++++++++++--------------
> 1 file changed, 14 insertions(+), 14 deletions(-)
>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2025-09-22 10:22 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-18 14:03 [PATCH 0/3] i2c: designware: Misc small fixes Jean Delvare
2025-09-18 14:09 ` [PATCH 1/3] i2c: designware: Use msgs[0] to validate the slave address Jean Delvare
2025-09-18 14:10 ` [PATCH 2/3] i2c: designware: Extend check for mixed slave addresses Jean Delvare
2025-09-19 17:14 ` Jean Delvare
2025-09-22 8:14 ` [PATCH 2/3 v2] " Jean Delvare
2025-09-22 10:22 ` Jarkko Nikula
2025-09-18 14:13 ` [PATCH 3/3] i2c: designware: Turn models back to enumerated values Jean Delvare
2025-09-18 18:50 ` Andy Shevchenko
2025-09-19 8:38 ` Jean Delvare
2025-09-19 12:13 ` [PATCH 0/3] i2c: designware: Misc small fixes Jarkko Nikula
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox