All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] check: Add 10bit/slave i2c reg flags support
@ 2020-05-27 12:25 ` Serge Semin
  0 siblings, 0 replies; 14+ messages in thread
From: Serge Semin @ 2020-05-27 12:25 UTC (permalink / raw)
  To: devicetree-compiler
  Cc: Serge Semin, Serge Semin, Alexey Malahov, Thomas Bogendoerfer,
	Wolfram Sang, Jarkko Nikula, Andy Shevchenko, Frank Rowand,
	Rob Herring, devicetree, linux-i2c, linux-kernel

Recently the I2C-controllers slave interface support was added to the
kernel I2C subsystem. In this case Linux can be used as, for example,
a I2C EEPROM machine. See [1] for details. Other than instantiating
the EEPROM-slave device from user-space there is a way to declare the
device in dts. In this case firstly the I2C bus controller must support
the slave interface. Secondly I2C-slave sub-node of that controller
must have "reg"-property with flag I2C_OWN_SLAVE_ADDRESS set (flag is
declared in [2]). That flag is declared as (1 << 30), which when set
makes dtc unhappy about too big address set for a I2C-slave:

Warning (i2c_bus_reg): /example-2/i2c@1120000/eeprom@64: I2C bus unit address format error, expected "40000064"
Warning (i2c_bus_reg): /example-2/i2c@1120000/eeprom@64:reg: I2C address must be less than 10-bits, got "0x40000064"

Similar problem would have happened if we had set the 10-bit address
flag I2C_TEN_BIT_ADDRESS in the "reg"-property.

In order to fix the problem we suggest to alter the I2C-bus reg-check
algorithm, so one would be aware of the upper bits set. Normally if no
flag specified, the 7-bit address is expected in the "reg"-property.
If I2C_TEN_BIT_ADDRESS is set, then the 10-bit address check will be
performed. The I2C_OWN_SLAVE_ADDRESS flag will be just ignored.

[1] kernel/Documentation/i2c/slave-interface.rst
[2] kernel/include/dt-bindings/i2c/i2c.h

Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: Wolfram Sang <wsa@the-dreams.de>
Cc: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Frank Rowand <frowand.list@gmail.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: devicetree-compiler@vger.kernel.org
Cc: devicetree@vger.kernel.org
Cc: linux-i2c@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 checks.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/checks.c b/checks.c
index 4b3c486f1399..6321fc5b7404 100644
--- a/checks.c
+++ b/checks.c
@@ -1028,6 +1028,7 @@ static void check_i2c_bus_reg(struct check *c, struct dt_info *dti, struct node
 	const char *unitname = get_unitname(node);
 	char unit_addr[17];
 	uint32_t reg = 0;
+	uint32_t addr;
 	int len;
 	cell_t *cells = NULL;
 
@@ -1044,17 +1045,21 @@ static void check_i2c_bus_reg(struct check *c, struct dt_info *dti, struct node
 	}
 
 	reg = fdt32_to_cpu(*cells);
-	snprintf(unit_addr, sizeof(unit_addr), "%x", reg);
+	addr = reg & 0x3FFFFFFFU;
+	snprintf(unit_addr, sizeof(unit_addr), "%x", addr);
 	if (!streq(unitname, unit_addr))
 		FAIL(c, dti, node, "I2C bus unit address format error, expected \"%s\"",
 		     unit_addr);
 
 	for (len = prop->val.len; len > 0; len -= 4) {
 		reg = fdt32_to_cpu(*(cells++));
-		if (reg > 0x3ff)
+		addr = reg & 0x3FFFFFFFU;
+		if ((reg & (1 << 31)) && addr > 0x3ff)
 			FAIL_PROP(c, dti, node, prop, "I2C address must be less than 10-bits, got \"0x%x\"",
-				  reg);
-
+				  addr);
+		else if (!(reg & (1 << 31)) && addr > 0x7f)
+			FAIL_PROP(c, dti, node, prop, "I2C address must be less than 7-bits, got \"0x%x\"",
+				  addr);
 	}
 }
 WARNING(i2c_bus_reg, check_i2c_bus_reg, NULL, &reg_format, &i2c_bus_bridge);
-- 
2.26.2


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

* [PATCH] check: Add 10bit/slave i2c reg flags support
@ 2020-05-27 12:25 ` Serge Semin
  0 siblings, 0 replies; 14+ messages in thread
From: Serge Semin @ 2020-05-27 12:25 UTC (permalink / raw)
  To: devicetree-compiler
  Cc: Serge Semin, Serge Semin, Alexey Malahov, Thomas Bogendoerfer,
	Wolfram Sang, Jarkko Nikula, Andy Shevchenko, Frank Rowand,
	Rob Herring, devicetree, linux-i2c, linux-kernel

