aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx18/cx18-irq.c
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2008-11-04 20:02:23 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-11-11 05:11:31 -0500
commit465f8a805d3796fac2b2fb0c630217f6f76e667c (patch)
tree1f0aec048a2eb5c0e54d9b134decfdfeb1e742db /drivers/media/video/cx18/cx18-irq.c
parent17ff61cb200e8ec0c8e456fbd426c1af63a6e28a (diff)
V4L/DVB (9515): cx18: Use correct Mailbox IRQ Ack values and misc IRQ handling cleanup
cx18: Use correct Mailbox IRQ Ack values and misc IRQ handling cleanup. The SCB field definitions for Ack IRQ's for mailboxes were inconsistent with the bitmasks being loaded into those SCB fields and the SW2 Ack IRQ handling logic. Renamed fields in SCB to make things consistent and did misc IRQ handling cleanups: removing legacy ivtv dma_reg_lock, HPU IRQ flags, etc. Signed-off-by: Andy Walls <awalls@radix.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx18/cx18-irq.c')
-rw-r--r--drivers/media/video/cx18/cx18-irq.c54
1 files changed, 29 insertions, 25 deletions
diff --git a/drivers/media/video/cx18/cx18-irq.c b/drivers/media/video/cx18/cx18-irq.c
index a366259bbb7b..c306e142c1c3 100644
--- a/drivers/media/video/cx18/cx18-irq.c
+++ b/drivers/media/video/cx18/cx18-irq.c
@@ -30,8 +30,6 @@
30#include "cx18-vbi.h" 30#include "cx18-vbi.h"
31#include "cx18-scb.h" 31#include "cx18-scb.h"
32 32
33#define DMA_MAGIC_COOKIE 0x000001fe
34
35static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb) 33static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb)
36{ 34{
37 u32 handle = mb->args[0]; 35 u32 handle = mb->args[0];
@@ -109,7 +107,7 @@ static void epu_debug(struct cx18 *cx, struct cx18_mailbox *mb)
109 CX18_INFO("FW version: %s\n", p - 1); 107 CX18_INFO("FW version: %s\n", p - 1);
110} 108}
111 109
112static void hpu_cmd(struct cx18 *cx, u32 sw1) 110static void epu_cmd(struct cx18 *cx, u32 sw1)
113{ 111{
114 struct cx18_mailbox mb; 112 struct cx18_mailbox mb;
115 113
@@ -125,12 +123,31 @@ static void hpu_cmd(struct cx18 *cx, u32 sw1)
125 epu_debug(cx, &mb); 123 epu_debug(cx, &mb);
126 break; 124 break;
127 default: 125 default:
128 CX18_WARN("Unexpected mailbox command %08x\n", mb.cmd); 126 CX18_WARN("Unknown CPU_TO_EPU mailbox command %#08x\n",
127 mb.cmd);
129 break; 128 break;
130 } 129 }
131 } 130 }
132 if (sw1 & (IRQ_APU_TO_EPU | IRQ_HPU_TO_EPU)) 131
133 CX18_WARN("Unexpected interrupt %08x\n", sw1); 132 if (sw1 & IRQ_APU_TO_EPU) {
133 cx18_memcpy_fromio(cx, &mb, &cx->scb->apu2epu_mb, sizeof(mb));
134 CX18_WARN("Unknown APU_TO_EPU mailbox command %#08x\n", mb.cmd);
135 }
136
137 if (sw1 & IRQ_HPU_TO_EPU) {
138 cx18_memcpy_fromio(cx, &mb, &cx->scb->hpu2epu_mb, sizeof(mb));
139 CX18_WARN("Unknown HPU_TO_EPU mailbox command %#08x\n", mb.cmd);
140 }
141}
142
143static void xpu_ack(struct cx18 *cx, u32 sw2)
144{
145 if (sw2 & IRQ_CPU_TO_EPU_ACK)
146 wake_up(&cx->mb_cpu_waitq);
147 if (sw2 & IRQ_APU_TO_EPU_ACK)
148 wake_up(&cx->mb_apu_waitq);
149 if (sw2 & IRQ_HPU_TO_EPU_ACK)
150 wake_up(&cx->mb_hpu_waitq);
134} 151}
135 152
136irqreturn_t cx18_irq_handler(int irq, void *dev_id) 153irqreturn_t cx18_irq_handler(int irq, void *dev_id)
@@ -140,11 +157,9 @@ irqreturn_t cx18_irq_handler(int irq, void *dev_id)
140 u32 sw2, sw2_mask; 157 u32 sw2, sw2_mask;
141 u32 hw2, hw2_mask; 158 u32 hw2, hw2_mask;
142 159
143 spin_lock(&cx->dma_reg_lock); 160 sw1_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI);
144
145 sw1_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU;
146 sw1 = cx18_read_reg(cx, SW1_INT_STATUS) & sw1_mask; 161 sw1 = cx18_read_reg(cx, SW1_INT_STATUS) & sw1_mask;
147 sw2_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU_ACK; 162 sw2_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI);
148 sw2 = cx18_read_reg(cx, SW2_INT_STATUS) & sw2_mask; 163 sw2 = cx18_read_reg(cx, SW2_INT_STATUS) & sw2_mask;
149 hw2_mask = cx18_read_reg(cx, HW2_INT_MASK5_PCI); 164 hw2_mask = cx18_read_reg(cx, HW2_INT_MASK5_PCI);
150 hw2 = cx18_read_reg(cx, HW2_INT_CLR_STATUS) & hw2_mask; 165 hw2 = cx18_read_reg(cx, HW2_INT_CLR_STATUS) & hw2_mask;
@@ -160,26 +175,15 @@ irqreturn_t cx18_irq_handler(int irq, void *dev_id)
160 CX18_DEBUG_HI_IRQ("SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2); 175 CX18_DEBUG_HI_IRQ("SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2);
161 176
162 /* To do: interrupt-based I2C handling 177 /* To do: interrupt-based I2C handling
163 if (hw2 & 0x00c00000) { 178 if (hw2 & (HW2_I2C1_INT|HW2_I2C2_INT)) {
164 } 179 }
165 */ 180 */
166 181
167 if (sw2) { 182 if (sw2)
168 if (sw2 & (cx18_readl(cx, &cx->scb->cpu2hpu_irq_ack) | 183 xpu_ack(cx, sw2);
169 cx18_readl(cx, &cx->scb->cpu2epu_irq_ack)))
170 wake_up(&cx->mb_cpu_waitq);
171 if (sw2 & (cx18_readl(cx, &cx->scb->apu2hpu_irq_ack) |
172 cx18_readl(cx, &cx->scb->apu2epu_irq_ack)))
173 wake_up(&cx->mb_apu_waitq);
174 if (sw2 & cx18_readl(cx, &cx->scb->epu2hpu_irq_ack))
175 wake_up(&cx->mb_epu_waitq);
176 if (sw2 & cx18_readl(cx, &cx->scb->hpu2epu_irq_ack))
177 wake_up(&cx->mb_hpu_waitq);
178 }
179 184
180 if (sw1) 185 if (sw1)
181 hpu_cmd(cx, sw1); 186 epu_cmd(cx, sw1);
182 spin_unlock(&cx->dma_reg_lock);
183 187
184 return (sw1 || sw2 || hw2) ? IRQ_HANDLED : IRQ_NONE; 188 return (sw1 || sw2 || hw2) ? IRQ_HANDLED : IRQ_NONE;
185} 189}