aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-pxa/viper.c54
1 files changed, 43 insertions, 11 deletions
diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c
index d7632f63603c..4b3120dbc049 100644
--- a/arch/arm/mach-pxa/viper.c
+++ b/arch/arm/mach-pxa/viper.c
@@ -204,25 +204,54 @@ static void viper_set_core_cpu_voltage(unsigned long khz, int force)
204 204
205/* Interrupt handling */ 205/* Interrupt handling */
206static unsigned long viper_irq_enabled_mask; 206static unsigned long viper_irq_enabled_mask;
207static const int viper_isa_irqs[] = { 3, 4, 5, 6, 7, 10, 11, 12, 9, 14, 15 };
208static const int viper_isa_irq_map[] = {
209 0, /* ISA irq #0, invalid */
210 0, /* ISA irq #1, invalid */
211 0, /* ISA irq #2, invalid */
212 1 << 0, /* ISA irq #3 */
213 1 << 1, /* ISA irq #4 */
214 1 << 2, /* ISA irq #5 */
215 1 << 3, /* ISA irq #6 */
216 1 << 4, /* ISA irq #7 */
217 0, /* ISA irq #8, invalid */
218 1 << 8, /* ISA irq #9 */
219 1 << 5, /* ISA irq #10 */
220 1 << 6, /* ISA irq #11 */
221 1 << 7, /* ISA irq #12 */
222 0, /* ISA irq #13, invalid */
223 1 << 9, /* ISA irq #14 */
224 1 << 10, /* ISA irq #15 */
225};
226
227static inline int viper_irq_to_bitmask(unsigned int irq)
228{
229 return viper_isa_irq_map[irq - PXA_ISA_IRQ(0)];
230}
231
232static inline int viper_bit_to_irq(int bit)
233{
234 return viper_isa_irqs[bit] + PXA_ISA_IRQ(0);
235}
207 236
208static void viper_ack_irq(unsigned int irq) 237static void viper_ack_irq(unsigned int irq)
209{ 238{
210 int viper_irq = irq - PXA_ISA_IRQ(0); 239 int viper_irq = viper_irq_to_bitmask(irq);
211 240
212 if (viper_irq < 8) 241 if (viper_irq & 0xff)
213 VIPER_LO_IRQ_STATUS = 1 << viper_irq; 242 VIPER_LO_IRQ_STATUS = viper_irq;
214 else 243 else
215 VIPER_HI_IRQ_STATUS = 1 << (viper_irq - 8); 244 VIPER_HI_IRQ_STATUS = (viper_irq >> 8);
216} 245}
217 246
218static void viper_mask_irq(unsigned int irq) 247static void viper_mask_irq(unsigned int irq)
219{ 248{
220 viper_irq_enabled_mask &= ~(1 << (irq - PXA_ISA_IRQ(0))); 249 viper_irq_enabled_mask &= ~(viper_irq_to_bitmask(irq));
221} 250}
222 251
223static void viper_unmask_irq(unsigned int irq) 252static void viper_unmask_irq(unsigned int irq)
224{ 253{
225 viper_irq_enabled_mask |= (1 << (irq - PXA_ISA_IRQ(0))); 254 viper_irq_enabled_mask |= viper_irq_to_bitmask(irq);
226} 255}
227 256
228static inline unsigned long viper_irq_pending(void) 257static inline unsigned long viper_irq_pending(void)
@@ -237,8 +266,12 @@ static void viper_irq_handler(unsigned int irq, struct irq_desc *desc)
237 266
238 pending = viper_irq_pending(); 267 pending = viper_irq_pending();
239 do { 268 do {
269 /* we're in a chained irq handler,
270 * so ack the interrupt by hand */
271 GEDR(VIPER_CPLD_GPIO) = GPIO_bit(VIPER_CPLD_GPIO);
272
240 if (likely(pending)) { 273 if (likely(pending)) {
241 irq = PXA_ISA_IRQ(0) + __ffs(pending); 274 irq = viper_bit_to_irq(__ffs(pending));
242 generic_handle_irq(irq); 275 generic_handle_irq(irq);
243 } 276 }
244 pending = viper_irq_pending(); 277 pending = viper_irq_pending();
@@ -254,15 +287,14 @@ static struct irq_chip viper_irq_chip = {
254 287
255static void __init viper_init_irq(void) 288static void __init viper_init_irq(void)
256{ 289{
257 const int isa_irqs[] = { 3, 4, 5, 6, 7, 10, 11, 12, 9, 14, 15 }; 290 int level;
258 int irq;
259 int isa_irq; 291 int isa_irq;
260 292
261 pxa25x_init_irq(); 293 pxa25x_init_irq();
262 294
263 /* setup ISA IRQs */ 295 /* setup ISA IRQs */
264 for (irq = 0; irq < ARRAY_SIZE(isa_irqs); irq++) { 296 for (level = 0; level < ARRAY_SIZE(viper_isa_irqs); level++) {
265 isa_irq = isa_irqs[irq]; 297 isa_irq = viper_bit_to_irq(level);
266 set_irq_chip(isa_irq, &viper_irq_chip); 298 set_irq_chip(isa_irq, &viper_irq_chip);
267 set_irq_handler(isa_irq, handle_edge_irq); 299 set_irq_handler(isa_irq, handle_edge_irq);
268 set_irq_flags(isa_irq, IRQF_VALID | IRQF_PROBE); 300 set_irq_flags(isa_irq, IRQF_VALID | IRQF_PROBE);