Recently the I2C-controllers slave interface support was added to the
kernel I2C subsystem. In this case Linux can be used as, for example,
a I2C EEPROM machine. See [1] for details. Other than instantiating
the EEPROM-slave device from user-space there is a way to declare the
device in dts. In this case firstly the I2C bus controller must support
the slave interface. Secondly I2C-slave sub-node of that controller
must have "reg"-property with flag I2C_OWN_SLAVE_ADDRESS set (flag is
declared in [2]). That flag is declared as (1 << 30), which when set
makes dtc unhappy about too big address set for a I2C-slave:

Warning (i2c_bus_reg): /example-2/i2c@1120000/eeprom@64: I2C bus unit address format error, expected "40000064"
Warning (i2c_bus_reg): /example-2/i2c@1120000/eeprom@64:reg: I2C address must be less than 10-bits, got "0x40000064"

Similar problem would have happened if we had set the 10-bit address
flag I2C_TEN_BIT_ADDRESS in the "reg"-property.

In order to fix the problem we suggest to alter the I2C-bus reg-check
algorithm, so one would be aware of the upper bits set. Normally if no
flag specified, the 7-bit address is expected in the "reg"-property.
If I2C_TEN_BIT_ADDRESS is set, then the 10-bit address check will be
performed. The I2C_OWN_SLAVE_ADDRESS flag will be just ignored.

[1] kernel/Documentation/i2c/slave-interface.rst
[2] kernel/include/dt-bindings/i2c/i2c.h

Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: Wolfram Sang <wsa@the-dreams.de>
Cc: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Frank Rowand <frowand.list@gmail.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: devicetree-compiler@vger.kernel.org
Cc: devicetree@vger.kernel.org
Cc: linux-i2c@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 checks.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/checks.c b/checks.c
index 4b3c486f1399..6321fc5b7404 100644
--- a/checks.c
+++ b/checks.c
@@ -1028,6 +1028,7 @@ static void check_i2c_bus_reg(struct check *c, struct dt_info *dti, struct node
 	const char *unitname = get_unitname(node);
 	char unit_addr[17];
 	uint32_t reg = 0;
+	uint32_t addr;
 	int len;
 	cell_t *cells = NULL;
 
@@ -1044,17 +1045,21 @@ static void check_i2c_bus_reg(struct check *c, struct dt_info *dti, struct node
 	}
 
 	reg = fdt32_to_cpu(*cells);
-	snprintf(unit_addr, sizeof(unit_addr), "%x", reg);
+	addr = reg & 0x3FFFFFFFU;
+	snprintf(unit_addr, sizeof(unit_addr), "%x", addr);
 	if (!streq(unitname, unit_addr))
 		FAIL(c, dti, node, "I2C bus unit address format error, expected \"%s\"",
 		     unit_addr);
 
 	for (len = prop->val.len; len > 0; len -= 4) {
 		reg = fdt32_to_cpu(*(cells++));
-		if (reg > 0x3ff)
+		addr = reg & 0x3FFFFFFFU;
+		if ((reg & (1 << 31)) && addr > 0x3ff)
 			FAIL_PROP(c, dti, node, prop, "I2C address must be less than 10-bits, got \"0x%x\"",
-				  reg);
-
+				  addr);
+		else if (!(reg & (1 << 31)) && addr > 0x7f)
+			FAIL_PROP(c, dti, node, prop, "I2C address must be less than 7-bits, got \"0x%x\"",
+				  addr);
 	}
 }
 WARNING(i2c_bus_reg, check_i2c_bus_reg, NULL, &reg_format, &i2c_bus_bridge);
-- 
2.26.2


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

