public inbox for linux-i2c@vger.kernel.org
 help / color / mirror / Atom feed
From: Jean Delvare <khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org>
To: David Brownell <david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
Cc: i2c-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org
Subject: Re: i2c-remove-redundant-i2c_client-list.patch
Date: Tue, 8 Jan 2008 15:18:17 +0100	[thread overview]
Message-ID: <20080108151817.35e05c6c@hyperion.delvare> (raw)
In-Reply-To: <200801061130.31774.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>

Hi David,

On Sun, 6 Jan 2008 11:30:31 -0800, David Brownell wrote:
> On Sunday 06 January 2008, Jean Delvare wrote:
> > > +static struct i2c_client *verify_client(struct device *dev)
> > > +{
> > > +	if (dev->bus != &i2c_bus_type)
> > 
> > Is this paranoia, or can this test really succeed? I thought that all
> > children of an i2c adapter node would always be i2c clients.
> 
> Let's call it well-founded paranoia.  I know that when the SPI
> code got a "remove class_device" patch, I had to fix an oops
> caused by an unexpected child ... and at the top of my current
> GIT snapshot is 911833440b498e3e4fe2f12c1ae2bd44400c7004 which
> fixed similar oopsing in SCSI.

OK, fine with me.

> > > --- a/drivers/i2c/i2c-dev.c
> > > +++ b/drivers/i2c/i2c-dev.c
> > > 		...
> > > -	}
> > > -	mutex_unlock(&adapter->clist_lock);
> > > +	if (!dev->bus || strcmp("i2c", dev->bus->name) != 0)
> > 
> > Please just export i2c_bus_type is you need it, or even verify_client
> > (then renamed to i2c_verify_client)? If the bus type check is really
> > needed then we'll need it for the 3 v4l drivers I mentioned earlier
> > anyway.
> 
> Good point.  I didn't like this part much, and that function can
> have other uses.  I updated kobj_to_i2c_client() to use it too.

I wouldn't change kobj_to_i2c_client(). Drivers using it already know
that their kobj is an i2c_client, so there's no need to check for that,
and the use cases I've seen are in runtime paths that should be fast, I
don't want to slow them down without a good reason.

> > Alternatively we could write and export an i2c_for_each_client()
> > function doing all the required checks so that drivers don't have to
> > care. What do you think?
> 
> Less good.  We can't know in advance which things they care about.

device_for_each_child() doesn't know either, and lets the caller pass
an arbitrary pointer as a parameter to the callbask function. My idea
was to do something similar, so i2c_for_each_client() would essentially
be a wrapper for device_for_each_child().

Here's what I have:

---
 drivers/i2c/i2c-core.c        |   28 ++++++++++++++++++++++++++++
 drivers/i2c/i2c-dev.c         |   10 ++++------
 drivers/media/video/dpc7146.c |    8 ++------
 drivers/media/video/mxb.c     |    8 ++------
 drivers/media/video/tvmixer.c |    9 +++------
 include/linux/i2c.h           |    3 +++
 6 files changed, 42 insertions(+), 24 deletions(-)

--- linux-2.6.24-rc7.orig/drivers/i2c/i2c-core.c	2008-01-08 14:19:39.000000000 +0100
+++ linux-2.6.24-rc7/drivers/i2c/i2c-core.c	2008-01-08 15:09:38.000000000 +0100
@@ -215,6 +215,34 @@ struct i2c_client *i2c_verify_client(str
 }
 EXPORT_SYMBOL(i2c_verify_client);
 
