summaryrefslogtreecommitdiff
path: root/linux/drivers/media
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2008-11-09 16:14:07 -0500
committerAndy Walls <awalls@radix.net>2008-11-09 16:14:07 -0500
commit4c6f942c4bda31271b632907d23021b22fa1d5cf (patch)
treebc184927fd85498afe45699b9318a0342d3e9806 /linux/drivers/media
parent359020f9d46c383a26678ad896a1b7911b6284f7 (diff)
downloadmediapointer-dvb-s2-4c6f942c4bda31271b632907d23021b22fa1d5cf.tar.gz
mediapointer-dvb-s2-4c6f942c4bda31271b632907d23021b22fa1d5cf.tar.bz2
cx18: Prevent CX23418 from clearing it's outgoing ack interrupts to driver
From: Andy Walls <awalls@radix.net> When the CX23418 CPU unit sent out an ack interrupt to the linux driver, it also received that interrupt and cleared the flag before the linux driver could see what the interrupt was for. This fix prevents the CPU from receiving an IRQ for it's own outgoing ack's to the linux driver. This fix is critical now that the linux driver doesn't poll but relies on these ack interrupts. Priority: high Signed-off-by: Andy Walls <awalls@radix.net>
Diffstat (limited to 'linux/drivers/media')
-rw-r--r--linux/drivers/media/video/cx18/cx18-firmware.c11
-rw-r--r--linux/drivers/media/video/cx18/cx18-io.c7
-rw-r--r--linux/drivers/media/video/cx18/cx18-io.h1
-rw-r--r--linux/drivers/media/video/cx18/cx18-irq.h1
4 files changed, 20 insertions, 0 deletions
diff --git a/linux/drivers/media/video/cx18/cx18-firmware.c b/linux/drivers/media/video/cx18/cx18-firmware.c
index ab02da727..06f5563d6 100644
--- a/linux/drivers/media/video/cx18/cx18-firmware.c
+++ b/linux/drivers/media/video/cx18/cx18-firmware.c
@@ -380,6 +380,17 @@ int cx18_firmware_init(struct cx18 *cx)
if (sz <= 0)
return -EIO;
}
+
+ /*
+ * The CPU firmware apparently sets up to receive an interrupt for it's
+ * outgoing IRQ_CPU_TO_EPU_ACK to us (*boggle*). We get an interrupt
+ * when it sends us an ack, but by the time we process it, that flag in
+ * the SW2 status register has been cleared by the CPU firmware.
+ * We'll prevent that not so useful behavior by clearing the CPU's
+ * interrupt enables for Ack IRQ's we want to process.
+ */
+ cx18_sw2_irq_disable_cpu(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
+
/* initialize GPIO */
cx18_write_reg_expect(cx, 0x14001400, 0xc78110, 0x00001400, 0x14001400);
return 0;
diff --git a/linux/drivers/media/video/cx18/cx18-io.c b/linux/drivers/media/video/cx18/cx18-io.c
index 48a8adc83..3c6485fce 100644
--- a/linux/drivers/media/video/cx18/cx18-io.c
+++ b/linux/drivers/media/video/cx18/cx18-io.c
@@ -262,6 +262,13 @@ void cx18_sw2_irq_disable(struct cx18 *cx, u32 val)
cx18_write_reg(cx, r & ~val, SW2_INT_ENABLE_PCI);
}
+void cx18_sw2_irq_disable_cpu(struct cx18 *cx, u32 val)
+{
+ u32 r;
+ r = cx18_read_reg(cx, SW2_INT_ENABLE_CPU);
+ cx18_write_reg(cx, r & ~val, SW2_INT_ENABLE_CPU);
+}
+
void cx18_setup_page(struct cx18 *cx, u32 addr)
{
u32 val;
diff --git a/linux/drivers/media/video/cx18/cx18-io.h b/linux/drivers/media/video/cx18/cx18-io.h
index cb695a596..4486b73fa 100644
--- a/linux/drivers/media/video/cx18/cx18-io.h
+++ b/linux/drivers/media/video/cx18/cx18-io.h
@@ -390,6 +390,7 @@ void cx18_sw1_irq_enable(struct cx18 *cx, u32 val);
void cx18_sw1_irq_disable(struct cx18 *cx, u32 val);
void cx18_sw2_irq_enable(struct cx18 *cx, u32 val);
void cx18_sw2_irq_disable(struct cx18 *cx, u32 val);
+void cx18_sw2_irq_disable_cpu(struct cx18 *cx, u32 val);
void cx18_setup_page(struct cx18 *cx, u32 addr);
#endif /* CX18_IO_H */
diff --git a/linux/drivers/media/video/cx18/cx18-irq.h b/linux/drivers/media/video/cx18/cx18-irq.h
index d1d9d1967..6472e42c6 100644
--- a/linux/drivers/media/video/cx18/cx18-irq.h
+++ b/linux/drivers/media/video/cx18/cx18-irq.h
@@ -28,6 +28,7 @@
#define SW1_INT_ENABLE_PCI 0xc7311c
#define SW2_INT_SET 0xc73140
#define SW2_INT_STATUS 0xc73144
+#define SW2_INT_ENABLE_CPU 0xc73158
#define SW2_INT_ENABLE_PCI 0xc7315c
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)