* Re: [PATCH] check: Add 10bit/slave i2c reg flags support
@ 2020-05-27 13:36   ` Andy Shevchenko
  0 siblings, 0 replies; 14+ messages in thread
From: Andy Shevchenko @ 2020-05-27 13:36 UTC (permalink / raw)
  To: Serge Semin
  Cc: devicetree-compiler, Serge Semin, Alexey Malahov,
	Thomas Bogendoerfer, Wolfram Sang, Jarkko Nikula, Frank Rowand,
	Rob Herring, devicetree, linux-i2c, linux-kernel

On Wed, May 27, 2020 at 03:25:25PM +0300, Serge Semin wrote:
> Recently the I2C-controllers slave interface support was added to the
> kernel I2C subsystem. In this case Linux can be used as, for example,
> a I2C EEPROM machine. See [1] for details. Other than instantiating
> the EEPROM-slave device from user-space there is a way to declare the
> device in dts. In this case firstly the I2C bus controller must support
> the slave interface. Secondly I2C-slave sub-node of that controller
> must have "reg"-property with flag I2C_OWN_SLAVE_ADDRESS set (flag is
> declared in [2]). That flag is declared as (1 << 30), which when set
> makes dtc unhappy about too big address set for a I2C-slave:
> 
> Warning (i2c_bus_reg): /example-2/i2c@1120000/eeprom@64: I2C bus unit address format error, expected "40000064"
> Warning (i2c_bus_reg): /example-2/i2c@1120000/eeprom@64:reg: I2C address must be less than 10-bits, got "0x40000064"
> 
> Similar problem would have happened if we had set the 10-bit address
> flag I2C_TEN_BIT_ADDRESS in the "reg"-property.
> 
> In order to fix the problem we suggest to alter the I2C-bus reg-check
> algorithm, so one would be aware of the upper bits set. Normally if no
> flag specified, the 7-bit address is expected in the "reg"-property.
> If I2C_TEN_BIT_ADDRESS is set, then the 10-bit address check will be
> performed. The I2C_OWN_SLAVE_ADDRESS flag will be just ignored.
> 
> [1] kernel/Documentation/i2c/slave-interface.rst
> [2] kernel/include/dt-bindings/i2c/i2c.h

...

> +		addr = reg & 0x3FFFFFFFU;
> +		if ((reg & (1 << 31)) && addr > 0x3ff)
>  			FAIL_PROP(c, dti, node, prop, "I2C address must be less than 10-bits, got \"0x%x\"",
> -				  reg);
> -
> +				  addr);
> +		else if (!(reg & (1 << 31)) && addr > 0x7f)
> +			FAIL_PROP(c, dti, node, prop, "I2C address must be less than 7-bits, got \"0x%x\"",
> +				  addr);

1 << 31 is UB.

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH] check: Add 10bit/slave i2c reg flags support
@ 2020-05-27 13:36   ` Andy Shevchenko
  0 siblings, 0 replies; 14+ messages in thread
From: Andy Shevchenko @ 2020-05-27 13:36 UTC (permalink / raw)
  To: Serge Semin
  Cc: devicetree-compiler-u79uwXL29TY76Z2rM5mHXA, Serge Semin,
	Alexey Malahov, Thomas Bogendoerfer, Wolfram Sang, Jarkko Nikula,
	Frank Rowand, Rob Herring, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Wed, May 27, 2020 at 03:25:25PM +0300, Serge Semin wrote:
> Recently the I2C-controllers slave interface support was added to the
> kernel I2C subsystem. In this case Linux can be used as, for example,
> a I2C EEPROM machine. See [1] for details. Other than instantiating
> the EEPROM-slave device from user-space there is a way to declare the
> device in dts. In this case firstly the I2C bus controller must support
> the slave interface. Secondly I2C-slave sub-node of that controller
> must have "reg"-property with flag I2C_OWN_SLAVE_ADDRESS set (flag is
> declared in [2]). That flag is declared as (1 << 30), which when set
> makes dtc unhappy about too big address set for a I2C-slave:
> 
> Warning (i2c_bus_reg): /example-2/i2c@1120000/eeprom@64: I2C bus unit address format error, expected "40000064"
> Warning (i2c_bus_reg): /example-2/i2c@1120000/eeprom@64:reg: I2C address must be less than 10-bits, got "0x40000064"
> 
> Similar problem would have happened if we had set the 10-bit address
> flag I2C_TEN_BIT_ADDRESS in the "reg"-property.
> 
> In order to fix the problem we suggest to alter the I2C-bus reg-check
> algorithm, so one would be aware of the upper bits set. Normally if no
> flag specified, the 7-bit address is expected in the "reg"-property.
> If I2C_TEN_BIT_ADDRESS is set, then the 10-bit address check will be
> performed. The I2C_OWN_SLAVE_ADDRESS flag will be just ignored.
> 
> [1] kernel/Documentation/i2c/slave-interface.rst
> [2] kernel/include/dt-bindings/i2c/i2c.h

...

> +		addr = reg & 0x3FFFFFFFU;
> +		if ((reg & (1 << 31)) && addr > 0x3ff)
>  			FAIL_PROP(c, dti, node, prop, "I2C address must be less than 10-bits, got \"0x%x\"",
> -				  reg);
> -
> +				  addr);
> +		else if (!(reg & (1 << 31)) && addr > 0x7f)
> +			FAIL_PROP(c, dti, node, prop, "I2C address must be less than 7-bits, got \"0x%x\"",
> +				  addr);

