diff options
Diffstat (limited to 'arch/arm/mach-rpc/irq.c')
-rw-r--r-- | arch/arm/mach-rpc/irq.c | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/arch/arm/mach-rpc/irq.c b/arch/arm/mach-rpc/irq.c new file mode 100644 index 000000000000..56b2716f8cf5 --- /dev/null +++ b/arch/arm/mach-rpc/irq.c | |||
@@ -0,0 +1,162 @@ | |||
1 | #include <linux/init.h> | ||
2 | #include <linux/list.h> | ||
3 | |||
4 | #include <asm/mach/irq.h> | ||
5 | #include <asm/hardware/iomd.h> | ||
6 | #include <asm/irq.h> | ||
7 | #include <asm/io.h> | ||
8 | |||
9 | static void iomd_ack_irq_a(unsigned int irq) | ||
10 | { | ||
11 | unsigned int val, mask; | ||
12 | |||
13 | mask = 1 << irq; | ||
14 | val = iomd_readb(IOMD_IRQMASKA); | ||
15 | iomd_writeb(val & ~mask, IOMD_IRQMASKA); | ||
16 | iomd_writeb(mask, IOMD_IRQCLRA); | ||
17 | } | ||
18 | |||
19 | static void iomd_mask_irq_a(unsigned int irq) | ||
20 | { | ||
21 | unsigned int val, mask; | ||
22 | |||
23 | mask = 1 << irq; | ||
24 | val = iomd_readb(IOMD_IRQMASKA); | ||
25 | iomd_writeb(val & ~mask, IOMD_IRQMASKA); | ||
26 | } | ||
27 | |||
28 | static void iomd_unmask_irq_a(unsigned int irq) | ||
29 | { | ||
30 | unsigned int val, mask; | ||
31 | |||
32 | mask = 1 << irq; | ||
33 | val = iomd_readb(IOMD_IRQMASKA); | ||
34 | iomd_writeb(val | mask, IOMD_IRQMASKA); | ||
35 | } | ||
36 | |||
37 | static struct irqchip iomd_a_chip = { | ||
38 | .ack = iomd_ack_irq_a, | ||
39 | .mask = iomd_mask_irq_a, | ||
40 | .unmask = iomd_unmask_irq_a, | ||
41 | }; | ||
42 | |||
43 | static void iomd_mask_irq_b(unsigned int irq) | ||
44 | { | ||
45 | unsigned int val, mask; | ||
46 | |||
47 | mask = 1 << (irq & 7); | ||
48 | val = iomd_readb(IOMD_IRQMASKB); | ||
49 | iomd_writeb(val & ~mask, IOMD_IRQMASKB); | ||
50 | } | ||
51 | |||
52 | static void iomd_unmask_irq_b(unsigned int irq) | ||
53 | { | ||
54 | unsigned int val, mask; | ||
55 | |||
56 | mask = 1 << (irq & 7); | ||
57 | val = iomd_readb(IOMD_IRQMASKB); | ||
58 | iomd_writeb(val | mask, IOMD_IRQMASKB); | ||
59 | } | ||
60 | |||
61 | static struct irqchip iomd_b_chip = { | ||
62 | .ack = iomd_mask_irq_b, | ||
63 | .mask = iomd_mask_irq_b, | ||
64 | .unmask = iomd_unmask_irq_b, | ||
65 | }; | ||
66 | |||
67 | static void iomd_mask_irq_dma(unsigned int irq) | ||
68 | { | ||
69 | unsigned int val, mask; | ||
70 | |||
71 | mask = 1 << (irq & 7); | ||
72 | val = iomd_readb(IOMD_DMAMASK); | ||
73 | iomd_writeb(val & ~mask, IOMD_DMAMASK); | ||
74 | } | ||
75 | |||
76 | static void iomd_unmask_irq_dma(unsigned int irq) | ||
77 | { | ||
78 | unsigned int val, mask; | ||
79 | |||
80 | mask = 1 << (irq & 7); | ||
81 | val = iomd_readb(IOMD_DMAMASK); | ||
82 | iomd_writeb(val | mask, IOMD_DMAMASK); | ||
83 | } | ||
84 | |||
85 | static struct irqchip iomd_dma_chip = { | ||
86 | .ack = iomd_mask_irq_dma, | ||
87 | .mask = iomd_mask_irq_dma, | ||
88 | .unmask = iomd_unmask_irq_dma, | ||
89 | }; | ||
90 | |||
91 | static void iomd_mask_irq_fiq(unsigned int irq) | ||
92 | { | ||
93 | unsigned int val, mask; | ||
94 | |||
95 | mask = 1 << (irq & 7); | ||
96 | val = iomd_readb(IOMD_FIQMASK); | ||
97 | iomd_writeb(val & ~mask, IOMD_FIQMASK); | ||
98 | } | ||
99 | |||
100 | static void iomd_unmask_irq_fiq(unsigned int irq) | ||
101 | { | ||
102 | unsigned int val, mask; | ||
103 | |||
104 | mask = 1 << (irq & 7); | ||
105 | val = iomd_readb(IOMD_FIQMASK); | ||
106 | iomd_writeb(val | mask, IOMD_FIQMASK); | ||
107 | } | ||
108 | |||
109 | static struct irqchip iomd_fiq_chip = { | ||
110 | .ack = iomd_mask_irq_fiq, | ||
111 | .mask = iomd_mask_irq_fiq, | ||
112 | .unmask = iomd_unmask_irq_fiq, | ||
113 | }; | ||
114 | |||
115 | void __init rpc_init_irq(void) | ||
116 | { | ||
117 | unsigned int irq, flags; | ||
118 | |||
119 | iomd_writeb(0, IOMD_IRQMASKA); | ||
120 | iomd_writeb(0, IOMD_IRQMASKB); | ||
121 | iomd_writeb(0, IOMD_FIQMASK); | ||
122 | iomd_writeb(0, IOMD_DMAMASK); | ||
123 | |||
124 | for (irq = 0; irq < NR_IRQS; irq++) { | ||
125 | flags = IRQF_VALID; | ||
126 | |||
127 | if (irq <= 6 || (irq >= 9 && irq <= 15)) | ||
128 | flags |= IRQF_PROBE; | ||
129 | |||
130 | if (irq == 21 || (irq >= 16 && irq <= 19) || | ||
131 | irq == IRQ_KEYBOARDTX) | ||
132 | flags |= IRQF_NOAUTOEN; | ||
133 | |||
134 | switch (irq) { | ||
135 | case 0 ... 7: | ||
136 | set_irq_chip(irq, &iomd_a_chip); | ||
137 | set_irq_handler(irq, do_level_IRQ); | ||
138 | set_irq_flags(irq, flags); | ||
139 | break; | ||
140 | |||
141 | case 8 ... 15: | ||
142 | set_irq_chip(irq, &iomd_b_chip); | ||
143 | set_irq_handler(irq, do_level_IRQ); | ||
144 | set_irq_flags(irq, flags); | ||
145 | break; | ||
146 | |||
147 | case 16 ... 21: | ||
148 | set_irq_chip(irq, &iomd_dma_chip); | ||
149 | set_irq_handler(irq, do_level_IRQ); | ||
150 | set_irq_flags(irq, flags); | ||
151 | break; | ||
152 | |||
153 | case 64 ... 71: | ||
154 | set_irq_chip(irq, &iomd_fiq_chip); | ||
155 | set_irq_flags(irq, IRQF_VALID); | ||
156 | break; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | init_FIQ(); | ||
161 | } | ||
162 | |||