]> err.no Git - linux-2.6/blobdiff - drivers/media/video/cx88/cx88-mpeg.c
V4L/DVB (6834): cx88-video: Enable selection of the WM8775 for cx88 cards
[linux-2.6] / drivers / media / video / cx88 / cx88-mpeg.c
index a652f294d23d8dd8e6a135eab458395ddb8928f6..339a88a64f5478f186ff4590cbd7897f60ce4bad 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))
@@ -195,7 +195,7 @@ static int cx8802_restart_queue(struct cx8802_dev    *dev,
                                list_del(&buf->vb.queue);
                                list_add_tail(&buf->vb.queue,&q->active);
                                cx8802_start_dma(dev, q, buf);
-                               buf->vb.state = STATE_ACTIVE;
+                               buf->vb.state = VIDEOBUF_ACTIVE;
                                buf->count    = q->count++;
                                mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
                                dprintk(1,"[%p/%d] restart_queue - first active\n",
@@ -206,7 +206,7 @@ static int cx8802_restart_queue(struct cx8802_dev    *dev,
                                   prev->fmt       == buf->fmt) {
                                list_del(&buf->vb.queue);
                                list_add_tail(&buf->vb.queue,&q->active);
-                               buf->vb.state = STATE_ACTIVE;
+                               buf->vb.state = VIDEOBUF_ACTIVE;
                                buf->count    = q->count++;
                                prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
                                dprintk(1,"[%p/%d] restart_queue - move to active\n",
@@ -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;
 }
@@ -244,7 +242,7 @@ int cx8802_buf_prepare(struct videobuf_queue *q, struct cx8802_dev *dev,
        if (0 != buf->vb.baddr  &&  buf->vb.bsize < size)
                return -EINVAL;
 
-       if (STATE_NEEDS_INIT == buf->vb.state) {
+       if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
                buf->vb.width  = dev->ts_packet_size;
                buf->vb.height = dev->ts_packet_count;
                buf->vb.size   = size;
@@ -256,7 +254,7 @@ int cx8802_buf_prepare(struct videobuf_queue *q, struct cx8802_dev *dev,
                                     dma->sglist,
                                     buf->vb.width, buf->vb.height, 0);
        }
-       buf->vb.state = STATE_PREPARED;
+       buf->vb.state = VIDEOBUF_PREPARED;
        return 0;
 
  fail:
@@ -278,7 +276,7 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
                dprintk( 1, "queue is empty - first active\n" );
                list_add_tail(&buf->vb.queue,&cx88q->active);
                cx8802_start_dma(dev, cx88q, buf);
-               buf->vb.state = STATE_ACTIVE;
+               buf->vb.state = VIDEOBUF_ACTIVE;
                buf->count    = cx88q->count++;
                mod_timer(&cx88q->timeout, jiffies+BUFFER_TIMEOUT);
                dprintk(1,"[%p/%d] %s - first active\n",
@@ -288,7 +286,7 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
                dprintk( 1, "queue is not empty - append to active\n" );
                prev = list_entry(cx88q->active.prev, struct cx88_buffer, vb.queue);
                list_add_tail(&buf->vb.queue,&cx88q->active);
-               buf->vb.state = STATE_ACTIVE;
+               buf->vb.state = VIDEOBUF_ACTIVE;
                buf->count    = cx88q->count++;
                prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
                dprintk( 1, "[%p/%d] %s - append to active\n",
@@ -308,7 +306,7 @@ static void do_cancel_buffers(struct cx8802_dev *dev, char *reason, int restart)
        while (!list_empty(&q->active)) {
                buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
                list_del(&buf->vb.queue);
-               buf->vb.state = STATE_ERROR;
+               buf->vb.state = VIDEOBUF_ERROR;
                wake_up(&buf->vb.done);
                dprintk(1,"[%p/%d] %s - dma=0x%08lx\n",
                        buf, buf->vb.i, reason, (unsigned long)buf->risc.dma);
@@ -439,10 +437,7 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id)
        return IRQ_RETVAL(handled);
 }
 
-/* ----------------------------------------------------------- */
-/* exported stuff                                              */
-
-int cx8802_init_common(struct cx8802_dev *dev)
+static int cx8802_init_common(struct cx8802_dev *dev)
 {
        struct cx88_core *core = dev->core;
        int err;
@@ -490,7 +485,7 @@ int cx8802_init_common(struct cx8802_dev *dev)
        return 0;
 }
 
-void cx8802_fini_common(struct cx8802_dev *dev)
+static void cx8802_fini_common(struct cx8802_dev *dev)
 {
        dprintk( 2, "cx8802_fini_common\n" );
        cx8802_stop_dma(dev);
@@ -506,7 +501,7 @@ void cx8802_fini_common(struct cx8802_dev *dev)
 
 /* ----------------------------------------------------------- */
 
-int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state)
+static int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state)
 {
        struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
        struct cx88_core *core = dev->core;
@@ -532,7 +527,7 @@ int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state)
        return 0;
 }
 
-int cx8802_resume_common(struct pci_dev *pci_dev)
+static int cx8802_resume_common(struct pci_dev *pci_dev)
 {
        struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
        struct cx88_core *core = dev->core;
@@ -572,42 +567,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 +653,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 +667,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 +680,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 +691,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 +730,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 +773,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 +793,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. */
@@ -896,12 +871,8 @@ EXPORT_SYMBOL(cx8802_buf_prepare);
 EXPORT_SYMBOL(cx8802_buf_queue);
 EXPORT_SYMBOL(cx8802_cancel_buffers);
 
-EXPORT_SYMBOL(cx8802_init_common);
-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);
 /* ----------------------------------------------------------- */
 /*