]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/media/video/cx18/cx18-driver.c
V4L/DVB (9730): cx18: Quiet a sometimes common warning that often has benign consequences
[linux-2.6-omap-h63xx.git] / drivers / media / video / cx18 / cx18-driver.c
index 7a1a7830a6b3fcc49ec0b1ff86c049c816c13b38..fbcbb500ca74304432e49b5850466be8e3a20b62 100644 (file)
@@ -56,6 +56,9 @@ struct cx18 *cx18_cards[CX18_MAX_CARDS];
 /* Protects cx18_cards_active */
 DEFINE_SPINLOCK(cx18_cards_lock);
 
+/* Queue for deferrable IRQ handling work for all cx18 cards in system */
+struct workqueue_struct *cx18_work_queue;
+
 /* add your revision and whatnot here */
 static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
        {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418,
@@ -75,14 +78,9 @@ static int radio[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
                                     -1, -1, -1, -1, -1, -1, -1, -1,
                                     -1, -1, -1, -1, -1, -1, -1, -1,
                                     -1, -1, -1, -1, -1, -1, -1, -1 };
-static int mmio_ndelay[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
-                                          -1, -1, -1, -1, -1, -1, -1, -1,
-                                          -1, -1, -1, -1, -1, -1, -1, -1,
-                                          -1, -1, -1, -1, -1, -1, -1, -1 };
 static unsigned cardtype_c = 1;
 static unsigned tuner_c = 1;
 static unsigned radio_c = 1;
-static unsigned mmio_ndelay_c = 1;
 static char pal[] = "--";
 static char secam[] = "--";
 static char ntsc[] = "-";
@@ -96,18 +94,20 @@ static int enc_pcm_buffers = CX18_DEFAULT_ENC_PCM_BUFFERS;
 
 static int cx18_pci_latency = 1;
 
-int cx18_retry_mmio = 1;
+static int mmio_ndelay;
+static int retry_mmio = 1;
+
 int cx18_debug;
 
 module_param_array(tuner, int, &tuner_c, 0644);
 module_param_array(radio, bool, &radio_c, 0644);
 module_param_array(cardtype, int, &cardtype_c, 0644);
-module_param_array(mmio_ndelay, int, &mmio_ndelay_c, 0644);
 module_param_string(pal, pal, sizeof(pal), 0644);
 module_param_string(secam, secam, sizeof(secam), 0644);
 module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
 module_param_named(debug, cx18_debug, int, 0644);
-module_param_named(retry_mmio, cx18_retry_mmio, int, 0644);
+module_param(mmio_ndelay, int, 0644);
+module_param(retry_mmio, int, 0644);
 module_param(cx18_pci_latency, int, 0644);
 module_param(cx18_first_minor, int, 0644);
 
@@ -152,13 +152,11 @@ MODULE_PARM_DESC(cx18_pci_latency,
                 "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n"
                 "\t\t\tDefault: Yes");
 MODULE_PARM_DESC(retry_mmio,
-                "Check and retry memory mapped IO accesses\n"
-                "\t\t\tDefault: 1 [Yes]");
+                "(Deprecated) MMIO writes are now always checked and retried\n"
+                "\t\t\tEffectively: 1 [Yes]");
 MODULE_PARM_DESC(mmio_ndelay,
-                "Delay (ns) for each CX23418 memory mapped IO access.\n"
-                "\t\t\tTry larger values that are close to a multiple of the\n"
-                "\t\t\tPCI clock period, 30.3 ns, if your card doesn't work.\n"
-                "\t\t\tDefault: " __stringify(CX18_DEFAULT_MMIO_NDELAY));
+                "(Deprecated) MMIO accesses are now never purposely delayed\n"
+                "\t\t\tEffectively: 0 ns");
 MODULE_PARM_DESC(enc_mpg_buffers,
                 "Encoder MPG Buffers (in MB)\n"
                 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFFERS));
