i2c bus multiplexing (Version 2).
Subsystems (3)
This patch set adds to the I2C core the ability to handle multiplexed I2C bus topologies by presenting each multiplexed segment as a I2C adapter.
As you can see from the changelog I had to update i2c-core since when a real adapter (not multiplexer) driver is inserted into the kernel _after_ an i2c multiplxer one, function i2c_add_adapter() is called recursively (and the same for i2c_del_adapter() during module removal) causing a kernel hang due the i2c's "core_lock" mutex.
Changelog
=========
Version 1 -> 2:
---------------
* Fixes a bug related to recursive calls of i2c_(add|del)_adapter() functions when main adapter is inserted or removed _after_ slave adapetrs (i2c multiplexers).
This goal has been achieved by:
a) using rwsem instead of mutex for accessing board info data struct,
b) ignoring any active client detaching faults (see relative patch for further info),
c) removing "core_lock" mutex into adapters (de)registration code.
Rodolfo
--
b/drivers/i2c/Kconfig | 10 + b/drivers/i2c/Makefile | 3 b/drivers/i2c/i2c-boardinfo.c | 6 b/drivers/i2c/i2c-core.c | 4 b/drivers/i2c/i2c-core.h | 2 b/drivers/i2c/i2c-mux.c | 180 +++++++++++++++++++++++ b/drivers/i2c/muxes/Kconfig | 8 + b/drivers/i2c/muxes/Makefile | 6 b/drivers/i2c/muxes/pca954x.c | 325 ++++++++++++++++++++++++++++++++++++++++++ b/include/linux/i2c-id.h | 3 b/include/linux/i2c.h | 14 + b/include/linux/i2c/pca954x.h | 13 + drivers/i2c/i2c-core.c | 78 ++++------ drivers/i2c/muxes/Kconfig | 9 + drivers/i2c/muxes/Makefile | 2 15 files changed, 615 insertions(+), 48 deletions(-)
A message that is not in the archive (sent off-list or not yet received): 1233840973-13268-1-git-send-email-giometti-k2GhghHVRtY@public.gmane.org
PATCH 1/6 i2c: put driver_unregister() out of core_lock protection.
As for i2c_register_driver() during driver registration only class_for_each_device() call is protected by the i2c "core_lock" so we can (hopefully) do the same during driver deletion.
--- drivers/i2c/i2c-core.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/i2c/i2c-core.c +2 -2
@@ -799,10 +799,10 @@ void i2c_del_driver(struct i2c_driver *driver)class_for_each_device (&i2c_adapter_class,NULL , driver, __detach_adapter); +mutex_unlock (&core_lock); +driver_unregister (&driver->driver);pr_debug ("i2c-core: driver [%s] unregistered\n" , driver->driver.name); - -mutex_unlock (&core_lock); }EXPORT_SYMBOL (i2c_del_driver);
Signature · 1 line
1.5.6.3
A message that is not in the archive (sent off-list or not yet received): 1233840973-13268-2-git-send-email-giometti-k2GhghHVRtY@public.gmane.org
PATCH 2/6 i2c: use rwsem instead of mutex.
By using rwsem we can easily manage recursive calls of i2c_scan_static_board_info() function without breaking the locking.
--- drivers/i2c/i2c-boardinfo.c | 6 +++--- drivers/i2c/i2c-core.c | 4 ++-- drivers/i2c/i2c-core.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-)
drivers/i2c/i2c-boardinfo.c +3 -3
@@ -25,7 +25,7 @@/* These symbols are exported ONLY FOR the i2c core. * No other users will be supported. */ -DEFINE_MUTEX (__i2c_board_lock); +DECLARE_RWSEM (__i2c_board_lock);EXPORT_SYMBOL_GPL (__i2c_board_lock);LIST_HEAD (__i2c_board_list);
@@ -63,7 +63,7 @@ i2c_register_board_info(int busnum, {int status; -mutex_lock (&__i2c_board_lock); +down_write (&__i2c_board_lock);/* dynamic bus numbers will be assigned after the last static one */ if (busnum >= __i2c_first_dynamic_bus_num)
@@ -84,7 +84,7 @@ i2c_register_board_info(int busnum,list_add_tail (&devinfo->list, &__i2c_board_list); } -mutex_unlock (&__i2c_board_lock); +up_write (&__i2c_board_lock);return status; }
drivers/i2c/i2c-core.c +2 -2
@@ -408,7 +408,7 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter) { struct i2c_devinfo *devinfo; - mutex_lock(&__i2c_board_lock); + down_read(&__i2c_board_lock); list_for_each_entry(devinfo, &__i2c_board_list, list) { if (devinfo->busnum == adapter->nr && !i2c_new_device(adapter,
@@ -417,7 +417,7 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter)i2c_adapter_id (adapter), devinfo->board_info.addr); } -mutex_unlock (&__i2c_board_lock); +up_read (&__i2c_board_lock); }static int i2c_do_add_adapter (struct device_driver *d,void *data)
drivers/i2c/i2c-core.h +1 -1
@@ -25,7 +25,7 @@ struct i2c_devinfo {/* board_lock protects board_list and first_dynamic_bus_num. * only i2c core components are allowed to use these symbols. */ -extern struct mutex __i2c_board_lock; +extern struct rw_semaphore __i2c_board_lock;extern struct list_head __i2c_board_list;extern int __i2c_first_dynamic_bus_num;
Signature · 1 line
1.5.6.3
A message that is not in the archive (sent off-list or not yet received): 1233840973-13268-3-git-send-email-giometti-k2GhghHVRtY@public.gmane.org
PATCH 3/6 i2c: ignore active clients detaching during adapter removal.
When we are removing an adapter we decide to ignore any active client detaching faults for two reasons:
1) one (or more) active client may be switched off, so it cannot replay to the "adapter removed" event.
2) it shouldn't happen, and even if it happens it may be due a bus fault which can be resolved by resetting the adapter (most of them can be resetted simply by rmmod and then insmod the module again).
--- drivers/i2c/i2c-core.c | 17 +++++++---------- 1 files changed, 7 insertions(+), 10 deletions(-)
drivers/i2c/i2c-core.c +7 -10
@@ -593,11 +593,13 @@ static int i2c_do_del_adapter(struct device_driver *d, void *data)if (!driver->detach_adapter)return 0 ; + +/* We ignore the return code; if it fails, too bad */ res = driver->detach_adapter (adapter);if (res)dev_err (&adapter->dev,"detach_adapter failed (%d) " "for driver [%s]\n" , res, driver->driver.name); -return res; +return 0 ; }/**
@@ -611,7 +613,7 @@ static int i2c_do_del_adapter(struct device_driver *d, void *data)int i2c_del_adapter (struct i2c_adapter *adap) {struct i2c_client *client, *_n; -int res =0 ; +int res =0 , dummy;mutex_lock (&core_lock);
@@ -624,13 +626,10 @@ int i2c_del_adapter(struct i2c_adapter *adap) }/* Tell drivers about this removal */ - res =bus_for_each_drv (&i2c_bus_type,NULL , adap, + dummy =bus_for_each_drv (&i2c_bus_type,NULL , adap, i2c_do_del_adapter); -if (res) - goto out_unlock; -/* detach any active clients. This must be done first, because -* it can fail; in which case we give up. */ +/* Detach any active clients */ list_for_each_entry_safe_reverse (client, _n, &adap->clients, list) {struct i2c_driver *driver;
@@ -643,12 +642,10 @@ int i2c_del_adapter(struct i2c_adapter *adap) }/* legacy drivers create and remove clients themselves */ -if ((res = driver->detach_client (client))) { +if (driver->detach_client (client))dev_err (&adap->dev,"detach_client failed for client " "[%s] at address 0x%02x\n" , client->name, client->addr); - goto out_unlock; - } }/* clean up the sysfs representation */
Signature · 1 line
1.5.6.3
A message that is not in the archive (sent off-list or not yet received): 1233840973-13268-4-git-send-email-giometti-k2GhghHVRtY@public.gmane.org
PATCH 4/6 i2c: free adapters (de)registration from i2c "core_lock" mutex.
The adapters (de)registration are now protectd by using a dedicated mutex instead of using global "core_lock" one. This allow multiple (and recursive) (de)registration of several adapters (or i2c multiplexers acting as i2c virtual adapters).
--- drivers/i2c/i2c-core.c | 57 +++++++++++++++++++++++------------------------ 1 files changed, 28 insertions(+), 29 deletions(-)
drivers/i2c/i2c-core.c +28 -29
@@ -40,6 +40,7 @@static DEFINE_MUTEX (core_lock); +static DEFINE_MUTEX (idr_adapter_lock);static DEFINE_IDR (i2c_adapter_idr);#define is_newstyle_driver (d) ((d)->probe || (d)->remove || (d)->detect)
@@ -438,7 +439,7 @@ static int i2c_do_add_adapter(struct device_driver *d, void *data)static int i2c_register_adapter (struct i2c_adapter *adap) { -int res =0 , dummy; +int res, dummy;/* Can't register until after driver model init */ if (unlikely (WARN_ON (!i2c_bus_type.p)))
@@ -448,8 +449,6 @@ static int i2c_register_adapter(struct i2c_adapter *adap)mutex_init (&adap->clist_lock);INIT_LIST_HEAD (&adap->clients); -mutex_lock (&core_lock); -/* Add the adapter to the driver core. * If the parent pointer is not set up, * we add this adapter to the host bus.
@@ -463,8 +462,13 @@ static int i2c_register_adapter(struct i2c_adapter *adap) adap->dev.release = &i2c_adapter_dev_release; adap->dev.class = &i2c_adapter_class; res =device_register (&adap->dev); -if (res) - goto out_list; +if (res) { +mutex_lock (&idr_adapter_lock); +idr_remove (&i2c_adapter_idr, adap->nr); +mutex_unlock (&idr_adapter_lock); + +return res; + }dev_dbg (&adap->dev,"adapter [%s] registered\n" , adap->name);
@@ -476,13 +480,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap) dummy =bus_for_each_drv (&i2c_bus_type,NULL , adap, i2c_do_add_adapter); -out_unlock: -mutex_unlock (&core_lock); -return res; - -out_list: -idr_remove (&i2c_adapter_idr, adap->nr); - goto out_unlock; +return 0 ; }/**
@@ -506,11 +504,11 @@ retry:if (idr_pre_get (&i2c_adapter_idr,GFP_KERNEL ) ==0 )return -ENOMEM ; -mutex_lock (&core_lock); +mutex_lock (&idr_adapter_lock);/* "above" here means "above or equal to", sigh */ res =idr_get_new_above (&i2c_adapter_idr, adapter, __i2c_first_dynamic_bus_num, &id); -mutex_unlock (&core_lock); +mutex_unlock (&idr_adapter_lock);if (res <0 ) {if (res == -EAGAIN )
@@ -555,7 +553,7 @@ retry:if (idr_pre_get (&i2c_adapter_idr,GFP_KERNEL ) ==0 )return -ENOMEM ; -mutex_lock (&core_lock); +mutex_lock (&idr_adapter_lock);/* "above" here means "above or equal to", sigh; * we need the "equal to" result to force the result */
@@ -564,7 +562,7 @@ retry: status = -EBUSY ;idr_remove (&i2c_adapter_idr, id); } -mutex_unlock (&core_lock); +mutex_unlock (&idr_adapter_lock);if (status == -EAGAIN ) goto retry;
@@ -612,19 +610,25 @@ static int i2c_do_del_adapter(struct device_driver *d, void *data)*/ int i2c_del_adapter (struct i2c_adapter *adap) { +struct i2c_adapter *ptr;struct i2c_client *client, *_n; -int res =0 , dummy; +int dummy; -mutex_lock (&core_lock); +mutex_lock (&idr_adapter_lock);/* First make sure that this adapter was ever added */ -if (idr_find (&i2c_adapter_idr, adap->nr) != adap) { + ptr =idr_find (&i2c_adapter_idr, adap->nr); +if (ptr != adap) {pr_debug ("i2c-core: attempting to delete unregistered " "adapter [%s]\n" , adap->name); - res = -EINVAL ; - goto out_unlock; +mutex_unlock (&idr_adapter_lock); +return -EINVAL ; } +/* ... then remove adapter ID */ +idr_remove (&i2c_adapter_idr, adap->nr); +mutex_unlock (&idr_adapter_lock); +/* Tell drivers about this removal */ dummy =bus_for_each_drv (&i2c_bus_type,NULL , adap, i2c_do_del_adapter);
@@ -655,18 +659,13 @@ int i2c_del_adapter(struct i2c_adapter *adap)/* wait for sysfs to drop all references */ wait_for_completion (&adap->dev_released); -/* free bus id */ -idr_remove (&i2c_adapter_idr, adap->nr); -dev_dbg (&adap->dev,"adapter [%s] unregistered\n" , adap->name);/* Clear the device structure in case this adapter is ever going to be added again */ memset (&adap->dev,0 ,sizeof (adap->dev)); - out_unlock: -mutex_unlock (&core_lock); -return res; +return 0 ; }EXPORT_SYMBOL (i2c_del_adapter);
@@ -1497,12 +1496,12 @@ struct i2c_adapter* i2c_get_adapter(int id) {struct i2c_adapter *adapter; -mutex_lock (&core_lock); +mutex_lock (&idr_adapter_lock); adapter = (struct i2c_adapter *)idr_find (&i2c_adapter_idr, id);if (adapter && !try_module_get (adapter->owner)) adapter =NULL ; -mutex_unlock (&core_lock); +mutex_unlock (&idr_adapter_lock);return adapter; }EXPORT_SYMBOL (i2c_get_adapter);
Signature · 1 line
1.5.6.3
A message that is not in the archive (sent off-list or not yet received): 1233840973-13268-5-git-send-email-giometti-k2GhghHVRtY@public.gmane.org
PATCH 5/6 i2c: Multiplexed I2C bus core support.
Add to the I2C core the ability to handle multiplexed I2C bus topologies by presenting each multiplexed segment as a I2C adapter.
--- drivers/i2c/Kconfig | 10 +++ drivers/i2c/Makefile | 3 +- drivers/i2c/i2c-mux.c | 180 ++++++++++++++++++++++++++++++++++++++++++++ drivers/i2c/muxes/Kconfig | 8 ++ drivers/i2c/muxes/Makefile | 6 ++ include/linux/i2c-id.h | 3 + include/linux/i2c.h | 14 ++++ 7 files changed, 223 insertions(+), 1 deletions(-) create mode 100644 drivers/i2c/i2c-mux.c create mode 100644 drivers/i2c/muxes/Kconfig create mode 100644 drivers/i2c/muxes/Makefile
drivers/i2c/Kconfig +10 -0
@@ -27,6 +27,16 @@ config I2C_BOARDINFO boolean default y +config I2C_MUX + tristate "I2C bus multiplexing support" + depends on I2C + help + Say Y here if you want the I2C core to support the ability to + handle multiplexed I2C bus topologies, by presenting each + multiplexed segment as a I2C adapter. + +source drivers/i2c/muxes/Kconfig + config I2C_CHARDEV tristate "I2C device interface" help
drivers/i2c/Makefile +2 -1
@@ -4,8 +4,9 @@ obj-$(CONFIG_I2C_BOARDINFO) += i2c-boardinfo.o obj-$(CONFIG_I2C) += i2c-core.o +obj-$(CONFIG_I2C_MUX) += i2c-mux.o obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o -obj-y += busses/ chips/ algos/ +obj-y += busses/ chips/ muxes/ algos/ ifeq ($(CONFIG_I2C_DEBUG_CORE),y) EXTRA_CFLAGS += -DDEBUG
drivers/i2c/i2c-mux.c new file +180 -0
180 lines not on this page · raw message
drivers/i2c/muxes/Kconfig new file +8 -0
@@ -0,0 +1,8 @@ +# +# Multiplexer I2C chip drivers configuration +# + +menu "Multiplexer I2C Chip support" + depends on I2C && I2C_MUX && EXPERIMENTAL + +endmenu
drivers/i2c/muxes/Makefile new file +6 -0
@@ -0,0 +1,6 @@ +# +# Makefile for multiplexer I2C chip drivers. + +ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) +EXTRA_CFLAGS += -DDEBUG +endif
include/linux/i2c-id.h +3 -0
@@ -162,4 +162,7 @@#define I2C_HW_SAA7146 0x060000/* SAA7146 video decoder bus */ #define I2C_HW_SAA7134 0x090000/* SAA7134 video decoder bus */ +/* --- Virtual adapter mark */ +#define I2C_HW_VIRT 0x80000000 +#endif /* LINUX_I2C_ID_H */
include/linux/i2c.h +14 -0
@@ -588,6 +588,20 @@ union i2c_smbus_data {#define I2C_SMBUS_BLOCK_PROC_CALL 7/* SMBus 2.0 */ #define I2C_SMBUS_I2C_BLOCK_DATA 8 +/* +* Called to create a 'virtual' i2c bus which represents a multiplexed bus +* segment. The client and mux_val are passed to the select and deselect +* callback functions to perform hardware-specific mux control. +*/ +struct i2c_adapter *i2c_add_mux_adapter (struct i2c_adapter *parent, +void *client,u32 force_nr,u32 mux_val, +int (*select_cb) (struct i2c_adapter *, +void *,u32 ), +int (*deselect_cb) (struct i2c_adapter *, +void *,u32 )); + +int i2c_del_mux_adapter (struct i2c_adapter *adap); +#ifdef __KERNEL__
Signature · 1 line
1.5.6.3
A message that is not in the archive (sent off-list or not yet received): 1233840973-13268-6-git-send-email-giometti-k2GhghHVRtY@public.gmane.org
PATCH 6/6 i2c: driver for PCA954x I2C multiplexer series.
--- drivers/i2c/muxes/Kconfig | 9 ++ drivers/i2c/muxes/Makefile | 2 + drivers/i2c/muxes/pca954x.c | 325 +++++++++++++++++++++++++++++++++++++++++++ include/linux/i2c/pca954x.h | 13 ++ 4 files changed, 349 insertions(+), 0 deletions(-) create mode 100644 drivers/i2c/muxes/pca954x.c create mode 100644 include/linux/i2c/pca954x.h
drivers/i2c/muxes/Kconfig +9 -0
@@ -5,4 +5,13 @@ menu "Multiplexer I2C Chip support" depends on I2C && I2C_MUX && EXPERIMENTAL +config I2CMUX_PCA954x + tristate "Philips PCA953x I2C Mux/switches" + help + If you say yes here you get support for the Philips PCA954x + I2C mux/switch devices. + + This driver can also be built as a module. If so, the module + will be called pca954x. + endmenu
drivers/i2c/muxes/Makefile +2 -0
@@ -1,6 +1,8 @@ # # Makefile for multiplexer I2C chip drivers. +obj-$(CONFIG_I2CMUX_PCA954x) += pca954x.o + ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) EXTRA_CFLAGS += -DDEBUG endif
drivers/i2c/muxes/pca954x.c new file +325 -0
325 lines not on this page · raw message
include/linux/i2c/pca954x.h new file +13 -0
@@ -0,0 +1,13 @@ +/* Platform data for the PCA954x I2C multiplexers */ + +struct pca954x_platform_mode { +int adap_id; +unsigned int deselect_on_exit:1 ; +int (*is_chan_connected)(struct i2c_adapter *adap, +struct i2c_client *client,u32 chan); +}; + +struct pca954x_platform_data { +struct pca954x_platform_mode *modes; +int num_modes; +};
Signature · 1 line
1.5.6.3
Re: [PATCH 3/6] i2c: ignore active clients detaching during adapter removal.
In reply to a message not in the archiveQuoted 10 lines · Rodolfo Giometti
When we are removing an adapter we decide to ignore any active client detaching faults for two reasons:
1) one (or more) active client may be switched off, so it cannot replay to the "adapter removed" event.
2) it shouldn't happen, and even if it happens it may be due a bus fault which can be resolved by resetting the adapter (most of them can be resetted simply by rmmod and then insmod the module again).
This bothers me. If the client can't detach, it can't; there may be all kinds of chaos introduced by trying to fake success in such cases. Like resources that suddenly just vanish, leaving breakage in their wake.
If this is a shutdown() path, where it's basically just a polite driver notification, that's one thing.
But I2C gets used as a system control bus, so this sort of "ignore the errors" stuff worries me a lot.
- Dave
A message that is not in the archive (sent off-list or not yet received): 200902051602.44036.david-b-yBeKhBN/[email protected]
Re: [PATCH 3/6] i2c: ignore active clients detaching during adapter removal.
Quoted 17 lines · David Brownell
Quoted 10 lines · Rodolfo Giometti
When we are removing an adapter we decide to ignore any active client detaching faults for two reasons:
1) one (or more) active client may be switched off, so it cannot replay to the "adapter removed" event.
2) it shouldn't happen, and even if it happens it may be due a bus fault which can be resolved by resetting the adapter (most of them can be resetted simply by rmmod and then insmod the module again).
This bothers me. If the client can't detach, it can't; there may be all kinds of chaos introduced by trying to fake success in such cases. Like resources that suddenly just vanish, leaving breakage in their wake.
Quoted 5 lines
If this is a
shutdown()path, where it's basically just a polite driver notification, that's one thing.But I2C gets used as a system control bus, so this sort of "ignore the errors" stuff worries me a lot.
If so I suppose we should take in account the adapter->client_unregister() return value also, which is currently ignored in i2c_unregister_device() function...
However, since I2c is a bus it could be possible that a slave device stops functioning (or the user decides to turn it off), so aborting the adapter removal in these cases can be not right... moreover if the adapter should be logically separated from the i2c clients I suppose is better allowing the user to remove (and eventually replace) it and then resolving i2c client's stale states into the relative driver.
I suppose this is the same behaviour of USB bus: we can remove an USB host adapter independently from USB devices.
Ciao,
Rodolfo
Signature · 4 lines
gnu/Linux Solutions e-mail: giometti-AVVDYK/kqiJWk0Htik3J/[email protected] Linux Device Driver [email protected] Embedded Systems phone: +39 349 2432127 UNIX programming skype: rodolfo.giometti
A message that is not in the archive (sent off-list or not yet received): 20090206102220.GF28554-AVVDYK/kqiJWk0Htik3J/[email protected]
Re: [PATCH 3/6] i2c: ignore active clients detaching during adapter removal.
Quoted 21 lines · Rodolfo Giometti
Quoted 20 lines · David Brownell
Quoted 10 lines · Rodolfo Giometti
When we are removing an adapter we decide to ignore any active client detaching faults for two reasons:
1) one (or more) active client may be switched off, so it cannot replay to the "adapter removed" event.
2) it shouldn't happen, and even if it happens it may be due a bus fault which can be resolved by resetting the adapter (most of them can be resetted simply by rmmod and then insmod the module again).
This bothers me. If the client can't detach, it can't; there may be all kinds of chaos introduced by trying to fake success in such cases. Like resources that suddenly just vanish, leaving breakage in their wake.
If this is a
shutdown()path, where it's basically just a polite driver notification, that's one thing.
Quoted 6 lines
Quoted 2 lines
But I2C gets used as a system control bus, so this sort of "ignore the errors" stuff worries me a lot.
If so I suppose we should take in account the
adapter->client_unregister()return value also, which is currently ignored ini2c_unregister_device()function...
Taking the old, deprecated, notoriously broken i2c model as an example doesn't necessarily serve your cause ;)
Quoted 9 lines
However, since I2c is a bus it could be possible that a slave device stops functioning (or the user decides to turn it off), so aborting the adapter removal in these cases can be not right... moreover if the adapter should be logically separated from the i2c clients I suppose is better allowing the user to remove (and eventually replace) it and then resolving i2c client's stale states into the relative driver.
I suppose this is the same behaviour of USB bus: we can remove an USB host adapter independently from USB devices.
The big difference, I presume, is that USB is never a system bus. But even for USB, devices can't exist without the host. If you kill the host and resurrect it later, you also kill the devices and resurrect them later.
The debate about drivers failing device removal is an old one, not specific to i2c. My opinion is that .remove() should succeed as much as possible. It should really only fail if the problem is so serious that the system's state would otherwise become a problem (e.g. freeing memory which is still referenced.) This should be a rare case.
Signature · 1 line
Jean Delvare
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH 3/6] i2c: ignore active clients detaching during adapter removal.
Quoted 3 lines · Jean Delvare
Taking the old, deprecated, notoriously broken i2c model as an example doesn't necessarily serve your cause ;)
I see, but till this part is in we should consider it, shouldn't we? Eheheh :D
Quoted 4 lines
The big difference, I presume, is that USB is never a system bus. But even for USB, devices can't exist without the host. If you kill the host and resurrect it later, you also kill the devices and resurrect them later.
But this can be done with i2c devices too! Let's think about leds drivers with uses an i2c GPIOs expander, they can exist without any adapter, even if they are not functional of course. :)
Quoted 5 lines
The debate about drivers failing device removal is an old one, not specific to i2c. My opinion is that .remove() should succeed as much as possible. It should really only fail if the problem is so serious that the system's state would otherwise become a problem (e.g. freeing memory which is still referenced.) This should be a rare case.
I think that i2c clients devices should be really separated by adapter ones, that is we should be free to add and remove any adapter without considering the clients state. Then each clients device drivers should free each allocated resource they use and the adapters shouldn't know about it.
Doing like this will semply the code a lot and it allows i2c core to be more flexible.
Ciao,
Rodolfo
Signature · 4 lines
GNU/Linux Solutions e-mail: giometti-AVVDYK/kqiJWk0Htik3J/[email protected] Linux Device Driver [email protected] Embedded Systems phone: +39 349 2432127 UNIX programming skype: rodolfo.giometti
A message that is not in the archive (sent off-list or not yet received): 20090206125907.GA8581-AVVDYK/kqiJWk0Htik3J/[email protected]
Re: [PATCH 3/6] i2c: ignore active clients detaching during adapter removal.
Quoted 7 lines · Rodolfo Giometti
Quoted 3 lines · Jean Delvare
Taking the old, deprecated, notoriously broken i2c model as an example doesn't necessarily serve your cause ;)
I see, but till this part is in we should consider it, shouldn't we? Eheheh :D
No. As I've said before, ideally I wanted legacy binding style to die _before_ we add support for multiplexing. But if we don't want to wait, I still want legacy binding and multiplexing to be mutually exclusive.
Quoted 8 lines
Quoted 4 lines
The big difference, I presume, is that USB is never a system bus. But even for USB, devices can't exist without the host. If you kill the host and resurrect it later, you also kill the devices and resurrect them later.
But this can be done with i2c devices too! Let's think about leds drivers with uses an i2c GPIOs expander, they can exist without any adapter, even if they are not functional of course. :)
That not the question. We all agree that some i2c chip drivers don't need to be able to prevent the removal of the underlying bus driver. The open point is whether some i2c chip drivers do. Honestly, I don't know, as such cases would happen on embedded systems, which are out of my realm. But maybe David has examples in mind.
Quoted 11 lines
Quoted 5 lines
The debate about drivers failing device removal is an old one, not specific to i2c. My opinion is that .remove() should succeed as much as possible. It should really only fail if the problem is so serious that the system's state would otherwise become a problem (e.g. freeing memory which is still referenced.) This should be a rare case.
I think that i2c clients devices should be really separated by adapter ones, that is we should be free to add and remove any adapter without considering the clients state. Then each clients device drivers should free each allocated resource they use and the adapters shouldn't know about it.
How does your description differ from the current implementation? I don't follow you.
Quoted 2 lines
Doing like this will semply the code a lot and it allows i2c core to be more flexible.
Patches welcome... but I have no clue what you want to do at this point.
Signature · 1 line
Jean Delvare
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH 3/6] i2c: ignore active clients detaching during adapter removal.
Quoted 4 lines · Jean Delvare
No. As I've said before, ideally I wanted legacy binding style to die _before_ we add support for multiplexing. But if we don't want to wait, I still want legacy binding and multiplexing to be mutually exclusive.
Ok.
Quoted 9 lines
Quoted 8 lines
Quoted 4 lines
The big difference, I presume, is that USB is never a system bus. But even for USB, devices can't exist without the host. If you kill the host and resurrect it later, you also kill the devices and resurrect them later.
But this can be done with i2c devices too! Let's think about leds drivers with uses an i2c GPIOs expander, they can exist without any adapter, even if they are not functional of course. :)
Quoted 5 lines
That not the question. We all agree that some i2c chip drivers don't need to be able to prevent the removal of the underlying bus driver. The open point is whether some i2c chip drivers do. Honestly, I don't know, as such cases would happen on embedded systems, which are out of my realm. But maybe David has examples in mind.
I see. But in this case we should dig into the code and verify what each i2c drivers wish to do during driver removal and eventually fix it, is that right?
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines
The debate about drivers failing device removal is an old one, not specific to i2c. My opinion is that .remove() should succeed as much as possible. It should really only fail if the problem is so serious that the system's state would otherwise become a problem (e.g. freeing memory which is still referenced.) This should be a rare case.
Quoted 8 lines
Quoted 5 lines
I think that i2c clients devices should be really separated by adapter ones, that is we should be free to add and remove any adapter without considering the clients state. Then each clients device drivers should free each allocated resource they use and the adapters shouldn't know about it.
How does your description differ from the current implementation? I don't follow you.
Currently an i2c driver may block adpater removal procedure, my implementation, instead, considers i2c adapter completely separated from i2c clients so that no one can't interfere with adapter insertion/removal code.
Quoted 4 lines
Quoted 2 lines
Doing like this will semply the code a lot and it allows i2c core to be more flexible.
Patches welcome... but I have no clue what you want to do at this point.
If you agree I can provide a branch tree from current vanilla and describe my solution into linux-i2c wiki, so users may test it and propose enhancements without touching current stable code.
Ciao,
Rodolfo
Signature · 4 lines
GNU/Linux Solutions e-mail: giometti-AVVDYK/kqiJWk0Htik3J/[email protected] Linux Device Driver [email protected] Embedded Systems phone: +39 349 2432127 UNIX programming skype: rodolfo.giometti
A message that is not in the archive (sent off-list or not yet received): 20090209130642.GV7975-AVVDYK/kqiJWk0Htik3J/[email protected]
Re: [PATCH 3/6] i2c: ignore active clients detaching during adapter removal.
Quoted 10 lines · Rodolfo Giometti
Quoted 5 lines · Jean Delvare
That not the question. We all agree that some i2c chip drivers don't need to be able to prevent the removal of the underlying bus driver. The open point is whether some i2c chip drivers do. Honestly, I don't know, as such cases would happen on embedded systems, which are out of my realm. But maybe David has examples in mind.
I see. But in this case we should dig into the code and verify what each i2c drivers wish to do during driver removal and eventually fix it, is that right?
I simply don't know. As I have written above, I do not have any example of an I2C device which should be allowed to prevent bus removal. But I am a PC person and the i2c subsystem is used in a very different way on embedded systems. So better discuss this with people who know these systems.
Quoted 8 lines
Quoted 3 lines
(...)
How does your description differ from the current implementation? I don't follow you.Currently an i2c driver may block adpater removal procedure, my implementation, instead, considers i2c adapter completely separated from i2c clients so that no one can't interfere with adapter insertion/removal code.
As far as I can see this only happens for legacy i2c chip drivers, which implement driver->detach_client() or driver->detach_adapter(). The plan is to get rid of the last few users of this model as soon as possible, so that's not really relevant.
Do you see any other place in i2c-core where we check for error on device removal and do something based on that, in particular for new-style i2c chip drivers?
Quoted 5 lines
Quoted 1 line
Patches welcome... but I have no clue what you want to do at this point.
If you agree I can provide a branch tree from current vanilla and describe my solution into linux-i2c wiki, so users may test it and propose enhancements without touching current stable code.
Well, you can always do that if you want, but please first clearly define the practical problem you are trying to solve. We are not going to change the i2c core without a good reason.
Oh, and if you have time to spend on i2c, then helping getting rid of the remaining legacy drivers would be greatly appreciated. As long as we have to support both models, there are many core cleanups and improvements that are simply not possible (or so risky that nobody wants to try.)
Signature · 1 line
Jean Delvare
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH 3/6] i2c: ignore active clients detaching during adapter removal.
Quoted 9 lines · Jean Delvare
Quoted 4 lines · Rodolfo Giometti
If you agree I can provide a branch tree from current vanilla and describe my solution into linux-i2c wiki, so users may test it and propose enhancements without touching current stable code.
Well, you can always do that if you want, but please first clearly define the practical problem you are trying to solve. We are not going to change the i2c core without a good reason.
I created a new page here:
http://i2c.wiki.kernel.org/index.php/I2C_bus_multiplexing
Please, take a look and report everything should be fixed. :)
Hope I did exactly what you requested...
Ciao,
Rodolfo
Signature · 4 lines
GNU/Linux Solutions e-mail: giometti-AVVDYK/kqiJWk0Htik3J/[email protected] Linux Device Driver [email protected] Embedded Systems phone: +39 349 2432127 UNIX programming skype: rodolfo.giometti
A message that is not in the archive (sent off-list or not yet received): 20090218164812.GA11217-AVVDYK/kqiJWk0Htik3J/[email protected]
Re: [PATCH 3/6] i2c: ignore active clients detaching during adapter removal.
Hi Rodolfo,
Sorry for the late answer, I missed this post in the middle of the thread.
Quoted 8 lines · Rodolfo Giometti
Quoted 3 lines · Jean Delvare
Well, you can always do that if you want, but please first clearly define the practical problem you are trying to solve. We are not going to change the i2c core without a good reason.
I created a new page here:
Thanks for doing this!
Quoted 1 line
Please, take a look and report everything should be fixed. :)
Random comments:
* I really would like to get rid of the "virtual" term that has been repeatedly abused. Bus segments behind multiplexers are very real.
* I am surprised that you use the term "trunk" for all segments, be they in front of or behind multiplexers. When I think of a multiplexer, I designate the segment between the controller and the multiplexer as the trunk, and the segments behind the multiplexer as branches.
Other than that I am rather happy with your page, which explains the problem and the proposed solution clearly.
Signature · 1 line
Jean Delvare
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH 3/6] i2c: ignore active clients detaching during adapter removal.
Quoted 4 lines · Jean Delvare
Hi Rodolfo,
Sorry for the late answer, I missed this post in the middle of the thread.
Don't worry about it! :)
Quoted 10 lines · Rodolfo Giometti
Quoted 8 lines · Jean Delvare
Quoted 3 lines
Well, you can always do that if you want, but please first clearly define the practical problem you are trying to solve. We are not going to change the i2c core without a good reason.
I created a new page here:
Quoted 8 lines
Thanks for doing this!
Quoted 1 line
Please, take a look and report everything should be fixed. :)
Random comments:
* I really would like to get rid of the "virtual" term that has been repeatedly abused. Bus segments behind multiplexers are very real.
Actually I use the term "virtual" regarding to the adapters not to the bus segments. In fact the new devices created are not "real" adapters but "virtual" ones.
Quoted 5 lines
* I am surprised that you use the term "trunk" for all segments, be they in front of or behind multiplexers. When I think of a multiplexer, I designate the segment between the controller and the multiplexer as the trunk, and the segments behind the multiplexer as branches.
Ok, this can be corrected easily. :)
Quoted 2 lines
Other than that I am rather happy with your page, which explains the problem and the proposed solution clearly.
Thanks a lot!
Ciao,
Rodolfo
Signature · 4 lines
GNU/Linux Solutions e-mail: giometti-AVVDYK/kqiJWk0Htik3J/[email protected] Linux Device Driver [email protected] Embedded Systems phone: +39 349 2432127 UNIX programming skype: rodolfo.giometti
A message that is not in the archive (sent off-list or not yet received): 20090528075835.GH20243-AVVDYK/kqiJWk0Htik3J/[email protected]
Re: [PATCH 3/6] i2c: ignore active clients detaching during adapter removal.
Quoted 7 lines · Rodolfo Giometti
Quoted 2 lines · Jean Delvare
* I really would like to get rid of the "virtual" term that has been repeatedly abused. Bus segments behind multiplexers are very real.
Actually I use the term "virtual" regarding to the adapters not to the bus segments. In fact the new devices created are not "real" adapters but "virtual" ones.
The confusion comes from the fact that struct i2c_adapter should have been named struct i2c_segment, as this is what it really represents. But back when it was decided, multiplexing wasn't considered so the developers thought "controller", "adapter" and "segment" were the same thing.
Ideally we should rename i2c_adapter to i2c_segment, but this seems a little intrusive for a rather thin benefit.
Signature · 1 line
Jean Delvare
Re: [PATCH 3/6] i2c: ignore active clients detaching during adapter removal.
In reply to a message not in the archiveQuoted 21 lines · Jean Delvare
Hi Rodolfo,
Sorry for the late answer, I missed this post in the middle of the thread.
Quoted 8 lines · Rodolfo Giometti
Quoted 3 lines · Jean Delvare
Well, you can always do that if you want, but please first clearly define the practical problem you are trying to solve. We are not going to change the i2c core without a good reason.
I created a new page here:
Thanks for doing this!
Quoted 1 line
Please, take a look and report everything should be fixed. :)
Random comments:
Quoted 8 lines
* I really would like to get rid of the "virtual" term that has been repeatedly abused. Bus segments behind multiplexers are very real.
* I am surprised that you use the term "trunk" for all segments, be they in front of or behind multiplexers. When I think of a multiplexer, I designate the segment between the controller and the multiplexer as the trunk, and the segments behind the multiplexer as branches.
Both fixed. Please review the page again. :)
Ciao,
Rodolfo
Signature · 4 lines
GNU/Linux Solutions e-mail: giometti-AVVDYK/kqiJWk0Htik3J/[email protected] Linux Device Driver [email protected] Embedded Systems phone: +39 349 2432127 UNIX programming skype: rodolfo.giometti
A message that is not in the archive (sent off-list or not yet received): 20090529072835.GA4575-AVVDYK/kqiJWk0Htik3J/[email protected]
Re: [PATCH 3/6] i2c: ignore active clients detaching during adapter removal.
Quoted 6 lines · Rodolfo Giometti
Quoted 5 lines · Jean Delvare
Random comments:
* I really would like to get rid of the "virtual" term that has been repeatedly abused. Bus segments behind multiplexers are very real.
Quoted 7 lines
Quoted 5 lines
* I am surprised that you use the term "trunk" for all segments, be they in front of or behind multiplexers. When I think of a multiplexer, I designate the segment between the controller and the multiplexer as the trunk, and the segments behind the multiplexer as branches.
Both fixed. Please review the page again. :)
Looks good, thanks!
Signature · 1 line
Jean Delvare
Re: [PATCH 2/6] i2c: use rwsem instead of mutex.
In reply to a message not in the archiveHi Rodolfo,
Quoted 68 lines · Rodolfo Giometti
By using rwsem we can easily manage recursive calls of
i2c_scan_static_board_info()function without breaking the locking.Signed-off-by Rodolfo Giometti <[email protected]>--- drivers/i2c/i2c-boardinfo.c | 6 +++--- drivers/i2c/i2c-core.c | 4 ++-- drivers/i2c/i2c-core.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-)drivers/i2c/i2c-boardinfo.c +3
-3@@ -25,7 +25,7 @@/* These symbols are exported ONLY FOR the i2c core. * No other users will be supported. */ -DEFINE_MUTEX (__i2c_board_lock); +DECLARE_RWSEM (__i2c_board_lock);EXPORT_SYMBOL_GPL (__i2c_board_lock);LIST_HEAD (__i2c_board_list);@@ -63,7 +63,7 @@ i2c_register_board_info(int busnum, {int status; -mutex_lock (&__i2c_board_lock); +down_write (&__i2c_board_lock);/* dynamic bus numbers will be assigned after the last static one */ if (busnum >= __i2c_first_dynamic_bus_num)@@ -84,7 +84,7 @@ i2c_register_board_info(int busnum,list_add_tail (&devinfo->list, &__i2c_board_list); } -mutex_unlock (&__i2c_board_lock); +up_write (&__i2c_board_lock);return status; }drivers/i2c/i2c-core.c +2
-2@@ -408,7 +408,7 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter) { struct i2c_devinfo *devinfo; - mutex_lock(&__i2c_board_lock); + down_read(&__i2c_board_lock); list_for_each_entry(devinfo, &__i2c_board_list, list) { if (devinfo->busnum == adapter->nr && !i2c_new_device(adapter,@@ -417,7 +417,7 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter)i2c_adapter_id (adapter), devinfo->board_info.addr); } -mutex_unlock (&__i2c_board_lock); +up_read (&__i2c_board_lock); }static int i2c_do_add_adapter (struct device_driver *d,void *data)drivers/i2c/i2c-core.h +0
-0
drivers/i2c/i2c-core.h struct i2c_devinfo { · line 31
Quoted 8 lines
drivers/i2c/i2c-core.h +1
-1@@ -25,7 +25,7 @@ struct i2c_devinfo {/* board_lock protects board_list and first_dynamic_bus_num. * only i2c core components are allowed to use these symbols. */ -extern struct mutex __i2c_board_lock; +extern struct rw_semaphore __i2c_board_lock;extern struct list_head __i2c_board_list;extern int __i2c_first_dynamic_bus_num;
Patch applied, thank you. I've add missing includes of <linux/rwsem.h> in all 3 files.
Signature · 1 line
Jean Delvare
Quoted 4 lines
This patch set adds to the I2C core the ability to handle multiplexed I2C bus topologies by presenting each multiplexed segment as a I2C adapter.
Hi Rodolfo,
Thanks for this patch. I learned about this patch through linux-media mailing list.
1)I have a sensor board header that uses pca9543a i2c switch which is addressed by this patch. In my board, I have another i2c chip that share the same i2c address with the sensor. Currently I cannot have both these drivers co-exists due to this. Please let me know if this can work once I use this patch.
2)Which kernel version you use for this patch?
3) Where can I download your patch so that I can give it a shot. Is there any platform data I need to setup in my arch/ folder to use this patch?
4) When do you think this will be merged to mainline kernel?
Thanks
Murali
A message that is not in the archive (sent off-list or not yet received): [email protected]
Hi Murali,
Quoted 7 lines · Muralidharan Karicheri
Quoted 4 lines
This patch set adds to the I2C core the ability to handle multiplexed I2C bus topologies by presenting each multiplexed segment as a I2C adapter.
Hi Rodolfo,
Quoted 8 lines
Thanks for this patch. I learned about this patch through linux-media mailing list.
1)I have a sensor board header that uses pca9543a i2c switch which is addressed by this patch. In my board, I have another i2c chip that share the same i2c address with the sensor. Currently I cannot have both these drivers co-exists due to this. Please let me know if this can work once I use this patch.
Yes, this is the idea. With bus multiplexing support, we can finally handle bus topologies with multiple chips using the same I2C address.
Quoted 7 lines
2)Which kernel version you use for this patch?
3) Where can I download your patch so that I can give it a shot. Is there any platform data I need to setup in my
arch/folder to use this patch?4) When do you think this will be merged to mainline kernel?
I am reviewing the patches at the moment, after Michael sends an updated version addressing my comments, we should be ready to go. So we currently aim at merging i2c multiplexing support into kernel 2.6.35. At least a first version... more features can be added later.
Signature · 1 line
Jean Delvare