1 << 31 is UB.

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH] check: Add 10bit/slave i2c reg flags support
@ 2020-05-27 14:00     ` Serge Semin
  0 siblings, 0 replies; 14+ messages in thread
From: Serge Semin @ 2020-05-27 14:00 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Serge Semin, devicetree-compiler, Alexey Malahov,
	Thomas Bogendoerfer, Wolfram Sang, Jarkko Nikula, Frank Rowand,
	Rob Herring, devicetree, linux-i2c, linux-kernel

On Wed, May 27, 2020 at 04:36:56PM +0300, Andy Shevchenko wrote:
> On Wed, May 27, 2020 at 03:25:25PM +0300, Serge Semin wrote:
> > Recently the I2C-controllers slave interface support was added to the
> > kernel I2C subsystem. In this case Linux can be used as, for example,
> > a I2C EEPROM machine. See [1] for details. Other than instantiating
> > the EEPROM-slave device from user-space there is a way to declare the
> > device in dts. In this case firstly the I2C bus controller must support
> > the slave interface. Secondly I2C-slave sub-node of that controller
> > must have "reg"-property with flag I2C_OWN_SLAVE_ADDRESS set (flag is
> > declared in [2]). That flag is declared as (1 << 30), which when set
> > makes dtc unhappy about too big address set for a I2C-slave:
> > 
> > Warning (i2c_bus_reg): /example-2/i2c@1120000/eeprom@64: I2C bus unit address format error, expected "40000064"
> > Warning (i2c_bus_reg): /example-2/i2c@1120000/eeprom@64:reg: I2C address must be less than 10-bits, got "0x40000064"
> > 
> > Similar problem would have happened if we had set the 10-bit address
> > flag I2C_TEN_BIT_ADDRESS in the "reg"-property.
> > 
> > In order to fix the problem we suggest to alter the I2C-bus reg-check
> > algorithm, so one would be aware of the upper bits set. Normally if no
> > flag specified, the 7-bit address is expected in the "reg"-property.
> > If I2C_TEN_BIT_ADDRESS is set, then the 10-bit address check will be
> > performed. The I2C_OWN_SLAVE_ADDRESS flag will be just ignored.
> > 
> > [1] kernel/Documentation/i2c/slave-interface.rst
> > [2] kernel/include/dt-bindings/i2c/i2c.h
> 
> ...
> 

> > +		addr = reg & 0x3FFFFFFFU;
> > +		if ((reg & (1 << 31)) && addr > 0x3ff)
> >  			FAIL_PROP(c, dti, node, prop, "I2C address must be less than 10-bits, got \"0x%x\"",
> > -				  reg);
> > -
> > +				  addr);
> > +		else if (!(reg & (1 << 31)) && addr > 0x7f)
> > +			FAIL_PROP(c, dti, node, prop, "I2C address must be less than 7-bits, got \"0x%x\"",
> > +				  addr);
> 
> 1 << 31 is UB.

Good point. Thanks.

-Sergey

> 
> -- 
> With Best Regards,
> Andy Shevchenko
> 
> 

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

* Re: [PATCH] check: Add 10bit/slave i2c reg flags support
@ 2020-05-27 14:00     ` Serge Semin
  0 siblings, 0 replies; 14+ messages in thread
From: Serge Semin @ 2020-05-27 14:00 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Serge Semin, devicetree-compiler-u79uwXL29TY76Z2rM5mHXA,
	Alexey Malahov, Thomas Bogendoerfer, Wolfram Sang, Jarkko Nikula,
	Frank Rowand, Rob Herring, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Wed, May 27, 2020 at 04:36:56PM +0300, Andy Shevchenko wrote:
> On Wed, May 27, 2020 at 03:25:25PM +0300, Serge Semin wrote:
> > Recently the I2C-controllers slave interface support was added to the
> > kernel I2C subsystem. In this case Linux can be used as, for example,
> > a I2C EEPROM machine. See [1] for details. Other than instantiating
> > the EEPROM-slave device from user-space there is a way to declare the
> > device in dts. In this case firstly the I2C bus controller must support
> > the slave interface. Secondly I2C-slave sub-node of that controller
> > must have "reg"-property with flag I2C_OWN_SLAVE_ADDRESS set (flag is
> > declared in [2]). That flag is declared as (1 << 30), which when set
> > makes dtc unhappy about too big address set for a I2C-slave:
> > 
> > Warning (i2c_bus_reg): /example-2/i2c@1120000/eeprom@64: I2C bus unit address format error, expected "40000064"
> > Warning (i2c_bus_reg): /example-2/i2c@1120000/eeprom@64:reg: I2C address must be less than 10-bits, got "0x40000064"
> > 
> > Similar problem would have happened if we had set the 10-bit address
> > flag I2C_TEN_BIT_ADDRESS in the "reg"-property.
> > 
> > In order to fix the problem we suggest to alter the I2C-bus reg-check
> > algorithm, so one would be aware of the upper bits set. Normally if no
> > flag specified, the 7-bit address is expected in the "reg"-property.
> > If I2C_TEN_BIT_ADDRESS is set, then the 10-bit address check will be
> > performed. The I2C_OWN_SLAVE_ADDRESS flag will be just ignored.
> > 
> > [1] kernel/Documentation/i2c/slave-interface.rst
> > [2] kernel/include/dt-bindings/i2c/i2c.h
> 
> ...
> 

