[i2c] i2c-remove-redundant-i2c_client-list.patch

Jean Delvare khali at linux-fr.org
Fri Jan 18 11:14:01 CET 2008


Hi David,

On Mon, 14 Jan 2008 14:20:48 -0800, David Brownell wrote:
> OK, here's the trimmed-down patch that leaves the deletion
> paths untouched until we have a better solution.  I've only
> build-tested it, but it's basically $SUBJECT without those
> troublesome paths.
> 
> - Dave
> 
> =======	CUT HERE
> The i2c_adapter.clients list of i2c_client nodes duplicates driver
> model state.  This patch starts removing that list, letting us remove
> most existing users of those i2c-core lists.
> 
>  * The core I2C code now iterates over the driver model's list instead
>    of the i2c-internal one in some places where it's safe:
>       - Passing a command/ioctl to each client, a mechanims
>         used almost exclusively by DVB adapters;
>       - Device address checking, in both i2c-core and i2c-dev.
> 
>  * Provide i2c_verify_client() to use with driver model iterators.
> 
>  * Flag the relevant i2c_adapter and i2c_client fields as deprecated,
>    to help prevent new users from appearing.
> 
> For the moment the list needs to stick around, since some issues show
> up when deleting devices created by legacy I2C drivers.  (They don't
> follow standard driver model rules.  Removing those devices can cause
> self-deadlocks.)
> 
> Signed-off-by: David Brownell <dbrownell at users.sourceforge.net>
> ---
>  drivers/i2c/i2c-core.c |   78 ++++++++++++++++++++++++++++---------------------
>  drivers/i2c/i2c-dev.c  |   29 +++++++-----------
>  include/linux/i2c.h    |    8 +++--
>  3 files changed, 63 insertions(+), 52 deletions(-)
> 
> --- at91.orig/drivers/i2c/i2c-core.c	2008-01-14 13:56:28.000000000 -0800
> +++ at91/drivers/i2c/i2c-core.c	2008-01-14 14:01:50.000000000 -0800
> (...)
> @@ -713,28 +732,19 @@ EXPORT_SYMBOL(i2c_del_driver);
>  
>  /* ------------------------------------------------------------------------- */
>  
> -static int __i2c_check_addr(struct i2c_adapter *adapter, unsigned int addr)
> +static int __i2c_check_addr(struct device *dev, void *addrp)
>  {
> -	struct list_head   *item;
> -	struct i2c_client  *client;
> +	struct i2c_client	*client = i2c_verify_client(dev);
> +	int			addr = *(int *)addrp;
>  
> -	list_for_each(item,&adapter->clients) {
> -		client = list_entry(item, struct i2c_client, list);
> -		if (client->addr == addr)
> -			return -EBUSY;
> -	}
> +	if (client && client->addr == addr)
> +		return -EBUSY;
>  	return 0;
>  }
>  
>  static int i2c_check_addr(struct i2c_adapter *adapter, int addr)
>  {
> -	int rval;
> -
> -	mutex_lock(&adapter->clist_lock);
> -	rval = __i2c_check_addr(adapter, addr);
> -	mutex_unlock(&adapter->clist_lock);
> -
> -	return rval;
> +	return device_for_each_child(&adapter->dev, &addr, __i2c_check_addr);
>  }
>  
>  int i2c_attach_client(struct i2c_client *client)

With this patch applied, any reason why i2c_new_probed_device() still
acquires adapter->clist_lock? My understanding is that it was there
because i2c_check_addr() was originally walking the internal client
list, but as this is no longer the case, the locking is no longer
needed, is it?

Thanks,
-- 
Jean Delvare



More information about the i2c mailing list