+struct i2c_for_each_client_data {
+	void *data;
+	int (*fn)(struct i2c_client *, void *);
+};
+
+static int __i2c_for_each_client(struct device *dev, void *d)
+{
+	struct i2c_for_each_client_data *_data = d;
+	struct i2c_client *client = i2c_verify_client(dev);
+
+	if (!client)
+		return 0;
+
+	return _data->fn(client, _data->data);
+}
+
+int i2c_for_each_client(struct i2c_adapter *adapter, void *data,
+			int (*fn)(struct i2c_client *, void *))
+{
+	struct i2c_for_each_client_data _data;
+
+	_data.data = data;
+	_data.fn = fn;
+
+	return device_for_each_child(&adapter->dev, &_data,
+				     __i2c_for_each_client);
+}
+EXPORT_SYMBOL(i2c_for_each_client);
 
 /**
  * i2c_new_device - instantiate an i2c device for use with a new style driver
--- linux-2.6.24-rc7.orig/include/linux/i2c.h	2008-01-08 14:19:15.000000000 +0100
+++ linux-2.6.24-rc7/include/linux/i2c.h	2008-01-08 15:09:34.000000000 +0100
@@ -181,6 +181,9 @@ struct i2c_client {
 
 extern struct i2c_client *i2c_verify_client(struct device *dev);
 
+extern int i2c_for_each_client(struct i2c_adapter *adapter, void *data,
+			       int (*fn)(struct i2c_client *, void *));
+
 static inline struct i2c_client *kobj_to_i2c_client(struct kobject *kobj)
 {
 	return i2c_verify_client(container_of(kobj, struct device, kobj));
--- linux-2.6.24-rc7.orig/drivers/media/video/dpc7146.c	2008-01-08 14:37:41.000000000 +0100
+++ linux-2.6.24-rc7/drivers/media/video/dpc7146.c	2008-01-08 14:59:28.000000000 +0100
@@ -87,13 +87,9 @@ struct dpc
 	int cur_input;	/* current input */
 };
 
