diff options
Diffstat (limited to 'arch/arm/mach-iop33x/irq.c')
-rw-r--r-- | arch/arm/mach-iop33x/irq.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/arch/arm/mach-iop33x/irq.c b/arch/arm/mach-iop33x/irq.c new file mode 100644 index 000000000000..63304b3d0d76 --- /dev/null +++ b/arch/arm/mach-iop33x/irq.c | |||
@@ -0,0 +1,127 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-iop33x/irq.c | ||
3 | * | ||
4 | * Generic IOP331 IRQ handling functionality | ||
5 | * | ||
6 | * Author: Dave Jiang <dave.jiang@intel.com> | ||
7 | * Copyright (C) 2003 Intel Corp. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/init.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/list.h> | ||
17 | #include <asm/mach/irq.h> | ||
18 | #include <asm/irq.h> | ||
19 | #include <asm/hardware.h> | ||
20 | #include <asm/mach-types.h> | ||
21 | |||
22 | static u32 iop33x_mask0; | ||
23 | static u32 iop33x_mask1; | ||
24 | |||
25 | static inline void intctl0_write(u32 val) | ||
26 | { | ||
27 | iop3xx_cp6_enable(); | ||
28 | asm volatile("mcr p6, 0, %0, c0, c0, 0" : : "r" (val)); | ||
29 | iop3xx_cp6_disable(); | ||
30 | } | ||
31 | |||
32 | static inline void intctl1_write(u32 val) | ||
33 | { | ||
34 | iop3xx_cp6_enable(); | ||
35 | asm volatile("mcr p6, 0, %0, c1, c0, 0" : : "r" (val)); | ||
36 | iop3xx_cp6_disable(); | ||
37 | } | ||
38 | |||
39 | static inline void intstr0_write(u32 val) | ||
40 | { | ||
41 | iop3xx_cp6_enable(); | ||
42 | asm volatile("mcr p6, 0, %0, c2, c0, 0" : : "r" (val)); | ||
43 | iop3xx_cp6_disable(); | ||
44 | } | ||
45 | |||
46 | static inline void intstr1_write(u32 val) | ||
47 | { | ||
48 | iop3xx_cp6_enable(); | ||
49 | asm volatile("mcr p6, 0, %0, c3, c0, 0" : : "r" (val)); | ||
50 | iop3xx_cp6_disable(); | ||
51 | } | ||
52 | |||
53 | static inline void intbase_write(u32 val) | ||
54 | { | ||
55 | iop3xx_cp6_enable(); | ||
56 | asm volatile("mcr p6, 0, %0, c12, c0, 0" : : "r" (val)); | ||
57 | iop3xx_cp6_disable(); | ||
58 | } | ||
59 | |||
60 | static inline void intsize_write(u32 val) | ||
61 | { | ||
62 | iop3xx_cp6_enable(); | ||
63 | asm volatile("mcr p6, 0, %0, c13, c0, 0" : : "r" (val)); | ||
64 | iop3xx_cp6_disable(); | ||
65 | } | ||
66 | |||
67 | static void | ||
68 | iop33x_irq_mask1 (unsigned int irq) | ||
69 | { | ||
70 | iop33x_mask0 &= ~(1 << irq); | ||
71 | intctl0_write(iop33x_mask0); | ||
72 | } | ||
73 | |||
74 | static void | ||
75 | iop33x_irq_mask2 (unsigned int irq) | ||
76 | { | ||
77 | iop33x_mask1 &= ~(1 << (irq - 32)); | ||
78 | intctl1_write(iop33x_mask1); | ||
79 | } | ||
80 | |||
81 | static void | ||
82 | iop33x_irq_unmask1(unsigned int irq) | ||
83 | { | ||
84 | iop33x_mask0 |= 1 << irq; | ||
85 | intctl0_write(iop33x_mask0); | ||
86 | } | ||
87 | |||
88 | static void | ||
89 | iop33x_irq_unmask2(unsigned int irq) | ||
90 | { | ||
91 | iop33x_mask1 |= (1 << (irq - 32)); | ||
92 | intctl1_write(iop33x_mask1); | ||
93 | } | ||
94 | |||
95 | struct irq_chip iop33x_irqchip1 = { | ||
96 | .name = "IOP33x-1", | ||
97 | .ack = iop33x_irq_mask1, | ||
98 | .mask = iop33x_irq_mask1, | ||
99 | .unmask = iop33x_irq_unmask1, | ||
100 | }; | ||
101 | |||
102 | struct irq_chip iop33x_irqchip2 = { | ||
103 | .name = "IOP33x-2", | ||
104 | .ack = iop33x_irq_mask2, | ||
105 | .mask = iop33x_irq_mask2, | ||
106 | .unmask = iop33x_irq_unmask2, | ||
107 | }; | ||
108 | |||
109 | void __init iop33x_init_irq(void) | ||
110 | { | ||
111 | int i; | ||
112 | |||
113 | intctl0_write(0); | ||
114 | intctl1_write(0); | ||
115 | intstr0_write(0); | ||
116 | intstr1_write(0); | ||
117 | intbase_write(0); | ||
118 | intsize_write(1); | ||
119 | if (machine_is_iq80331()) | ||
120 | *IOP3XX_PCIIRSR = 0x0f; | ||
121 | |||
122 | for (i = 0; i < NR_IRQS; i++) { | ||
123 | set_irq_chip(i, (i < 32) ? &iop33x_irqchip1 : &iop33x_irqchip2); | ||
124 | set_irq_handler(i, do_level_IRQ); | ||
125 | set_irq_flags(i, IRQF_VALID | IRQF_PROBE); | ||
126 | } | ||
127 | } | ||