summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/cx18/cx18-driver.c
diff options
context:
space:
mode:
authorPatrick Boettcher <pb@linuxtv.org>2008-12-10 22:28:25 +0100
committerPatrick Boettcher <pb@linuxtv.org>2008-12-10 22:28:25 +0100
commita9efe23fbe1000bff6e24012a5b580f9a8b93a92 (patch)
tree0308e2214bcc86e348e5d731d6bf958f1d4bf54f /linux/drivers/media/video/cx18/cx18-driver.c
parent12583b9f4af4d04cce76742c9859bff4068e6345 (diff)
parent97b478e31ccddc358a73628542bb2d32983abeac (diff)
downloadmediapointer-dvb-s2-a9efe23fbe1000bff6e24012a5b580f9a8b93a92.tar.gz
mediapointer-dvb-s2-a9efe23fbe1000bff6e24012a5b580f9a8b93a92.tar.bz2
sync from main
From: Patrick Boettcher <pb@linuxtv.org> sync from main Priority: normal Signed-off-by: Patrick Boettcher <pb@linuxtv.org>
Diffstat (limited to 'linux/drivers/media/video/cx18/cx18-driver.c')
-rw-r--r--linux/drivers/media/video/cx18/cx18-driver.c80
1 files changed, 50 insertions, 30 deletions
diff --git a/linux/drivers/media/video/cx18/cx18-driver.c b/linux/drivers/media/video/cx18/cx18-driver.c
index 54f0fde42..57fcce84b 100644
--- a/linux/drivers/media/video/cx18/cx18-driver.c
+++ b/linux/drivers/media/video/cx18/cx18-driver.c
@@ -75,14 +75,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 +91,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 +149,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));
@@ -375,11 +370,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,6 +430,8 @@ 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);
@@ -451,11 +443,22 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
spin_lock_init(&cx->lock);
+ cx->work_queue = create_singlethread_workqueue(cx->name);
+ if (cx->work_queue == NULL) {
+ CX18_ERR("Unable to create work hander thread\n");
+ return -ENOMEM;
+ }
+
+ 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;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
- INIT_WORK(&cx->work, cx18_work_handler);
+ INIT_WORK(&cx->epu_work_order[i].work, cx18_epu_work_handler);
#else
- INIT_WORK(&cx->work, cx18_work_handler, cx);
+ INIT_WORK(&cx->epu_work_order[i].work, cx18_epu_work_handler,
+ &cx->epu_work_order[i].work);
#endif
+ }
/* start counting open_id at 1 */
cx->open_id = 1;
@@ -660,12 +663,9 @@ static int __devinit cx18_probe(struct pci_dev *dev,
/* PCI Device Setup */
retval = cx18_setup_pci(cx, dev, pci_id);
- if (retval != 0) {
- if (retval == -EIO)
- goto free_workqueue;
- else if (retval == -ENXIO)
- goto free_mem;
- }
+ if (retval != 0)
+ goto free_workqueue;
+
/* save cx in the pci struct for later use */
pci_set_drvdata(dev, cx);
@@ -835,11 +835,11 @@ free_map:
free_mem:
release_mem_region(cx->base_addr, CX18_MEM_SIZE);
free_workqueue:
+ destroy_workqueue(cx->work_queue);
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);
@@ -918,6 +918,15 @@ int cx18_init_on_first_open(struct cx18 *cx)
return 0;
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
+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);
+}
+
+#endif
static void cx18_remove(struct pci_dev *pci_dev)
{
struct cx18 *cx = pci_get_drvdata(pci_dev);
@@ -931,11 +940,22 @@ static void cx18_remove(struct pci_dev *pci_dev)
/* Interrupts */
cx18_sw1_irq_disable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
+ cx18_sw2_irq_disable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
+
+ cx18_halt_firmware(cx);
+
+ cx18_cancel_epu_work_orders(cx);
+#else
+
+ flush_workqueue(cx->work_queue);
+
cx18_sw2_irq_disable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
cx18_halt_firmware(cx);
+#endif
- flush_scheduled_work();
+ destroy_workqueue(cx->work_queue);
cx18_streams_cleanup(cx, 1);
@@ -949,7 +969,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);
}
@@ -998,6 +1017,7 @@ static void module_cleanup(void)
continue;
kfree(cx18_cards[i]);
}
+
}
module_init(module_start);