> > +		addr = reg & 0x3FFFFFFFU;
> > +		if ((reg & (1 << 31)) && addr > 0x3ff)
> >  			FAIL_PROP(c, dti, node, prop, "I2C address must be less than 10-bits, got \"0x%x\"",
> > -				  reg);
> > -
> > +				  addr);
> > +		else if (!(reg & (1 << 31)) && addr > 0x7f)
> > +			FAIL_PROP(c, dti, node, prop, "I2C address must be less than 7-bits, got \"0x%x\"",
> > +				  addr);
> 
> 1 << 31 is UB.

Good point. Thanks.

-Sergey

> 
> -- 
> With Best Regards,
> Andy Shevchenko
> 
> 

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

* [PATCH v2] check: Add 10bit/slave i2c reg flags support
  2020-05-27 12:25 ` Serge Semin
@ 2020-05-27 14:15   ` Serge Semin
  -1 siblings, 0 replies; 14+ messages in thread
From: Serge Semin @ 2020-05-27 14:15 UTC (permalink / raw)
  To: devicetree-compiler
  Cc: Serge Semin, Serge Semin, Alexey Malahov, Thomas Bogendoerfer,
	Wolfram Sang, Jarkko Nikula, Andy Shevchenko, Frank Rowand,
	Rob Herring, devicetree, linux-i2c, linux-kernel

Recently the I2C-controllers slave interface support was added to the
kernel I2C subsystem. In this case Linux can be used as, for example,
a I2C EEPROM machine. See [1] for details. Other than instantiating
the EEPROM-slave device from user-space there is a way to declare the
device in dts. In this case firstly the I2C bus controller must support
the slave interface. Secondly I2C-slave sub-node of that controller
must have "reg"-property with flag I2C_OWN_SLAVE_ADDRESS set (flag is
declared in [2]). That flag is declared as (1 << 30), which when set
makes dtc unhappy about too big address set for a I2C-slave:

Warning (i2c_bus_reg): /example-2/i2c@1120000/eeprom@64: I2C bus unit address format error, expected "40000064"
Warning (i2c_bus_reg): /example-2/i2c@1120000/eeprom@64:reg: I2C address must be less than 10-bits, got "0x40000064"

Similar problem would have happened if we had set the 10-bit address
flag I2C_TEN_BIT_ADDRESS in the "reg"-property.

In order to fix the problem we suggest to alter the I2C-bus reg-check
algorithm, so one would be aware of the upper bits set. Normally if no
flag specified, the 7-bit address is expected in the "reg"-property.
If I2C_TEN_BIT_ADDRESS is set, then the 10-bit address check will be
performed. The I2C_OWN_SLAVE_ADDRESS flag will be just ignored.

[1] kernel/Documentation/i2c/slave-interface.rst
[2] kernel/include/dt-bindings/i2c/i2c.h

Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: Wolfram Sang <wsa@the-dreams.de>
Cc: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Frank Rowand <frowand.list@gmail.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: devicetree-compiler@vger.kernel.org
Cc: devicetree@vger.kernel.org
Cc: linux-i2c@vger.kernel.org
Cc: linux-kernel@vger.kernel.org

---

Changelog v2:
- Use unsigned numeric literal in the left-shit operation to avoid UB.
---
 checks.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/checks.c b/checks.c
