]> Pileus Git - ~andy/linux/blobdiff - drivers/media/video/cx88/cx88-mpeg.c
Merge git://git.infradead.org/battery-2.6
[~andy/linux] / drivers / media / video / cx88 / cx88-mpeg.c
index a652f294d23d8dd8e6a135eab458395ddb8928f6..448c67380945e62d4598793b19bb027445c7ac02 100644 (file)
@@ -79,7 +79,8 @@ static int cx8802_start_dma(struct cx8802_dev    *dev,
 {
        struct cx88_core *core = dev->core;
 
-       dprintk(1, "cx8802_start_dma w: %d, h: %d, f: %d\n", dev->width, dev->height, buf->vb.field);
+       dprintk(1, "cx8802_start_dma w: %d, h: %d, f: %d\n",
+               buf->vb.width, buf->vb.height, buf->vb.field);
 
        /* setup fifo + format */
        cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
@@ -177,7 +178,6 @@ static int cx8802_restart_queue(struct cx8802_dev    *dev,
                                struct cx88_dmaqueue *q)
 {
        struct cx88_buffer *buf;
-       struct list_head *item;
 
        dprintk( 1, "cx8802_restart_queue\n" );
        if (list_empty(&q->active))
@@ -223,10 +223,8 @@ static int cx8802_restart_queue(struct cx8802_dev    *dev,
        dprintk(2,"restart_queue [%p/%d]: restart dma\n",
                buf, buf->vb.i);
        cx8802_start_dma(dev, q, buf);
-       list_for_each(item,&q->active) {
-               buf = list_entry(item, struct cx88_buffer, vb.queue);
+       list_for_each_entry(buf, &q->active, vb.queue)
                buf->count = q->count++;
-       }
        mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
        return 0;
 }
@@ -572,42 +570,29 @@ int cx8802_resume_common(struct pci_dev *pci_dev)
        return 0;
 }
 
+#if defined(CONFIG_VIDEO_CX88_BLACKBIRD) || \
+    defined(CONFIG_VIDEO_CX88_BLACKBIRD_MODULE)
 struct cx8802_dev * cx8802_get_device(struct inode *inode)
 {
        int minor = iminor(inode);
-       struct cx8802_dev *h = NULL;
-       struct list_head *list;
+       struct cx8802_dev *dev;
 
-       list_for_each(list,&cx8802_devlist) {
-               h = list_entry(list, struct cx8802_dev, devlist);
-               if (h->mpeg_dev && h->mpeg_dev->minor == minor)
-                       return h;
-       }
+       list_for_each_entry(dev, &cx8802_devlist, devlist)
+               if (dev->mpeg_dev && dev->mpeg_dev->minor == minor)
+                       return dev;
 
        return NULL;
 }
+EXPORT_SYMBOL(cx8802_get_device);
+#endif
 
 struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype)
 {
-       struct cx8802_dev *h = NULL;
-       struct cx8802_driver *d = NULL;
-       struct list_head *list;
-       struct list_head *list2;
-
-       list_for_each(list,&cx8802_devlist) {
-               h = list_entry(list, struct cx8802_dev, devlist);
-               if (h != dev)
-                       continue;
-
-               list_for_each(list2, &h->drvlist.devlist) {
-                       d = list_entry(list2, struct cx8802_driver, devlist);
+       struct cx8802_driver *d;
 
-                       /* only unregister the correct driver type */
-                       if (d->type_id == btype) {
-                               return d;
-                       }
-               }
-       }
+       list_for_each_entry(d, &dev->drvlist, drvlist)
+               if (d->type_id == btype)
+                       return d;
 
        return NULL;
 }
@@ -671,10 +656,9 @@ static int cx8802_check_driver(struct cx8802_driver *drv)
 
 int cx8802_register_driver(struct cx8802_driver *drv)
 {
-       struct cx8802_dev *h;
+       struct cx8802_dev *dev;
        struct cx8802_driver *driver;
-       struct list_head *list;
-       int err = 0, i = 0;
+       int err, i = 0;
 
        printk(KERN_INFO
               "cx88/2: registering cx8802 driver, type: %s access: %s\n",
@@ -686,14 +670,12 @@ int cx8802_register_driver(struct cx8802_driver *drv)
                return err;
        }
 
-       list_for_each(list,&cx8802_devlist) {
-               h = list_entry(list, struct cx8802_dev, devlist);
-
+       list_for_each_entry(dev, &cx8802_devlist, devlist) {
                printk(KERN_INFO
                       "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n",
-                      h->core->name, h->pci->subsystem_vendor,
-                      h->pci->subsystem_device, h->core->board.name,
-                      h->core->boardnr);
+                      dev->core->name, dev->pci->subsystem_vendor,
+                      dev->pci->subsystem_device, dev->core->board.name,
+                      dev->core->boardnr);
 
                /* Bring up a new struct for each driver instance */
                driver = kzalloc(sizeof(*drv),GFP_KERNEL);
@@ -701,7 +683,7 @@ int cx8802_register_driver(struct cx8802_driver *drv)
                        return -ENOMEM;
 
                /* Snapshot of the driver registration data */
-               drv->core = h->core;
+               drv->core = dev->core;
                drv->suspend = cx8802_suspend_common;
                drv->resume = cx8802_resume_common;
                drv->request_acquire = cx8802_request_acquire;
@@ -712,49 +694,38 @@ int cx8802_register_driver(struct cx8802_driver *drv)
                if (err == 0) {
                        i++;
                        mutex_lock(&drv->core->lock);
-                       list_add_tail(&driver->devlist,&h->drvlist.devlist);
+                       list_add_tail(&driver->drvlist, &dev->drvlist);
                        mutex_unlock(&drv->core->lock);
                } else {
                        printk(KERN_ERR
                               "%s/2: cx8802 probe failed, err = %d\n",
-                              h->core->name, err);
+                              dev->core->name, err);
                }
 
        }
-       if (i == 0)
-               err = -ENODEV;
-       else
-               err = 0;
 
-       return err;
+       return i ? 0 : -ENODEV;
 }
 
 int cx8802_unregister_driver(struct cx8802_driver *drv)
 {
-       struct cx8802_dev *h;
-       struct cx8802_driver *d;
-       struct list_head *list;
-       struct list_head *list2, *q;
-       int err = 0, i = 0;
+       struct cx8802_dev *dev;
+       struct cx8802_driver *d, *dtmp;
+       int err = 0;
 
        printk(KERN_INFO
               "cx88/2: unregistering cx8802 driver, type: %s access: %s\n",
               drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird",
               drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive");
 
-       list_for_each(list,&cx8802_devlist) {
-               i++;
-               h = list_entry(list, struct cx8802_dev, devlist);
-
+       list_for_each_entry(dev, &cx8802_devlist, devlist) {
                printk(KERN_INFO
                       "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n",
-                      h->core->name, h->pci->subsystem_vendor,
-                      h->pci->subsystem_device, h->core->board.name,
-                      h->core->boardnr);
-
-               list_for_each_safe(list2, q, &h->drvlist.devlist) {
-                       d = list_entry(list2, struct cx8802_driver, devlist);
+                      dev->core->name, dev->pci->subsystem_vendor,
+                      dev->pci->subsystem_device, dev->core->board.name,
+                      dev->core->boardnr);
 
+               list_for_each_entry_safe(d, dtmp, &dev->drvlist, drvlist) {
                        /* only unregister the correct driver type */
                        if (d->type_id != drv->type_id)
                                continue;
@@ -762,12 +733,12 @@ int cx8802_unregister_driver(struct cx8802_driver *drv)
                        err = d->remove(d);
                        if (err == 0) {
                                mutex_lock(&drv->core->lock);
-                               list_del(list2);
+                               list_del(&d->drvlist);
                                mutex_unlock(&drv->core->lock);
+                               kfree(d);
                        } else
                                printk(KERN_ERR "%s/2: cx8802 driver remove "
-                                      "failed (%d)\n", h->core->name, err);
-
+                                      "failed (%d)\n", dev->core->name, err);
                }
 
        }
@@ -805,7 +776,7 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
        if (err != 0)
                goto fail_free;
 
-       INIT_LIST_HEAD(&dev->drvlist.devlist);
+       INIT_LIST_HEAD(&dev->drvlist);
        list_add_tail(&dev->devlist,&cx8802_devlist);
 
        /* Maintain a reference so cx88-video can query the 8802 device. */
@@ -825,23 +796,30 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
 static void __devexit cx8802_remove(struct pci_dev *pci_dev)
 {
        struct cx8802_dev *dev;
-       struct cx8802_driver *h;
-       struct list_head *list;
 
        dev = pci_get_drvdata(pci_dev);
 
        dprintk( 1, "%s\n", __FUNCTION__);
 
-       list_for_each(list,&dev->drvlist.devlist) {
-               h = list_entry(list, struct cx8802_driver, devlist);
-               dprintk( 1, " ->driver\n");
-               if (h->remove == NULL) {
-                       printk(KERN_ERR "%s .. skipping driver, no probe function\n", __FUNCTION__);
-                       continue;
+       if (!list_empty(&dev->drvlist)) {
+               struct cx8802_driver *drv, *tmp;
+               int err;
+
+               printk(KERN_WARNING "%s/2: Trying to remove cx8802 driver "
+                      "while cx8802 sub-drivers still loaded?!\n",
+                      dev->core->name);
+
+               list_for_each_entry_safe(drv, tmp, &dev->drvlist, drvlist) {
+                       err = drv->remove(drv);
+                       if (err == 0) {
+                               mutex_lock(&drv->core->lock);
+                               list_del(&drv->drvlist);
+                               mutex_unlock(&drv->core->lock);
+                       } else
+                               printk(KERN_ERR "%s/2: cx8802 driver remove "
+                                      "failed (%d)\n", dev->core->name, err);
+                       kfree(drv);
                }
-               printk(KERN_INFO "%s .. Removing driver type %d\n", __FUNCTION__, h->type_id);
-               cx8802_unregister_driver(h);
-               list_del(&dev->drvlist.devlist);
        }
 
        /* Destroy any 8802 reference. */
@@ -901,7 +879,6 @@ EXPORT_SYMBOL(cx8802_fini_common);
 
 EXPORT_SYMBOL(cx8802_register_driver);
 EXPORT_SYMBOL(cx8802_unregister_driver);
-EXPORT_SYMBOL(cx8802_get_device);
 EXPORT_SYMBOL(cx8802_get_driver);
 /* ----------------------------------------------------------- */
 /*