@@ -187,7 +185,7 @@ MODULE_VERSION(CX18_VERSION);
 /* Generic utility functions */
 int cx18_msleep_timeout(unsigned int msecs, int intr)
 {
-       int timeout = msecs_to_jiffies(msecs);
+       long int timeout = msecs_to_jiffies(msecs);
        int sig;
 
        do {
@@ -375,11 +373,6 @@ static void cx18_process_options(struct cx18 *cx)
        cx->options.tuner = tuner[cx->num];
        cx->options.radio = radio[cx->num];
 
-       if (mmio_ndelay[cx->num] < 0)
-               cx->options.mmio_ndelay = CX18_DEFAULT_MMIO_NDELAY;
-       else
-               cx->options.mmio_ndelay = mmio_ndelay[cx->num];
-
        cx->std = cx18_parse_std(cx);
        if (cx->options.cardtype == -1) {
                CX18_INFO("Ignore card\n");
@@ -440,15 +433,24 @@ done:
  */
 static int __devinit cx18_init_struct1(struct cx18 *cx)
 {
+       int i;
+
        cx->base_addr = pci_resource_start(cx->dev, 0);
 
        mutex_init(&cx->serialize_lock);
        mutex_init(&cx->i2c_bus_lock[0]);
        mutex_init(&cx->i2c_bus_lock[1]);
        mutex_init(&cx->gpio_lock);
+       mutex_init(&cx->epu2apu_mb_lock);
+       mutex_init(&cx->epu2cpu_mb_lock);
 
        spin_lock_init(&cx->lock);
-       spin_lock_init(&cx->dma_reg_lock);
+
+       for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++) {
+               cx->epu_work_order[i].cx = cx;
+               cx->epu_work_order[i].str = cx->epu_debug_str;
+               INIT_WORK(&cx->epu_work_order[i].work, cx18_epu_work_handler);
+       }
 
        /* start counting open_id at 1 */
        cx->open_id = 1;
@@ -465,8 +467,6 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
        init_waitqueue_head(&cx->cap_w);
        init_waitqueue_head(&cx->mb_apu_waitq);
        init_waitqueue_head(&cx->mb_cpu_waitq);
-       init_waitqueue_head(&cx->mb_epu_waitq);
-       init_waitqueue_head(&cx->mb_hpu_waitq);
        init_waitqueue_head(&cx->dma_waitq);
 
        /* VBI */
@@ -581,10 +581,10 @@ static void cx18_load_and_init_modules(struct cx18 *cx)
 
 #ifdef MODULE
        /* load modules */
-#ifndef CONFIG_MEDIA_TUNER
+#ifdef CONFIG_MEDIA_TUNER_MODULE
        hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER);
 #endif
-#ifndef CONFIG_VIDEO_CS5345
+#ifdef CONFIG_VIDEO_CS5345_MODULE
        hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345);
 #endif
 #endif
@@ -732,8 +732,6 @@ static int __devinit cx18_probe(struct pci_dev *dev,
                cx->std = V4L2_STD_NTSC_M;
 
        if (cx->options.tuner == -1) {
-               int i;
-
                for (i = 0; i < CX18_CARD_MAX_TUNERS; i++) {
                        if ((cx->std & cx->card->tuners[i].std) == 0)
                                continue;
@@ -836,7 +834,6 @@ err:
        if (retval == 0)
                retval = -ENODEV;
        CX18_ERR("Error %d on initialization\n", retval);
-       cx18_log_statistics(cx);
 
        i = cx->num;
        spin_lock(&cx18_cards_lock);
@@ -915,6 +912,13 @@ int cx18_init_on_first_open(struct cx18 *cx)
        return 0;
 }
 
+static void cx18_cancel_epu_work_orders(struct cx18 *cx)
+{
+       int i;
+       for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++)
+               cancel_work_sync(&cx->epu_work_order[i].work);
+}
+
 static void cx18_remove(struct pci_dev *pci_dev)
 {
        struct cx18 *cx = pci_get_drvdata(pci_dev);
@@ -932,6 +936,8 @@ static void cx18_remove(struct pci_dev *pci_dev)
 
        cx18_halt_firmware(cx);
 
+       cx18_cancel_epu_work_orders(cx);
+
        cx18_streams_cleanup(cx, 1);
 
        exit_cx18_i2c(cx);
@@ -944,7 +950,6 @@ static void cx18_remove(struct pci_dev *pci_dev)
 
        pci_disable_device(cx->dev);
 
-       cx18_log_statistics(cx);
        CX18_INFO("Removed %s, card #%d\n", cx->card_name, cx->num);
 }
 
@@ -974,8 +979,17 @@ static int module_start(void)
                printk(KERN_INFO "cx18:   Debug value must be >= 0 and <= 511!\n");
        }
 
+       cx18_work_queue = create_singlethread_workqueue("cx18");
+       if (cx18_work_queue == NULL) {
+               printk(KERN_ERR
+                      "cx18:   Unable to create work hander thread\n");
+               return -ENOMEM;
+       }
+
        if (pci_register_driver(&cx18_pci_driver)) {
                printk(KERN_ERR "cx18:   Error detecting PCI card\n");
+               destroy_workqueue(cx18_work_queue);
+               cx18_work_queue = NULL;
                return -ENODEV;
        }
        printk(KERN_INFO "cx18:  End initialization\n");
@@ -988,11 +1002,15 @@ static void module_cleanup(void)
 
        pci_unregister_driver(&cx18_pci_driver);
 
+       destroy_workqueue(cx18_work_queue);
+       cx18_work_queue = NULL;
+
        for (i = 0; i < cx18_cards_active; i++) {
                if (cx18_cards[i] == NULL)
                        continue;
                kfree(cx18_cards[i]);
        }
+
 }
 
 module_init(module_start);