index 4b3c486f1399..7091d1bc38d2 100644
--- a/checks.c
+++ b/checks.c
@@ -1028,6 +1028,7 @@ static void check_i2c_bus_reg(struct check *c, struct dt_info *dti, struct node
 	const char *unitname = get_unitname(node);
 	char unit_addr[17];
 	uint32_t reg = 0;
+	uint32_t addr;
 	int len;
 	cell_t *cells = NULL;
 
@@ -1044,17 +1045,21 @@ static void check_i2c_bus_reg(struct check *c, struct dt_info *dti, struct node
 	}
 
 	reg = fdt32_to_cpu(*cells);
-	snprintf(unit_addr, sizeof(unit_addr), "%x", reg);
+	addr = reg & 0x3FFFFFFFU;
+	snprintf(unit_addr, sizeof(unit_addr), "%x", addr);
 	if (!streq(unitname, unit_addr))
 		FAIL(c, dti, node, "I2C bus unit address format error, expected \"%s\"",
 		     unit_addr);
 
 	for (len = prop->val.len; len > 0; len -= 4) {
 		reg = fdt32_to_cpu(*(cells++));
-		if (reg > 0x3ff)
+		addr = reg & 0x3FFFFFFFU;
+		if ((reg & (1U << 31)) && addr > 0x3ff)
 			FAIL_PROP(c, dti, node, prop, "I2C address must be less than 10-bits, got \"0x%x\"",
-				  reg);
-
+				  addr);
+		else if (!(reg & (1U << 31)) && addr > 0x7f)
+			FAIL_PROP(c, dti, node, prop, "I2C address must be less than 7-bits, got \"0x%x\"",
+				  addr);
 	}
 }
 WARNING(i2c_bus_reg, check_i2c_bus_reg, NULL, &reg_format, &i2c_bus_bridge);
-- 
2.26.2


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

* [PATCH v2] check: Add 10bit/slave i2c reg flags support
@ 2020-05-27 14:15   ` Serge Semin
  0 siblings, 0 replies; 14+ messages in thread
From: Serge Semin @ 2020-05-27 14:15 UTC (permalink / raw)
  To: devicetree-compiler
  Cc: Serge Semin, Serge Semin, Alexey Malahov, Thomas Bogendoerfer,
	Wolfram Sang, Jarkko Nikula, Andy Shevchenko, Frank Rowand,
	Rob Herring, devicetree, linux-i2c, linux-kernel

Recently the I2C-controllers slave interface support was added to the
kernel I2C subsystem. In this case Linux can be used as, for example,
a I2C EEPROM machine. See [1] for details. Other than instantiating
the EEPROM-slave device from user-space there is a way to declare the
device in dts. In this case firstly the I2C bus controller must support
the slave interface. Secondly I2C-slave sub-node of that controller
must have "reg"-property with flag I2C_OWN_SLAVE_ADDRESS set (flag is
declared in [2]). That flag is declared as (1 << 30), which when set
makes dtc unhappy about too big address set for a I2C-slave:

Warning (i2c_bus_reg): /example-2/i2c@1120000/eeprom@64: I2C bus unit address format error, expected "40000064"
Warning (i2c_bus_reg): /example-2/i2c@1120000/eeprom@64:reg: I2C address must be less than 10-bits, got "0x40000064"

Similar problem would have happened if we had set the 10-bit address
flag I2C_TEN_BIT_ADDRESS in the "reg"-property.

In order to fix the problem we suggest to alter the I2C-bus reg-check
algorithm, so one would be aware of the upper bits set. Normally if no
flag specified, the 7-bit address is expected in the "reg"-property.
If I2C_TEN_BIT_ADDRESS is set, then the 10-bit address check will be
performed. The I2C_OWN_SLAVE_ADDRESS flag will be just ignored.

[1] kernel/Documentation/i2c/slave-interface.rst
[2] kernel/include/dt-bindings/i2c/i2c.h

Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: Wolfram Sang <wsa@the-dreams.de>
Cc: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Frank Rowand <frowand.list@gmail.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: devicetree-compiler@vger.kernel.org
Cc: devicetree@vger.kernel.org
Cc: linux-i2c@vger.kernel.org
Cc: linux-kernel@vger.kernel.org

---

Changelog v2:
- Use unsigned numeric literal in the left-shit operation to avoid UB.
---
 checks.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/checks.c b/checks.c
index 4b3c486f1399..7091d1bc38d2 100644
--- a/checks.c
+++ b/checks.c
@@ -1028,6 +1028,7 @@ static void check_i2c_bus_reg(struct check *c, struct dt_info *dti, struct node
 	const char *unitname = get_unitname(node);
 	char unit_addr[17];
 	uint32_t reg = 0;
+	uint32_t addr;
 	int len;
 	cell_t *cells = NULL;
 
@@ -1044,17 +1045,21 @@ static void check_i2c_bus_reg(struct check *c, struct dt_info *dti, struct node
 	}
 
 	reg = fdt32_to_cpu(*cells);
-	snprintf(unit_addr, sizeof(unit_addr), "%x", reg);
+	addr = reg & 0x3FFFFFFFU;
+	snprintf(unit_addr, sizeof(unit_addr), "%x", addr);
 	if (!streq(unitname, unit_addr))
 		FAIL(c, dti, node, "I2C bus unit address format error, expected \"%s\"",
 		     unit_addr);
 
 	for (len = prop->val.len; len > 0; len -= 4) {
 		reg = fdt32_to_cpu(*(cells++));
-		if (reg > 0x3ff)
+		addr = reg & 0x3FFFFFFFU;
+		if ((reg & (1U << 31)) && addr > 0x3ff)
 			FAIL_PROP(c, dti, node, prop, "I2C address must be less than 10-bits, got \"0x%x\"",
-				  reg);
-
+				  addr);
+		else if (!(reg & (1U << 31)) && addr > 0x7f)
+			FAIL_PROP(c, dti, node, prop, "I2C address must be less than 7-bits, got \"0x%x\"",
+				  addr);
 	}
 }
 WARNING(i2c_bus_reg, check_i2c_bus_reg, NULL, &reg_format, &i2c_bus_bridge);
-- 
2.26.2


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

* Re: [PATCH v2] check: Add 10bit/slave i2c reg flags support
  2020-05-27 14:15   ` Serge Semin
  (?)