-static int dpc_check_clients(struct device *dev, void *data)
+static int dpc_check_clients(struct i2c_client *client, void *data)
 {
 	struct dpc* dpc = data;
-	struct i2c_client *client = i2c_verify_client(dev);
-
-	if( !client )
-		return 0;
 
 	if( I2C_SAA7111A == client->addr )
 		dpc->saa7111a = client;
@@ -128,7 +124,7 @@ static int dpc_probe(struct saa7146_dev*
 	}
 
 	/* loop through all i2c-devices on the bus and look who is there */
-	device_for_each_child(&dpc->i2c_adapter.dev, dpc, dpc_check_clients);
+	i2c_for_each_client(&dpc->i2c_adapter, dpc, dpc_check_clients);
 
 	/* check if all devices are present */
 	if( 0 == dpc->saa7111a ) {
--- linux-2.6.24-rc7.orig/drivers/media/video/mxb.c	2008-01-08 14:37:33.000000000 +0100
+++ linux-2.6.24-rc7/drivers/media/video/mxb.c	2008-01-08 15:00:12.000000000 +0100
@@ -149,13 +149,9 @@ struct mxb
 
 static struct saa7146_extension extension;
 
-static int mxb_check_clients(struct device *dev, void *data)
+static int mxb_check_clients(struct i2c_client *client, void *data)
 {
 	struct mxb* mxb = data;
-	struct i2c_client *client = i2c_verify_client(dev);
-
-	if( !client )
-		return 0;
 
 	if( I2C_ADDR_TEA6420_1 == client->addr )
 		mxb->tea6420_1 = client;
@@ -218,7 +214,7 @@ static int mxb_probe(struct saa7146_dev*
 	}
 
 	/* loop through all i2c-devices on the bus and look who is there */
-	device_for_each_child(&mxb->i2c_adapter.dev, mxb, mxb_check_clients);
+	i2c_for_each_client(&mxb->i2c_adapter, mxb, mxb_check_clients);
 
 	/* check if all devices are present */
 	if(    0 == mxb->tea6420_1	|| 0 == mxb->tea6420_2	|| 0 == mxb->tea6415c
--- linux-2.6.24-rc7.orig/drivers/media/video/tvmixer.c	2008-01-08 14:34:30.000000000 +0100
+++ linux-2.6.24-rc7/drivers/media/video/tvmixer.c	2008-01-08 15:01:27.000000000 +0100
@@ -235,18 +235,15 @@ static const struct file_operations tvmi
 
 /* ----------------------------------------------------------------------- */
 
-static int __tvmixer_adapters(struct device *dev, void *data)
+static int __tvmixer_adapters(struct i2c_client *client, void *data)
 {
-	struct i2c_client *client = i2c_verify_client(dev);
-
-	if (client)
-		tvmixer_clients(client);
+	tvmixer_clients(client);
 	return 0;
 }
 
 static int tvmixer_adapters(struct i2c_adapter *adap)
 {
-	device_for_each_child(&adap->dev, NULL, __tvmixer_adapters);
+	i2c_for_each_client(adap, NULL, __tvmixer_adapters);
 	return 0;
 }
 
--- linux-2.6.24-rc7.orig/drivers/i2c/i2c-dev.c	2008-01-08 14:19:15.000000000 +0100
+++ linux-2.6.24-rc7/drivers/i2c/i2c-dev.c	2008-01-08 15:05:25.000000000 +0100
@@ -182,14 +182,12 @@ static ssize_t i2cdev_write (struct file
 	return ret;
 }
 
-static int i2cdev_check(struct device *dev, void *addrp)
+static int i2cdev_check(struct i2c_client *client, void *addrp)
 {
-	struct i2c_client *client = i2c_verify_client(dev);
-
-	if (!client || client->addr != *(unsigned int *)addrp)
+	if (client->addr != *(unsigned int *)addrp)
 		return 0;
 
-	return dev->driver ? -EBUSY : 0;
+	return client->dev.driver ? -EBUSY : 0;
 }
 
 /* This address checking function differs from the one in i2c-core
@@ -197,7 +195,7 @@ static int i2cdev_check(struct device *d
    driver to it, as NOT busy. */
 static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr)
 {
-	return device_for_each_child(&adapter->dev, &addr, i2cdev_check);
+	return i2c_for_each_client(adapter, &addr, i2cdev_check);
 }
 
 static int i2cdev_ioctl(struct inode *inode, struct file *file,

Admittedly it will slow down things a bit as each iteration of the loop
will have one additional level of indirection. This makes the calling
code somewhat simpler though. Whether it is worth the additional
runtime cost, I just don't know. What do you think?

> Though I was a bit worried it might have bugs in it, since all I had
> time to do was code it, and sanity check it with a couple variants of
> one new-style config.  (I no longer have those monster "build all I2C
> drivers" configs around.)

I'll give it good testing, don't worry too much about that.

-- 
Jean Delvare

  parent reply	other threads:[~2008-01-08 14:18 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20071216052308.A0FB11668D7@adsl-69-226-248-13.dsl.pltn13.pacbell.net>
     [not found] ` <20071216052308.A0FB11668D7-ZcXrCSuhvln6VZ3dlLfH/g4gEjPzgfUyLrfjE7I9kuVHxeISYlDBzl6hYfS7NtTn@public.gmane.org>
2007-12-27 20:58   ` [patch 2.6.24-rc5-git] add i2c_new_dummy() utility Byron Bradley
     [not found]     ` <57e2b00712271258l6ea661ai2bfd6b9e099c71be-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2007-12-27 21:53       ` David Brownell
     [not found]         ` <200712271353.05857.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2007-12-27 22:09           ` Byron Bradley
     [not found]             ` <57e2b00712271409n6c98f76o45116cd92b01f396-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2007-12-27 23:06               ` David Brownell
     [not found]                 ` <200712271506.43069.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2007-12-27 23:37                   ` Byron Bradley
2007-12-27 23:59                   ` David Brownell
     [not found] ` <200712281230.17840.david-b@pacbell.net>
     [not found]   ` <57e2b00712281645y70f6ec74s57945dc53f113ec8@mail.gmail.com>
     [not found]     ` <57e2b00712281645y70f6ec74s57945dc53f113ec8-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2007-12-30  3:05       ` David Brownell
     [not found]         ` <200712291905.15160.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-01-04 22:16           ` Jean Delvare
     [not found]             ` <20080104231633.135f2875-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-01-04 23:48               ` David Brownell
     [not found]                 ` <200801041548.54825.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-01-06  9:57                   ` Jean Delvare
2008-01-06 11:23           ` i2c-remove-redundant-i2c_client-list.patch Jean Delvare
     [not found]             ` <20080106122356.78556b8a-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-01-06 19:30               ` i2c-remove-redundant-i2c_client-list.patch David Brownell
     [not found]                 ` <200801061130.31774.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-01-08 14:18                   ` Jean Delvare [this message]
     [not found]                     ` <20080108151817.35e05c6c-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-01-08 16:20                       ` i2c-remove-redundant-i2c_client-list.patch Jean Delvare
     [not found]                         ` <20080108172001.33de6afc-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-01-08 19:12                           ` i2c-remove-redundant-i2c_client-list.patch David Brownell
     [not found]                             ` <200801081112.46972.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-01-08 20:50                               ` i2c-remove-redundant-i2c_client-list.patch Jean Delvare
     [not found]                                 ` <20080108215042.534e32fa-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-01-08 21:44                                   ` i2c-remove-redundant-i2c_client-list.patch David Brownell
     [not found]                                     ` <200801081344.45544.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-01-08 22:04                                       ` i2c-remove-redundant-i2c_client-list.patch Greg KH
     [not found]                                         ` <20080108220445.GB3873-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>
2008-01-08 22:27                                           ` i2c-remove-redundant-i2c_client-list.patch David Brownell
2008-01-09 13:29                                       ` i2c-remove-redundant-i2c_client-list.patch Jean Delvare
     [not found]                                         ` <20080109142906.23a55f5f-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-01-09 16:19                                           ` i2c-remove-redundant-i2c_client-list.patch Jean Delvare
     [not found]                                             ` <20080109171934.4f894bdc-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-01-09 21:21                                               ` i2c-remove-redundant-i2c_client-list.patch David Brownell
     [not found]                                                 ` <200801091321.29212.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-01-10 13:31                                                   ` i2c-remove-redundant-i2c_client-list.patch Jean Delvare
     [not found]                                                     ` <20080110143105.456ddaf0-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-01-14 22:20                                                       ` i2c-remove-redundant-i2c_client-list.patch David Brownell
     [not found]                                                         ` <200801141420.49274.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-01-17 22:02                                                           ` i2c-remove-redundant-i2c_client-list.patch Jean Delvare
2008-01-18 10:14                                                           ` i2c-remove-redundant-i2c_client-list.patch Jean Delvare
     [not found]                                                             ` <20080118111401.7ffdccc5-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-01-18 10:30                                                               ` i2c-remove-redundant-i2c_client-list.patch David Brownell
2008-01-14 22:42                                                       ` i2c-remove-redundant-i2c_client-list.patch David Brownell
2008-01-17 19:35                                                   ` i2c-remove-redundant-i2c_client-list.patch David Brownell
     [not found]                                                     ` <200801171135.45797.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-01-17 19:59                                                       ` i2c-remove-redundant-i2c_client-list.patch David Brownell
     [not found]                                                         ` <200801171159.00291.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-01-18  9:32                                                           ` i2c-remove-redundant-i2c_client-list.patch Jean Delvare
     [not found]                                                             ` <20080118103209.4b92ac76-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-01-18 10:16                                                               ` i2c-remove-redundant-i2c_client-list.patch David Brownell
     [not found]                                                                 ` <200801180216.22363.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-01-18 12:10                                                                   ` i2c-remove-redundant-i2c_client-list.patch Jean Delvare
2008-01-08 18:52                       ` i2c-remove-redundant-i2c_client-list.patch David Brownell
     [not found]                         ` <200801081052.31413.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-01-08 19:57                           ` i2c-remove-redundant-i2c_client-list.patch Jean Delvare
2008-01-09 16:09                       ` i2c-remove-redundant-i2c_client-list.patch Jean Delvare
2008-01-06 19:43               ` i2c-remove-redundant-i2c_client-list.patch David Brownell
     [not found]                 ` <200801061143.34020.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-01-08 14:21                   ` i2c-remove-redundant-i2c_client-list.patch Jean Delvare
2008-01-17 22:24           ` [patch 2.6.24-rc5-git] add i2c_new_dummy() utility David Brownell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080108151817.35e05c6c@hyperion.delvare \
    --to=khali-puyad+kwke1g9huczpvpmw@public.gmane.org \
    --cc=david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org \
    --cc=i2c-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox