2022-04-06 13:52:43

by Vincent Whitchurch

[permalink] [raw]
Subject: [PATCH 0/2] i2c: Allow disabling auto detection via devicetree

When a driver with a ->detect callback (such as lm75) is loaded, the i2c core
performs I2C transactions on the bus to all the addresses listed in that
driver's address_list. This kind of probing wastes time and as
Documentation/i2c/instantiating-devices.rst says, this method is not
recommended and it is instead advised to list all devices in the devicetree.

However, even if all the devices are listed in the devicetree, there is
currently no way to prevent the core from attempting auto detection short of
patching controller drivers to not pass the I2C_CLASS* bits in adap->class.
The latter is not always possible since generic drivers like i2c-gpio set these
bits.

To avoid this unnecessary probing and reduce boot time, this series adds a
property to the devicetree and support in the I2C core to allow this feature to
be disabled.

Cc: [email protected]

Cc: [email protected]
Cc: [email protected]
Cc: [email protected]

Cc: [email protected]

Vincent Whitchurch (2):
i2c: add binding to prevent device detection
i2c: core: support no-detect property

Documentation/devicetree/bindings/i2c/i2c.txt | 4 ++++
drivers/i2c/i2c-core-base.c | 8 +++++++-
include/linux/i2c.h | 1 +
3 files changed, 12 insertions(+), 1 deletion(-)

--
2.34.1


2022-04-06 14:48:28

by Vincent Whitchurch

[permalink] [raw]
Subject: [PATCH 2/2] i2c: core: support no-detect property

If the devicetree specifies the no-detect property, we can avoid calling
drivers' detect callback and wasting time probing for devices which do
not exist.

Signed-off-by: Vincent Whitchurch <[email protected]>
---
drivers/i2c/i2c-core-base.c | 8 +++++++-
include/linux/i2c.h | 1 +
2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index d43db2c3876e..d43025b84546 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -1341,7 +1341,8 @@ static int i2c_do_add_adapter(struct i2c_driver *driver,
struct i2c_adapter *adap)
{
/* Detect supported devices on that bus, and instantiate them */
- i2c_detect(adap, driver);
+ if (adap->detect)
+ i2c_detect(adap, driver);

return 0;
}
@@ -1432,6 +1433,7 @@ EXPORT_SYMBOL_GPL(i2c_handle_smbus_host_notify);

static int i2c_register_adapter(struct i2c_adapter *adap)
{
+ struct device_node *np = adap->dev.of_node;
int res = -EINVAL;

/* Can't register until after driver model init */
@@ -1502,6 +1504,10 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
"Failed to create compatibility class link\n");
#endif

+ adap->detect = true;
+ if (np && of_property_read_bool(np, "no-detect"))
+ adap->detect = false;
+
/* create pre-declared device nodes */
of_i2c_register_devices(adap);
i2c_acpi_install_space_handler(adap);
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index fbda5ada2afc..8fad5fe85685 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -728,6 +728,7 @@ struct i2c_adapter {
struct rt_mutex bus_lock;
struct rt_mutex mux_lock;

+ bool detect;
int timeout; /* in jiffies */
int retries;
struct device dev; /* the adapter device */
--
2.34.1