@ 2020-05-30  9:31   ` Wolfram Sang
  2020-05-31 19:07       ` Serge Semin
  2020-06-01 17:08     ` Rob Herring
  -1 siblings, 2 replies; 14+ messages in thread
From: Wolfram Sang @ 2020-05-30  9:31 UTC (permalink / raw)
  To: Serge Semin
  Cc: devicetree-compiler, Serge Semin, Alexey Malahov,
	Thomas Bogendoerfer, Jarkko Nikula, Andy Shevchenko,
	Frank Rowand, Rob Herring, devicetree, linux-i2c, linux-kernel

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


> +	addr = reg & 0x3FFFFFFFU;
> +	snprintf(unit_addr, sizeof(unit_addr), "%x", addr);

Hmm, this hardcoded value will not work if we ever need to add another
bit. I hope this will never happen, though.

> +		if ((reg & (1U << 31)) && addr > 0x3ff)

Same here with bit 31. I haven't checked DTC but can't we import the
header with the defines into the project? Or is this then a circular
dependency?


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

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

* Re: [PATCH v2] check: Add 10bit/slave i2c reg flags support
  2020-05-30  9:31   ` Wolfram Sang
@ 2020-05-31 19:07       ` Serge Semin
  2020-06-01 17:08     ` Rob Herring
  1 sibling, 0 replies; 14+ messages in thread
From: Serge Semin @ 2020-05-31 19:07 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: Serge Semin, devicetree-compiler, Alexey Malahov,
	Thomas Bogendoerfer, Jarkko Nikula, Andy Shevchenko,
	Frank Rowand, Rob Herring, devicetree, linux-i2c, linux-kernel

On Sat, May 30, 2020 at 11:31:52AM +0200, Wolfram Sang wrote:
> 
> > +	addr = reg & 0x3FFFFFFFU;
> > +	snprintf(unit_addr, sizeof(unit_addr), "%x", addr);
> 
> Hmm, this hardcoded value will not work if we ever need to add another
> bit. I hope this will never happen, though.
> 
> > +		if ((reg & (1U << 31)) && addr > 0x3ff)
> 
> Same here with bit 31.

I'd be glad to use a macro or some helper here, but alas there is no
ready-to-use i2c-related one in the dtc code. See, there are hard-coded
literals in the PCI nodes checkers (check_pci_device_reg(),
check_pci_device_bus_num()) and the hard-coded literals've been in the
i2c-nodes checkers even before this patch.

> I haven't checked DTC but can't we import the
> header with the defines into the project? Or is this then a circular
> dependency?
> 

I guess importing header would be much better than the hard-coded values
currently used. What do the code maintainers say about that? Any idea how it
is supposed to be implemented?

-Sergey

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

