linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / media / video / bttv-gpio.c
index 585f67d..c4d5e2b 100644 (file)
@@ -1,4 +1,5 @@
 /*
+
     bttv-gpio.c  --  gpio sub drivers
 
     sysfs-based sub driver interface for bttv
@@ -6,7 +7,7 @@
 
 
     Copyright (C) 1996,97,98 Ralph  Metzler (rjkm@thp.uni-koeln.de)
-                           & Marcus Metzler (mocm@thp.uni-koeln.de)
+                          & Marcus Metzler (mocm@thp.uni-koeln.de)
     (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
 
     This program is free software; you can redistribute it and/or modify
@@ -22,7 +23,7 @@
     You should have received a copy of the GNU General Public License
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-    
+
 */
 
 #include <linux/module.h>
@@ -46,9 +47,29 @@ static int bttv_sub_bus_match(struct device *dev, struct device_driver *drv)
        return 0;
 }
 
+static int bttv_sub_probe(struct device *dev)
+{
+       struct bttv_sub_device *sdev = to_bttv_sub_dev(dev);
+       struct bttv_sub_driver *sub = to_bttv_sub_drv(dev->driver);
+
+       return sub->probe ? sub->probe(sdev) : -ENODEV;
+}
+
+static int bttv_sub_remove(struct device *dev)
+{
+       struct bttv_sub_device *sdev = to_bttv_sub_dev(dev);
+       struct bttv_sub_driver *sub = to_bttv_sub_drv(dev->driver);
+
+       if (sub->remove)
+               sub->remove(sdev);
+       return 0;
+}
+
 struct bus_type bttv_sub_bus_type = {
-       .name  = "bttv-sub",
-       .match = &bttv_sub_bus_match,
+       .name   = "bttv-sub",
+       .match  = &bttv_sub_bus_match,
+       .probe  = bttv_sub_probe,
+       .remove = bttv_sub_remove,
 };
 EXPORT_SYMBOL(bttv_sub_bus_type);
 
@@ -61,11 +82,11 @@ static void release_sub_device(struct device *dev)
 int bttv_sub_add_device(struct bttv_core *core, char *name)
 {
        struct bttv_sub_device *sub;
+       int err;
 
-       sub = kmalloc(sizeof(*sub),GFP_KERNEL);
+       sub = kzalloc(sizeof(*sub),GFP_KERNEL);
        if (NULL == sub)
                return -ENOMEM;
-       memset(sub,0,sizeof(*sub));
 
        sub->core        = core;
        sub->dev.parent  = &core->pci->dev;
@@ -74,9 +95,13 @@ int bttv_sub_add_device(struct bttv_core *core, char *name)
        snprintf(sub->dev.bus_id,sizeof(sub->dev.bus_id),"%s%d",
                 name, core->nr);
 
+       err = device_register(&sub->dev);
+       if (0 != err) {
+               kfree(sub);
+               return err;
+       }
        printk("bttv%d: add subdevice \"%s\"\n", core->nr, sub->dev.bus_id);
        list_add_tail(&sub->list,&core->subs);
-       device_register(&sub->dev);
        return 0;
 }
 
@@ -87,6 +112,7 @@ int bttv_sub_del_devices(struct bttv_core *core)
 
        list_for_each_safe(item,save,&core->subs) {
                sub = list_entry(item,struct bttv_sub_device,list);
+               list_del(&sub->list);
                device_unregister(&sub->dev);
        }
        return 0;
@@ -106,20 +132,6 @@ void bttv_gpio_irq(struct bttv_core *core)
        }
 }
 
-void bttv_i2c_info(struct bttv_core *core, struct i2c_client *client, int attach)
-{
-       struct bttv_sub_driver *drv;
-       struct bttv_sub_device *dev;
-       struct list_head *item;
-
-       list_for_each(item,&core->subs) {
-               dev = list_entry(item,struct bttv_sub_device,list);
-               drv = to_bttv_sub_drv(dev->dev.driver);
-               if (drv && drv->i2c_info)
-                       drv->i2c_info(dev,client,attach);
-       }
-}
-
 /* ----------------------------------------------------------------------- */
 /* external: sub-driver register/unregister                                */
 
@@ -127,8 +139,7 @@ int bttv_sub_register(struct bttv_sub_driver *sub, char *wanted)
 {
        sub->drv.bus = &bttv_sub_bus_type;
        snprintf(sub->wanted,sizeof(sub->wanted),"%s",wanted);
-       driver_register(&sub->drv);
-       return 0;
+       return driver_register(&sub->drv);
 }
 EXPORT_SYMBOL(bttv_sub_register);