linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [patch] i2c #1/3: listify i2c core
@ 2003-05-06 19:34 Gerd Knorr
  2003-05-06 19:40 ` [patch] i2c #2/3: add i2c_clients_command Gerd Knorr
  2003-05-07  0:17 ` [patch] i2c #1/3: listify i2c core Greg KH
  0 siblings, 2 replies; 6+ messages in thread
From: Gerd Knorr @ 2003-05-06 19:34 UTC (permalink / raw)
  To: Linus Torvalds, Greg KH, Frank Davis, Kernel List, Ronald Bultje

  Hi,

This is the first of tree patches for i2c.  Trying to get the i2c
cleanups finshed before 2.6.x, so we (hopefully) don't have a
ever-changing i2c subsystem in 2.7.x again (which is very annonying for
driver maintainance).

Changes:

 * listify i2c-core, i.e. make it use <linux/list.h> instead of
   statically-sized arrays, removed lots of ugly code :)
 * added i2c_(get|put)_adapter, changed i2c-dev.c to use these
   functions instead maintaining is own adapter list.
 * killed the I2C_DF_DUMMY flag which had the strange semantics to
   make the i2c subsystem call driver->attach_adapter on detaches.
   Added a detach_adapter() callback instead.
 * some other minor cleanups along the way ...

Please apply,

  Gerd

diff -urN -X /home/kraxel/.kdontdiff linux-vanilla-2.5.69/drivers/i2c/i2c-core.c linux-i2c-1-2.5.69/drivers/i2c/i2c-core.c
--- linux-vanilla-2.5.69/drivers/i2c/i2c-core.c	2003-05-06 14:01:54.000000000 +0200
+++ linux-i2c-1-2.5.69/drivers/i2c/i2c-core.c	2003-05-06 13:42:07.000000000 +0200
@@ -38,8 +38,8 @@
 #define DEB(x) if (i2c_debug>=1) x;
 #define DEB2(x) if (i2c_debug>=2) x;
 
-static struct i2c_adapter *adapters[I2C_ADAP_MAX];
-static struct i2c_driver *drivers[I2C_DRIVER_MAX];
+static LIST_HEAD(adapters);
+static LIST_HEAD(drivers);
 static DECLARE_MUTEX(core_lists);
 
 /**** debug level */
@@ -75,23 +75,17 @@
  */
 int i2c_add_adapter(struct i2c_adapter *adap)
 {
-	int res = 0, i, j;
+	static int nr = 0;
+	struct list_head   *item;
+	struct i2c_driver  *driver;
 
 	down(&core_lists);
-	for (i = 0; i < I2C_ADAP_MAX; i++)
-		if (NULL == adapters[i])
-			break;
-	if (I2C_ADAP_MAX == i) {
-		dev_warn(&adap->dev,
-			"register_adapter - enlarge I2C_ADAP_MAX.\n");
-		res = -ENOMEM;
-		goto out_unlock;
-	}
 
-	adapters[i] = adap;
-
-	init_MUTEX(&adap->bus);
-	init_MUTEX(&adap->list);
+	adap->nr = nr++;
+	init_MUTEX(&adap->bus_lock);
+	init_MUTEX(&adap->clist_lock);
+	list_add_tail(&adap->list,&adapters);
+	INIT_LIST_HEAD(&adap->clients);
 
 	/* Add the adapter to the driver core.
 	 * If the parent pointer is not set up,
@@ -99,77 +93,65 @@
 	 */
 	if (adap->dev.parent == NULL)
 		adap->dev.parent = &legacy_bus;
-	sprintf(adap->dev.bus_id, "i2c-%d", i);
+	sprintf(adap->dev.bus_id, "i2c-%d", adap->nr);
 	adap->dev.driver = &i2c_generic_driver;
 	device_register(&adap->dev);
 
 	/* inform drivers of new adapters */
-	for (j=0;j<I2C_DRIVER_MAX;j++)
-		if (drivers[j]!=NULL && 
-		    (drivers[j]->flags&(I2C_DF_NOTIFY|I2C_DF_DUMMY)))
+	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 */
-			drivers[j]->attach_adapter(adap);
+			driver->attach_adapter(adap);
+	}
 	up(&core_lists);
-	
-	DEB(dev_dbg(&adap->dev, "registered as adapter %d.\n", i));
 