* Re: [PATCH v2] check: Add 10bit/slave i2c reg flags support
@ 2020-05-31 19:07       ` Serge Semin
  0 siblings, 0 replies; 14+ messages in thread
From: Serge Semin @ 2020-05-31 19:07 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: Serge Semin, devicetree-compiler-u79uwXL29TY76Z2rM5mHXA,
	Alexey Malahov, Thomas Bogendoerfer, Jarkko Nikula,
	Andy Shevchenko, Frank Rowand, Rob Herring,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Sat, May 30, 2020 at 11:31:52AM +0200, Wolfram Sang wrote:
> 
> > +	addr = reg & 0x3FFFFFFFU;
> > +	snprintf(unit_addr, sizeof(unit_addr), "%x", addr);
> 
> Hmm, this hardcoded value will not work if we ever need to add another
> bit. I hope this will never happen, though.
> 
> > +		if ((reg & (1U << 31)) && addr > 0x3ff)
> 
> Same here with bit 31.

I'd be glad to use a macro or some helper here, but alas there is no
ready-to-use i2c-related one in the dtc code. See, there are hard-coded
literals in the PCI nodes checkers (check_pci_device_reg(),
check_pci_device_bus_num()) and the hard-coded literals've been in the
i2c-nodes checkers even before this patch.

> I haven't checked DTC but can't we import the
> header with the defines into the project? Or is this then a circular
> dependency?
> 

I guess importing header would be much better than the hard-coded values
currently used. What do the code maintainers say about that? Any idea how it
is supposed to be implemented?

-Sergey

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

* Re: [PATCH v2] check: Add 10bit/slave i2c reg flags support
  2020-05-30  9:31   ` Wolfram Sang
  2020-05-31 19:07       ` Serge Semin
@ 2020-06-01 17:08     ` Rob Herring
  2020-06-02  7:46         ` Wolfram Sang
  1 sibling, 1 reply; 14+ messages in thread
From: Rob Herring @ 2020-06-01 17:08 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: Serge Semin, Devicetree Compiler, Serge Semin, Alexey Malahov,
	Thomas Bogendoerfer, Jarkko Nikula, Andy Shevchenko,
	Frank Rowand, devicetree, Linux I2C, linux-kernel

On Sat, May 30, 2020 at 3:32 AM Wolfram Sang <wsa@the-dreams.de> wrote:
>
>
> > +     addr = reg & 0x3FFFFFFFU;
> > +     snprintf(unit_addr, sizeof(unit_addr), "%x", addr);
>
> Hmm, this hardcoded value will not work if we ever need to add another
> bit. I hope this will never happen, though.

I had this concern and requested the first time this was submitted
(and abandoned) to just mask out the top byte. However, Joel's version
of this fix[1] does some actual checks on 10-bit addressing, so I've
dropped that request.

> > +             if ((reg & (1U << 31)) && addr > 0x3ff)
>
> Same here with bit 31. I haven't checked DTC but can't we import the
> header with the defines into the project? Or is this then a circular
> dependency?

Easier to just duplicate the define here which Joel's patches do.

Rob

[1] https://www.spinics.net/lists/devicetree-compiler/msg03196.html

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

* Re: [PATCH v2] check: Add 10bit/slave i2c reg flags support
@ 2020-06-02  7:46         ` Wolfram Sang
  0 siblings, 0 replies; 14+ messages in thread
From: Wolfram Sang @ 2020-06-02  7:46 UTC (permalink / raw)
  To: Rob Herring
  Cc: Serge Semin, Devicetree Compiler, Serge Semin, Alexey Malahov,
	Thomas Bogendoerfer, Jarkko Nikula, Andy Shevchenko,
	Frank Rowand, devicetree, Linux I2C, linux-kernel

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


> Easier to just duplicate the define here which Joel's patches do.

Well, seems this case is closed then. Thanks everyone!


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

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

* Re: [PATCH v2] check: Add 10bit/slave i2c reg flags support
@ 2020-06-02  7:46         ` Wolfram Sang
  0 siblings, 0 replies; 14+ messages in thread
From: Wolfram Sang @ 2020-06-02  7:46 UTC (permalink / raw)
  To: Rob Herring
  Cc: Serge Semin, Devicetree Compiler, Serge Semin, Alexey Malahov,
	Thomas Bogendoerfer, Jarkko Nikula, Andy Shevchenko,
	Frank Rowand, devicetree-u79uwXL29TY76Z2rM5mHXA, Linux I2C,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

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


> Easier to just duplicate the define here which Joel's patches do.

Well, seems this case is closed then. Thanks everyone!


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

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

end of thread, other threads:[~2020-06-02  7:46 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-27 12:25 [PATCH] check: Add 10bit/slave i2c reg flags support Serge Semin
2020-05-27 12:25 ` Serge Semin
2020-05-27 13:36 ` Andy Shevchenko
2020-05-27 13:36   ` Andy Shevchenko
2020-05-27 14:00   ` Serge Semin
2020-05-27 14:00     ` Serge Semin
2020-05-27 14:15 ` [PATCH v2] " Serge Semin
2020-05-27 14:15   ` Serge Semin
2020-05-30  9:31   ` Wolfram Sang
2020-05-31 19:07     ` Serge Semin
2020-05-31 19:07       ` Serge Semin
2020-06-01 17:08     ` Rob Herring
2020-06-02  7:46       ` Wolfram Sang
2020-06-02  7:46         ` Wolfram Sang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.