diff options
author | Andy Walls <awalls@radix.net> | 2008-11-04 20:02:23 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-11-11 05:11:31 -0500 |
commit | 465f8a805d3796fac2b2fb0c630217f6f76e667c (patch) | |
tree | 1f0aec048a2eb5c0e54d9b134decfdfeb1e742db /drivers/media/video/cx18/cx18-irq.c | |
parent | 17ff61cb200e8ec0c8e456fbd426c1af63a6e28a (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.c | 54 |
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 | |||
35 | static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb) | 33 | static 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 | ||
112 | static void hpu_cmd(struct cx18 *cx, u32 sw1) | 110 | static 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 | |||
143 | static 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 | ||
136 | irqreturn_t cx18_irq_handler(int irq, void *dev_id) | 153 | irqreturn_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 | } |