- out_unlock:
-	up(&core_lists);
-	return res;;
+	DEB(dev_dbg(&adap->dev, "registered as adapter #%d\n", adap->nr));
+	return 0;
 }
 
 
 int i2c_del_adapter(struct i2c_adapter *adap)
 {
-	int res = 0, i, j;
+	struct list_head  *item;
+	struct i2c_driver *driver;
+	struct i2c_client *client;
+	int res = 0;
 
 	down(&core_lists);
-	for (i = 0; i < I2C_ADAP_MAX; i++)
-		if (adap == adapters[i])
-			break;
-	if (I2C_ADAP_MAX == i) {
-		dev_warn(&adap->dev, "unregister_adapter adap not found.\n");
-		res = -ENODEV;
-		goto out_unlock;
-	}
 
-	/* DUMMY drivers do not register their clients, so we have to
-	 * use a trick here: we call driver->attach_adapter to
-	 * *detach* it! Of course, each dummy driver should know about
-	 * this or hell will break loose...
-	 */
-	for (j = 0; j < I2C_DRIVER_MAX; j++) 
-		if (drivers[j] && (drivers[j]->flags & I2C_DF_DUMMY))
-			if ((res = drivers[j]->attach_adapter(adap))) {
+	list_for_each(item,&drivers) {
+		driver = list_entry(item, struct i2c_driver, list);
+		if (driver->detach_adapter)
+			if ((res = driver->detach_adapter(adap))) {
 				dev_warn(&adap->dev, "can't detach adapter"
-				       "while detaching driver %s: driver not "
-				       "detached!", drivers[j]->name);
+					 "while detaching driver %s: driver not "
+					 "detached!", driver->name);
 				goto out_unlock;
 			}
+	}
 
 	/* detach any active clients. This must be done first, because
 	 * it can fail; in which case we give upp. */
-	for (j=0;j<I2C_CLIENT_MAX;j++) {
-		struct i2c_client *client = adap->clients[j];
-		if (client!=NULL) {
-		    /* detaching devices is unconditional of the set notify
-		     * flag, as _all_ clients that reside on the adapter
-		     * must be deleted, as this would cause invalid states.
-		     */
-			if ((res=client->driver->detach_client(client))) {
-				dev_err(&adap->dev, "adapter not "
-					"unregistered, because client at "
-					"address %02x can't be detached. ",
-					client->addr);
-				goto out_unlock;
-			}
+	list_for_each(item,&adap->clients) {
+		client = list_entry(item, struct i2c_client, list);
+
+		/* detaching devices is unconditional of the set notify
+		 * flag, as _all_ clients that reside on the adapter
+		 * must be deleted, as this would cause invalid states.
+		 */
+		if ((res=client->driver->detach_client(client))) {
+			dev_err(&adap->dev, "adapter not "
+				"unregistered, because client at "
+				"address %02x can't be detached. ",
+				client->addr);
+			goto out_unlock;
 		}
 	}
 
 	/* clean up the sysfs representation */
 	device_unregister(&adap->dev);
-
-	adapters[i] = NULL;
+	list_del(&adap->list);
 
 	DEB(dev_dbg(&adap->dev, "adapter unregistered\n"));
 
@@ -187,24 +169,11 @@
 
 int i2c_add_driver(struct i2c_driver *driver)
 {
-	int res = 0, i;
+	struct list_head   *item;
+	struct i2c_adapter *adapter;
+	int res = 0;
 
 	down(&core_lists);
-	for (i = 0; i < I2C_DRIVER_MAX; i++)
-		if (NULL == drivers[i])
-			break;
-	if (I2C_DRIVER_MAX == i) {
-		printk(KERN_WARNING 
-		       " i2c-core.o: register_driver(%s) "
-		       "- enlarge I2C_DRIVER_MAX.\n",
-			driver->name);
-		res = -ENOMEM;
-		goto out_unlock;
-	}
-
-	drivers[i] = driver;
-	
-	DEB(printk(KERN_DEBUG "i2c-core.o: driver %s registered.\n",driver->name));
 
 	/* add the driver to the list of i2c drivers in the driver core */
 	driver->driver.name = driver->name;
@@ -216,13 +185,14 @@
 	if (res)
 		goto out_unlock;
 	
-	/* now look for instances of driver on our adapters
-	 */
-	if (driver->flags& (I2C_DF_NOTIFY|I2C_DF_DUMMY)) {
-		for (i=0;i<I2C_ADAP_MAX;i++) {
-			if (adapters[i]!=NULL)
-				/* Ignore errors */
-				driver->attach_adapter(adapters[i]);
+	list_add_tail(&driver->list,&drivers);
+	DEB(printk(KERN_DEBUG "i2c-core.o: driver %s registered.\n",driver->name));
+
+	/* now look for instances of driver on our adapters */
+	if (driver->flags & I2C_DF_NOTIFY) {
+		list_for_each(item,&adapters) {
+			adapter = list_entry(item, struct i2c_adapter, list);
+			driver->attach_adapter(adapter);
 		}
 	}
 
@@ -233,44 +203,29 @@
 
 int i2c_del_driver(struct i2c_driver *driver)
 {
-	int res = 0, i, j, k;
+	struct list_head   *item1;
+	struct list_head   *item2;
+	struct i2c_client  *client;
+	struct i2c_adapter *adap;
+	
+	int res = 0;
 
 	down(&core_lists);
-	for (i = 0; i < I2C_DRIVER_MAX; i++)
-		if (driver == drivers[i])
-			break;
-	if (I2C_DRIVER_MAX == i) {
-		printk(KERN_WARNING " i2c-core.o: unregister_driver: "
-				    "[%s] not found\n",
-			driver->name);
-		res = -ENODEV;
-		goto out_unlock;
-	}
-
-	driver_unregister(&driver->driver);
 
 	/* Have a look at each adapter, if clients of this driver are still
 	 * attached. If so, detach them to be able to kill the driver 
 	 * afterwards.
 	 */
 	DEB2(printk(KERN_DEBUG "i2c-core.o: unregister_driver - looking for clients.\n"));
-
 	/* removing clients does not depend on the notify flag, else 
 	 * invalid operation might (will!) result, when using stale client
 	 * pointers.
 	 */
-	for (k=0;k<I2C_ADAP_MAX;k++) {
-		struct i2c_adapter *adap = adapters[k];
-		if (adap == NULL) /* skip empty entries. */
-			continue;
+	list_for_each(item1,&adapters) {
+		adap = list_entry(item1, struct i2c_adapter, list);
 		DEB2(dev_dbg(&adap->dev, "examining adapter\n"));
-		if (driver->flags & I2C_DF_DUMMY) {
-		/* DUMMY drivers do not register their clients, so we have to
-		 * use a trick here: we call driver->attach_adapter to
-		 * *detach* it! Of course, each dummy driver should know about
-		 * this or hell will break loose...  
-		 */
-			if ((res = driver->attach_adapter(adap))) {
+		if (driver->detach_adapter) {
+			if ((res = driver->detach_adapter(adap))) {
 				dev_warn(&adap->dev, "while unregistering "
 				       "dummy driver %s, adapter could "
 				       "not be detached properly; driver "
@@ -278,31 +233,31 @@
 				goto out_unlock;
 			}
 		} else {
-			for (j=0;j<I2C_CLIENT_MAX;j++) { 
-				struct i2c_client *client = adap->clients[j];
-				if (client != NULL && 
-				    client->driver == driver) {
-					DEB2(printk(KERN_DEBUG "i2c-core.o: "
-						    "detaching client %s:\n",
-					            client->dev.name));
-					if ((res = driver->detach_client(client))) {
-						dev_err(&adap->dev, "while "
-						       "unregistering driver "
-						       "`%s', the client at "
-						       "address %02x of "
-						       "adapter could not "
-						       "be detached; driver "
-						       "not unloaded!",
-						       driver->name,
-						       client->addr);
-						goto out_unlock;
-					}
+			list_for_each(item2,&adap->clients) {
+				client = list_entry(item2, struct i2c_client, list);
+				if (client->driver != driver)
+					continue;
+				DEB2(printk(KERN_DEBUG "i2c-core.o: "
+					    "detaching client %s:\n",
+					    client->dev.name));
+				if ((res = driver->detach_client(client))) {
+					dev_err(&adap->dev, "while "
+						"unregistering driver "
+						"`%s', the client at "
+						"address %02x of "
+						"adapter could not "
+						"be detached; driver "
+						"not unloaded!",
+						driver->name,
+						client->addr);
+					goto out_unlock;
 				}
 			}
 		}
 	}
-	drivers[i] = NULL;
-	
+
+	driver_unregister(&driver->driver);
+	list_del(&driver->list);
 	DEB(printk(KERN_DEBUG "i2c-core.o: driver unregistered: %s\n",driver->name));
 
  out_unlock:
@@ -310,14 +265,16 @@
 	return 0;
 }
 
-static int __i2c_check_addr(struct i2c_adapter *adapter, int addr)
+static int __i2c_check_addr(struct i2c_adapter *adapter, unsigned int addr)
 {
-	int i;
+	struct list_head   *item;
+	struct i2c_client  *client;
 
-	for (i = 0; i < I2C_CLIENT_MAX ; i++)
-		if (adapter->clients[i] && (adapter->clients[i]->addr == addr))
+	list_for_each(item,&adapter->clients) {
+		client = list_entry(item, struct i2c_client, list);
+		if (client->addr == addr)
 			return -EBUSY;
-
+	}
 	return 0;
 }
 
@@ -325,9 +282,9 @@
 {
 	int rval;
 
-	down(&adapter->list);
+	down(&adapter->clist_lock);
 	rval = __i2c_check_addr(adapter, addr);
-	up(&adapter->list);
+	up(&adapter->clist_lock);
 
 	return rval;
 }
@@ -335,28 +292,14 @@
 int i2c_attach_client(struct i2c_client *client)
 {
 	struct i2c_adapter *adapter = client->adapter;
-	int i;
-
-	down(&adapter->list);
-	if (__i2c_check_addr(client->adapter, client->addr))
-		goto out_unlock_list;
 
-	for (i = 0; i < I2C_CLIENT_MAX; i++) {
-		if (!adapter->clients[i])
-			goto free_slot;
+	down(&adapter->clist_lock);
+	if (__i2c_check_addr(client->adapter, client->addr)) {
+		up(&adapter->clist_lock);
+		return -EBUSY;
 	}
-
-	printk(KERN_WARNING 
-	       " i2c-core.o: attach_client(%s) - enlarge I2C_CLIENT_MAX.\n",
-	       client->dev.name);
-
- out_unlock_list:
-	up(&adapter->list);
-	return -EBUSY;
-
- free_slot:
-	adapter->clients[i] = client;
-	up(&adapter->list);
+	list_add_tail(&client->list,&adapter->clients);
+	up(&adapter->clist_lock);
 	
 	if (adapter->client_register)  {
 		if (adapter->client_register(client))  {
@@ -388,7 +331,7 @@
 int i2c_detach_client(struct i2c_client *client)
 {
 	struct i2c_adapter *adapter = client->adapter;
-	int res = 0, i;
+	int res = 0;
 	
 	if ((client->flags & I2C_CLIENT_ALLOW_USE) && (client->usage_count > 0))
 		return -EBUSY;
@@ -403,22 +346,11 @@
 		}
 	}
 
-	down(&adapter->list);
-	for (i = 0; i < I2C_CLIENT_MAX; i++) {
-		if (client == adapter->clients[i]) {
-			adapter->clients[i] = NULL;
-			goto out_unlock;
-		}
-	}
-
-	printk(KERN_WARNING
-	       " i2c-core.o: unregister_client [%s] not found\n",
-	       client->dev.name);
-	res = -ENODEV;
-
- out_unlock:
+	down(&adapter->clist_lock);
+	list_del(&client->list);
 	device_unregister(&client->dev);
-	up(&adapter->list);
+	up(&adapter->clist_lock);
+
  out:
 	return res;
 }
@@ -516,9 +448,9 @@
 	if (adap->algo->master_xfer) {
  	 	DEB2(dev_dbg(&adap->dev, "master_xfer: with %d msgs.\n", num));
 
-		down(&adap->bus);
+		down(&adap->bus_lock);
 		ret = adap->algo->master_xfer(adap,msgs,num);
-		up(&adap->bus);
+		up(&adap->bus_lock);
 
 		return ret;
 	} else {
@@ -542,9 +474,9 @@
 		DEB2(dev_dbg(&client->adapter->dev, "master_send: writing %d bytes.\n",
 				count));
 	
-		down(&adap->bus);
+		down(&adap->bus_lock);
 		ret = adap->algo->master_xfer(adap,&msg,1);
-		up(&adap->bus);
+		up(&adap->bus_lock);
 
 		/* if everything went ok (i.e. 1 msg transmitted), return #bytes
 		 * transmitted, else error code.
@@ -572,9 +504,9 @@
 		DEB2(dev_dbg(&client->adapter->dev, "master_recv: reading %d bytes.\n",
 				count));
 	
-		down(&adap->bus);
+		down(&adap->bus_lock);
 		ret = adap->algo->master_xfer(adap,&msg,1);
-		up(&adap->bus);
+		up(&adap->bus_lock);
 	
 		DEB2(printk(KERN_DEBUG "i2c-core.o: master_recv: return:%d (count:%d, addr:0x%02x)\n",
 			ret, count, client->addr));
@@ -743,11 +675,30 @@
  */
 int i2c_adapter_id(struct i2c_adapter *adap)
 {
-	int i;
-	for (i = 0; i < I2C_ADAP_MAX; i++)
-		if (adap == adapters[i])
-			return i;
-	return -1;
+	return adap->nr;
+}
+
+struct i2c_adapter* i2c_get_adapter(int id)
+{
+	struct list_head   *item;
+	struct i2c_adapter *adapter;
+	
+	down(&core_lists);
+	list_for_each(item,&adapters) {
+		adapter = list_entry(item, struct i2c_adapter, list);
+		if (id == adapter->nr &&
+		    try_module_get(adapter->owner)) {
+			up(&core_lists);
+			return adapter;
+		}
+	}
+	up(&core_lists);
+	return NULL;
+}
+
+void i2c_put_adapter(struct i2c_adapter *adap)
+{
+	module_put(adap->owner);
 }
 
 /* The SMBus parts */
@@ -1189,10 +1140,10 @@
 	}
 
 	if (adapter->algo->smbus_xfer) {
-		down(&adapter->bus);
+		down(&adapter->bus_lock);
 		res = adapter->algo->smbus_xfer(adapter,addr,flags,read_write,
 		                                command,size,data);
-		up(&adapter->bus);
+		up(&adapter->bus_lock);
 	} else
 		res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write,
 	                                      command,size,data);
@@ -1239,6 +1190,8 @@
 EXPORT_SYMBOL(i2c_control);
 EXPORT_SYMBOL(i2c_transfer);
 EXPORT_SYMBOL(i2c_adapter_id);
+EXPORT_SYMBOL(i2c_get_adapter);
+EXPORT_SYMBOL(i2c_put_adapter);
 EXPORT_SYMBOL(i2c_probe);
 
 EXPORT_SYMBOL(i2c_smbus_xfer);
diff -urN -X /home/kraxel/.kdontdiff linux-vanilla-2.5.69/drivers/i2c/i2c-dev.c linux-i2c-1-2.5.69/drivers/i2c/i2c-dev.c
--- linux-vanilla-2.5.69/drivers/i2c/i2c-dev.c	2003-05-06 14:03:11.000000000 +0200
+++ linux-i2c-1-2.5.69/drivers/i2c/i2c-dev.c	2003-05-06 13:46:19.000000000 +0200
@@ -58,6 +58,7 @@
 static int i2cdev_release (struct inode *inode, struct file *file);
 
 static int i2cdev_attach_adapter(struct i2c_adapter *adap);
+static int i2cdev_detach_adapter(struct i2c_adapter *adap);
 static int i2cdev_detach_client(struct i2c_client *client);
 static int i2cdev_command(struct i2c_client *client, unsigned int cmd,
                            void *arg);
@@ -72,15 +73,13 @@
 	.release	= i2cdev_release,
 };
 
-#define I2CDEV_ADAPS_MAX I2C_ADAP_MAX
-static struct i2c_adapter *i2cdev_adaps[I2CDEV_ADAPS_MAX];
-
 static struct i2c_driver i2cdev_driver = {
 	.owner		= THIS_MODULE,
 	.name		= "dev driver",
 	.id		= I2C_DRIVERID_I2CDEV,
-	.flags		= I2C_DF_DUMMY,
+	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= i2cdev_attach_adapter,
+	.detach_adapter	= i2cdev_detach_adapter,
 	.detach_client	= i2cdev_detach_client,
 	.command	= i2cdev_command,
 };
@@ -340,35 +339,31 @@
 {
 	unsigned int minor = minor(inode->i_rdev);
 	struct i2c_client *client;
+	struct i2c_adapter *adap;
 
-	if ((minor >= I2CDEV_ADAPS_MAX) || !(i2cdev_adaps[minor]))
+	adap = i2c_get_adapter(minor);
+	if (NULL == adap)
 		return -ENODEV;
 
 	client = kmalloc(sizeof(*client), GFP_KERNEL);
-	if (!client)
+	if (!client) {
+		i2c_put_adapter(adap);
 		return -ENOMEM;
+	}
 	memcpy(client, &i2cdev_client_template, sizeof(*client));
 
 	/* registered with adapter, passed as client to user */
-	client->adapter = i2cdev_adaps[minor];
+	client->adapter = adap;
 	file->private_data = client;
 
-	/* use adapter module, i2c-dev handled with fops */
-	if (!try_module_get(client->adapter->owner))
-		goto out_kfree;
-
 	return 0;
-
-out_kfree:
-	kfree(client);
-	return -ENODEV;
 }
 
 static int i2cdev_release(struct inode *inode, struct file *file)
 {
 	struct i2c_client *client = file->private_data;
 
-	module_put(client->adapter->owner);
+	i2c_put_adapter(client->adapter);
 	kfree(client);
 	file->private_data = NULL;
 
@@ -377,33 +372,28 @@
 
 int i2cdev_attach_adapter(struct i2c_adapter *adap)
 {
-	int i;
 	char name[12];
+	int i;
 
-	if ((i = i2c_adapter_id(adap)) < 0) {
-		dev_dbg(&adap->dev, "Unknown adapter ?!?\n");
-		return -ENODEV;
-	}
-	if (i >= I2CDEV_ADAPS_MAX) {
-		dev_dbg(&adap->dev, "Adapter number too large?!? (%d)\n",i);
-		return -ENODEV;
-	}
-
+	i = i2c_adapter_id(adap);
 	sprintf (name, "i2c/%d", i);
-	if (! i2cdev_adaps[i]) {
-		i2cdev_adaps[i] = adap;
-		devfs_register (NULL, name,
+
+	devfs_register (NULL, name,
 			DEVFS_FL_DEFAULT, I2C_MAJOR, i,
 			S_IFCHR | S_IRUSR | S_IWUSR,
 			&i2cdev_fops, NULL);
-		dev_dbg(&adap->dev, "Registered as minor %d\n", i);
-	} else {
-		/* This is actually a detach_adapter call! */
-		devfs_remove("i2c/%d", i);
-		i2cdev_adaps[i] = NULL;
-		dev_dbg(&adap->dev, "Adapter unregistered\n");
-	}
+	dev_dbg(&adap->dev, "Registered as minor %d\n", i);
+	return 0;
+}
+
+int i2cdev_detach_adapter(struct i2c_adapter *adap)
+{
+	int i;
+
+	i = i2c_adapter_id(adap);
 
+	devfs_remove("i2c/%d", i);
+	dev_dbg(&adap->dev, "Adapter unregistered\n");
 	return 0;
 }
 
diff -urN -X /home/kraxel/.kdontdiff linux-vanilla-2.5.69/drivers/media/video/dpc7146.c linux-i2c-1-2.5.69/drivers/media/video/dpc7146.c
--- linux-vanilla-2.5.69/drivers/media/video/dpc7146.c	2003-05-06 14:02:27.000000000 +0200
+++ linux-i2c-1-2.5.69/drivers/media/video/dpc7146.c	2003-05-06 13:55:30.000000000 +0200
@@ -96,7 +96,8 @@
 static int dpc_probe(struct saa7146_dev* dev)
 {
 	struct dpc* dpc = 0;	
-	int i = 0;
+	struct i2c_client *client;
+	struct list_head *item;
 
 	dpc = (struct dpc*)kmalloc(sizeof(struct dpc), GFP_KERNEL);
 	if( NULL == dpc ) {
@@ -117,12 +118,10 @@
 	}
 
 	/* loop through all i2c-devices on the bus and look who is there */
-	for(i = 0; i < I2C_CLIENT_MAX; i++) {
-		if( NULL == dpc->i2c_adapter.clients[i] ) {
-			continue;
-		}
-		if( I2C_SAA7111A == dpc->i2c_adapter.clients[i]->addr ) 
-			dpc->saa7111a = dpc->i2c_adapter.clients[i];
+	list_for_each(item,&dpc->i2c_adapter.clients) {
+		client = list_entry(item, struct i2c_client, list);
+		if( I2C_SAA7111A == client->addr ) 
+			dpc->saa7111a = client;
 	}
 
 	/* check if all devices are present */
diff -urN -X /home/kraxel/.kdontdiff linux-vanilla-2.5.69/drivers/media/video/mxb.c linux-i2c-1-2.5.69/drivers/media/video/mxb.c
--- linux-vanilla-2.5.69/drivers/media/video/mxb.c	2003-05-06 14:01:35.000000000 +0200
+++ linux-i2c-1-2.5.69/drivers/media/video/mxb.c	2003-05-06 13:53:36.000000000 +0200
@@ -208,7 +208,8 @@
 static int mxb_probe(struct saa7146_dev* dev)
 {
 	struct mxb* mxb = 0;
-	int i = 0;	
+	struct i2c_client *client;
+	struct list_head *item;
 
 	request_module("tuner");
 	request_module("tea6420");
@@ -235,22 +236,20 @@
 	}
 
 	/* loop through all i2c-devices on the bus and look who is there */
-	for(i = 0; i < I2C_CLIENT_MAX; i++) {
-		if( NULL == mxb->i2c_adapter.clients[i] ) {
-			continue;
-		}
-		if( I2C_TEA6420_1 == mxb->i2c_adapter.clients[i]->addr )
-			mxb->tea6420_1 = mxb->i2c_adapter.clients[i];
-		if( I2C_TEA6420_2 == mxb->i2c_adapter.clients[i]->addr ) 
-			mxb->tea6420_2 = mxb->i2c_adapter.clients[i];
-		if( I2C_TEA6415C_2 == mxb->i2c_adapter.clients[i]->addr ) 
-			mxb->tea6415c = mxb->i2c_adapter.clients[i];
-		if( I2C_TDA9840 == mxb->i2c_adapter.clients[i]->addr ) 
-			mxb->tda9840 = mxb->i2c_adapter.clients[i];
-		if( I2C_SAA7111A == mxb->i2c_adapter.clients[i]->addr ) 
-			mxb->saa7111a = mxb->i2c_adapter.clients[i];
-		if( 0x60 == mxb->i2c_adapter.clients[i]->addr ) 
-			mxb->tuner = mxb->i2c_adapter.clients[i];
+	list_for_each(item,&mxb->i2c_adapter.clients) {
+		client = list_entry(item, struct i2c_client, list);
+		if( I2C_TEA6420_1 == client->addr )
+			mxb->tea6420_1 = client;
+		if( I2C_TEA6420_2 == client->addr ) 
+			mxb->tea6420_2 = client;
+		if( I2C_TEA6415C_2 == client->addr ) 
+			mxb->tea6415c = client;
+		if( I2C_TDA9840 == client->addr ) 
+			mxb->tda9840 = client;
+		if( I2C_SAA7111A == client->addr ) 
+			mxb->saa7111a = client;
+		if( 0x60 == client->addr ) 
+			mxb->tuner = client;
 	}
 
 	/* check if all devices are present */
diff -urN -X /home/kraxel/.kdontdiff linux-vanilla-2.5.69/drivers/media/video/tvmixer.c linux-i2c-1-2.5.69/drivers/media/video/tvmixer.c
--- linux-vanilla-2.5.69/drivers/media/video/tvmixer.c	2003-05-06 14:03:31.000000000 +0200
+++ linux-i2c-1-2.5.69/drivers/media/video/tvmixer.c	2003-05-06 13:49:59.000000000 +0200
@@ -217,8 +217,9 @@
 	.owner           = THIS_MODULE,
 	.name            = "tv card mixer driver",
         .id              = I2C_DRIVERID_TVMIXER,
-	.flags           = I2C_DF_DUMMY,
+	.flags           = I2C_DF_NOTIFY,
         .attach_adapter  = tvmixer_adapters,
+        .detach_adapter  = tvmixer_adapters,
         .detach_client   = tvmixer_clients,
 };
 
@@ -234,14 +235,15 @@
 
 static int tvmixer_adapters(struct i2c_adapter *adap)
 {
-	int i;
+	struct list_head  *item;
+	struct i2c_client *client;
 
 	if (debug)
 		printk("tvmixer: adapter %s\n",adap->dev.name);
-	for (i=0; i<I2C_CLIENT_MAX; i++) {
-		if (!adap->clients[i])
-			continue;
-		tvmixer_clients(adap->clients[i]);
+
+	list_for_each(item,&adap->clients) {
+		client = list_entry(item, struct i2c_client, list);
+		tvmixer_clients(client);
 	}
 	return 0;
 }
@@ -264,7 +266,8 @@
 			       client->adapter->dev.name);
 		return -1;
 	}
-	printk("tvmixer: debug: %s\n",client->dev.name);
+	if (debug)
+		printk("tvmixer: debug: %s\n",client->dev.name);
 
 	/* unregister ?? */
 	for (i = 0; i < DEV_MAX; i++) {
diff -urN -X /home/kraxel/.kdontdiff linux-vanilla-2.5.69/include/linux/i2c.h linux-i2c-1-2.5.69/include/linux/i2c.h
--- linux-vanilla-2.5.69/include/linux/i2c.h	2003-05-06 14:01:56.000000000 +0200
+++ linux-i2c-1-2.5.69/include/linux/i2c.h	2003-05-06 13:41:07.000000000 +0200
@@ -39,12 +39,6 @@
 
 /* --- General options ------------------------------------------------	*/
 
-#define I2C_ALGO_MAX	4		/* control memory consumption	*/
-#define I2C_ADAP_MAX	16
-#define I2C_DRIVER_MAX	16
-#define I2C_CLIENT_MAX	32
-#define I2C_DUMMY_MAX 4
-
 struct i2c_msg;
 struct i2c_algorithm;
 struct i2c_adapter;
@@ -131,6 +125,7 @@
 	 * i2c_attach_client.
 	 */
 	int (*attach_adapter)(struct i2c_adapter *);
+	int (*detach_adapter)(struct i2c_adapter *);
 
 	/* tells the driver that a client is about to be deleted & gives it 
 	 * the chance to remove its private data. Also, if the client struct
@@ -145,6 +140,7 @@
 	int (*command)(struct i2c_client *client,unsigned int cmd, void *arg);
 
 	struct device_driver driver;
+	struct list_head list;
 };
 #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver)
 
@@ -169,6 +165,7 @@
 	int usage_count;		/* How many accesses currently  */
 					/* to the client		*/
 	struct device dev;		/* the device structure		*/
+	struct list_head list;
 };
 #define to_i2c_client(d) container_of(d, struct i2c_client, dev)
 
@@ -236,12 +233,10 @@
 	int (*client_unregister)(struct i2c_client *);
 
 	/* data fields that are valid for all devices	*/
-	struct semaphore bus;
-	struct semaphore list;  
+	struct semaphore bus_lock;
+	struct semaphore clist_lock;
 	unsigned int flags;/* flags specifying div. data		*/
 
-	struct i2c_client *clients[I2C_CLIENT_MAX];
-
 	int timeout;
 	int retries;
 	struct device dev;	/* the adapter device */
@@ -250,6 +245,10 @@
 	/* No need to set this when you initialize the adapter          */
 	int inode;
 #endif /* def CONFIG_PROC_FS */
+
+	int nr;
+	struct list_head clients;
+	struct list_head list;
 };
 #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
 
@@ -265,7 +264,11 @@
 
 /*flags for the driver struct: */
 #define I2C_DF_NOTIFY	0x01		/* notify on bus (de/a)ttaches 	*/
-#define I2C_DF_DUMMY	0x02		/* do not connect any clients */
+#if 0
+/* this flag is gone -- there is a (optional) driver->detach_adapter
+ * callback now which can be used instead */
+# define I2C_DF_DUMMY	0x02
+#endif
 
 /*flags for the client struct: */
 #define I2C_CLIENT_ALLOW_USE		0x01	/* Client allows access */
@@ -352,7 +355,8 @@
  * or -1 if the adapter was not registered. 
  */
 extern int i2c_adapter_id(struct i2c_adapter *adap);
-
+extern struct i2c_adapter* i2c_get_adapter(int id);
+extern void i2c_put_adapter(struct i2c_adapter *adap);
 
 
 /* Return the functionality mask */

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2003-05-09 21:46 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-05-06 19:34 [patch] i2c #1/3: listify i2c core Gerd Knorr
2003-05-06 19:40 ` [patch] i2c #2/3: add i2c_clients_command Gerd Knorr
2003-05-06 19:51   ` [patch] i2c #3/3: add class field to i2c_adapter Gerd Knorr
2003-05-07 10:12     ` Mark McClelland
2003-05-09 22:00       ` Greg KH
2003-05-07  0:17 ` [patch] i2c #1/3: listify i2c core Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).