Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[linux-dvb] Re: Proposal for new frontend architecture



On Thursday 16 Sep 2004 12:26, Andrew de Quincey wrote:
> On Thursday 16 Sep 2004 12:00, Gerd Knorr wrote:
> > > > I've been implementing this suggestion. One reason I prefer having a
> > > > flag in the adapter (as opposed to i2c_add_adapter_noprobe()) is the
> > > > following situation:
> > > >
> > > > i2c_add_adapter_noprobe()
> > > > .... hardware communicates with EEPROM
> > > > .... in the meantime, another module is loaded which registers an
> > > > i2c_driver with the I2C_DF_NOTIFY flag set - this will attempt to
> > > > register this new driver with the the partially initialised adapter.
> > > > ....
> >
> > Yep, for that a flag probably works better.
> >
> > > However, I think I would prefer to be able to just say NOPROBE once and
> > > for all and only have to worry about things registering themselves when
> > > I specifically call i2c_adapter_probe_drivers().
> >
> > i2c_adapter_probe_drivers() probably should (a) clear the NOPROBE flags
> > and (b) refuse to probe (again) if NOPROBE is already cleared (maybe
> > even BUG() on that).  That way the probing is really just delayed to
> > solve initialization order problems, any modules loaded after the
> > i2c_adapter_probe_drivers() call will still be probed.
> >
> > If you don't want autoprobing you must never ever call
> > i2c_adapter_probe_drivers().  Do the probing exactly one when you'll
> > call i2c_adapter_probe_drivers() is silly and would introduce all kinds
> > of strange module load order bugs.  Don't even think about that.
> >
> > i2c_adapter_enable_probing() would probably a better name to make clear
> > what it actually does.
>
> Yeah - I was wondering about that.
>
> What I originally thought was that i2c_adapter_probe_drivers() should not
> re-enable probing. If you want to do that, you're perfectly free to mask
> off the I2C_AF_NOPROBE flag when you want to reenable it.
>
> But yeah - there is still the issue of someone calling it twice... and we
> can always stop things from attaching themselves later using the other
> mechanisms we've just added.

New patch with suggested changes.
--- linux-2.6.9-rc1/include/linux/i2c.h	2004-08-29 17:31:47.000000000 +0100
+++ linux-2.6.9-rc1.adqpatch/include/linux/i2c.h	2004-09-16 12:37:42.341385984 +0100
@@ -230,6 +230,12 @@
 	unsigned int class;
 	struct i2c_algorithm *algo;/* the algorithm to access the bus	*/
 	void *algo_data;
+	unsigned int flags;
+
+	/* a ioctl like command that can be used to perform specific functions
+	 * with the adapter.
+	 */
+	int (*command)(struct i2c_client *client,unsigned int cmd, void *arg);
 
 	/* --- administration stuff. */
 	int (*client_register)(struct i2c_client *);
@@ -295,6 +301,9 @@
 #define I2C_CLASS_SOUND		(1<<6)	/* sound devices */
 #define I2C_CLASS_ALL		(UINT_MAX) /* all of the above */
 
+/*flags for the adapter struct: */
+#define I2C_AF_NOPROBE   0x01			/* do not auto-probe devices on i2c bus */
+
 /* i2c_client_address_data is the struct for holding default client
  * addresses for a driver and for the parameters supplied on the
  * command line
@@ -327,6 +336,7 @@
  */
 extern int i2c_add_adapter(struct i2c_adapter *);
 extern int i2c_del_adapter(struct i2c_adapter *);
+extern int i2c_adapter_enable_probing(struct i2c_adapter*);
 
 extern int i2c_add_driver(struct i2c_driver *);
 extern int i2c_del_driver(struct i2c_driver *);
--- linux-2.6.9-rc1/drivers/i2c/i2c-core.c	2004-08-29 17:31:47.000000000 +0100
+++ linux-2.6.9-rc1.adqpatch/drivers/i2c/i2c-core.c	2004-09-16 12:40:05.283655456 +0100
@@ -159,18 +159,45 @@
 	class_device_register(&adap->class_dev);
 
 	/* inform drivers of new adapters */
+	if (!(adap->flags & I2C_AF_NOPROBE)) {
+		list_for_each(item,&drivers) {
+			driver = list_entry(item, struct i2c_driver, list);
+			if (driver->flags & I2C_DF_NOTIFY)
+				/* We ignore the return code; if it fails, too bad */
+				driver->attach_adapter(adap);
+		}
+	}
+
+	dev_dbg(&adap->dev, "registered as adapter #%d\n", adap->nr);
+
+out_unlock:
+	up(&core_lists);
+	return res;
+}
+
+
+int i2c_adapter_enable_probing(struct i2c_adapter* adap)
+{
+	struct list_head   *item;
+	struct i2c_driver  *driver;
+
+	down(&core_lists);
+
+	/* it is a bug to try to enable probing twice! */
+	if (!(adap->flags & I2C_AF_NOPROBE)) {
+		BUG();
+	}
+   
 	list_for_each(item,&drivers) {
 		driver = list_entry(item, struct i2c_driver, list);
 		if (driver->flags & I2C_DF_NOTIFY)
 			/* We ignore the return code; if it fails, too bad */
 			driver->attach_adapter(adap);
 	}
+	adap->flags &= ~I2C_AF_NOPROBE;
 
-	dev_dbg(&adap->dev, "registered as adapter #%d\n", adap->nr);
-
-out_unlock:
 	up(&core_lists);
-	return res;
+   	return 0;
 }
 
 
@@ -266,7 +293,9 @@
 	if (driver->flags & I2C_DF_NOTIFY) {
 		list_for_each(item,&adapters) {
 			adapter = list_entry(item, struct i2c_adapter, list);
-			driver->attach_adapter(adapter);
+			if (!(adapter->flags & I2C_AF_NOPROBE)) {
+				driver->attach_adapter(adapter);
+			}
 		}
 	}
 
@@ -1284,6 +1313,7 @@
 EXPORT_SYMBOL(i2c_release_client);
 EXPORT_SYMBOL(i2c_clients_command);
 EXPORT_SYMBOL(i2c_check_addr);
+EXPORT_SYMBOL(i2c_adapter_enable_probing);
 
 EXPORT_SYMBOL(i2c_master_send);
 EXPORT_SYMBOL(i2c_master_recv);

Home | Main Index | Thread Index