aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/sysdev/ipic.c113
-rw-r--r--arch/powerpc/sysdev/ipic.h6
2 files changed, 45 insertions, 74 deletions
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index 7168b0349792..7274750fd9c6 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -30,11 +30,11 @@
30#include "ipic.h" 30#include "ipic.h"
31 31
32static struct ipic * primary_ipic; 32static struct ipic * primary_ipic;
33static struct irq_chip ipic_level_irq_chip, ipic_edge_irq_chip;
33static DEFINE_SPINLOCK(ipic_lock); 34static DEFINE_SPINLOCK(ipic_lock);
34 35
35static struct ipic_info ipic_info[] = { 36static struct ipic_info ipic_info[] = {
36 [1] = { 37 [1] = {
37 .pend = IPIC_SIPNR_H,
38 .mask = IPIC_SIMSR_H, 38 .mask = IPIC_SIMSR_H,
39 .prio = IPIC_SIPRR_C, 39 .prio = IPIC_SIPRR_C,
40 .force = IPIC_SIFCR_H, 40 .force = IPIC_SIFCR_H,
@@ -42,7 +42,6 @@ static struct ipic_info ipic_info[] = {
42 .prio_mask = 0, 42 .prio_mask = 0,
43 }, 43 },
44 [2] = { 44 [2] = {
45 .pend = IPIC_SIPNR_H,
46 .mask = IPIC_SIMSR_H, 45 .mask = IPIC_SIMSR_H,
47 .prio = IPIC_SIPRR_C, 46 .prio = IPIC_SIPRR_C,
48 .force = IPIC_SIFCR_H, 47 .force = IPIC_SIFCR_H,
@@ -50,7 +49,6 @@ static struct ipic_info ipic_info[] = {
50 .prio_mask = 1, 49 .prio_mask = 1,
51 }, 50 },
52 [4] = { 51 [4] = {
53 .pend = IPIC_SIPNR_H,
54 .mask = IPIC_SIMSR_H, 52 .mask = IPIC_SIMSR_H,
55 .prio = IPIC_SIPRR_C, 53 .prio = IPIC_SIPRR_C,
56 .force = IPIC_SIFCR_H, 54 .force = IPIC_SIFCR_H,
@@ -58,7 +56,6 @@ static struct ipic_info ipic_info[] = {
58 .prio_mask = 3, 56 .prio_mask = 3,
59 }, 57 },
60 [9] = { 58 [9] = {
61 .pend = IPIC_SIPNR_H,
62 .mask = IPIC_SIMSR_H, 59 .mask = IPIC_SIMSR_H,
63 .prio = IPIC_SIPRR_D, 60 .prio = IPIC_SIPRR_D,
64 .force = IPIC_SIFCR_H, 61 .force = IPIC_SIFCR_H,
@@ -66,7 +63,6 @@ static struct ipic_info ipic_info[] = {
66 .prio_mask = 0, 63 .prio_mask = 0,
67 }, 64 },
68 [10] = { 65 [10] = {
69 .pend = IPIC_SIPNR_H,
70 .mask = IPIC_SIMSR_H, 66 .mask = IPIC_SIMSR_H,
71 .prio = IPIC_SIPRR_D, 67 .prio = IPIC_SIPRR_D,
72 .force = IPIC_SIFCR_H, 68 .force = IPIC_SIFCR_H,
@@ -74,7 +70,6 @@ static struct ipic_info ipic_info[] = {
74 .prio_mask = 1, 70 .prio_mask = 1,
75 }, 71 },
76 [11] = { 72 [11] = {
77 .pend = IPIC_SIPNR_H,
78 .mask = IPIC_SIMSR_H, 73 .mask = IPIC_SIMSR_H,
79 .prio = IPIC_SIPRR_D, 74 .prio = IPIC_SIPRR_D,
80 .force = IPIC_SIFCR_H, 75 .force = IPIC_SIFCR_H,
@@ -82,7 +77,6 @@ static struct ipic_info ipic_info[] = {
82 .prio_mask = 2, 77 .prio_mask = 2,
83 }, 78 },
84 [12] = { 79 [12] = {
85 .pend = IPIC_SIPNR_H,
86 .mask = IPIC_SIMSR_H, 80 .mask = IPIC_SIMSR_H,
87 .prio = IPIC_SIPRR_D, 81 .prio = IPIC_SIPRR_D,
88 .force = IPIC_SIFCR_H, 82 .force = IPIC_SIFCR_H,
@@ -90,7 +84,6 @@ static struct ipic_info ipic_info[] = {
90 .prio_mask = 3, 84 .prio_mask = 3,
91 }, 85 },
92 [13] = { 86 [13] = {
93 .pend = IPIC_SIPNR_H,
94 .mask = IPIC_SIMSR_H, 87 .mask = IPIC_SIMSR_H,
95 .prio = IPIC_SIPRR_D, 88 .prio = IPIC_SIPRR_D,
96 .force = IPIC_SIFCR_H, 89 .force = IPIC_SIFCR_H,
@@ -98,7 +91,6 @@ static struct ipic_info ipic_info[] = {
98 .prio_mask = 4, 91 .prio_mask = 4,
99 }, 92 },
100 [14] = { 93 [14] = {
101 .pend = IPIC_SIPNR_H,
102 .mask = IPIC_SIMSR_H, 94 .mask = IPIC_SIMSR_H,
103 .prio = IPIC_SIPRR_D, 95 .prio = IPIC_SIPRR_D,
104 .force = IPIC_SIFCR_H, 96 .force = IPIC_SIFCR_H,
@@ -106,7 +98,6 @@ static struct ipic_info ipic_info[] = {
106 .prio_mask = 5, 98 .prio_mask = 5,
107 }, 99 },
108 [15] = { 100 [15] = {
109 .pend = IPIC_SIPNR_H,
110 .mask = IPIC_SIMSR_H, 101 .mask = IPIC_SIMSR_H,
111 .prio = IPIC_SIPRR_D, 102 .prio = IPIC_SIPRR_D,
112 .force = IPIC_SIFCR_H, 103 .force = IPIC_SIFCR_H,
@@ -114,7 +105,6 @@ static struct ipic_info ipic_info[] = {
114 .prio_mask = 6, 105 .prio_mask = 6,
115 }, 106 },
116 [16] = { 107 [16] = {
117 .pend = IPIC_SIPNR_H,
118 .mask = IPIC_SIMSR_H, 108 .mask = IPIC_SIMSR_H,
119 .prio = IPIC_SIPRR_D, 109 .prio = IPIC_SIPRR_D,
120 .force = IPIC_SIFCR_H, 110 .force = IPIC_SIFCR_H,
@@ -122,7 +112,7 @@ static struct ipic_info ipic_info[] = {
122 .prio_mask = 7, 112 .prio_mask = 7,
123 }, 113 },
124 [17] = { 114 [17] = {
125 .pend = IPIC_SEPNR, 115 .ack = IPIC_SEPNR,
126 .mask = IPIC_SEMSR, 116 .mask = IPIC_SEMSR,
127 .prio = IPIC_SMPRR_A, 117 .prio = IPIC_SMPRR_A,
128 .force = IPIC_SEFCR, 118 .force = IPIC_SEFCR,
@@ -130,7 +120,7 @@ static struct ipic_info ipic_info[] = {
130 .prio_mask = 5, 120 .prio_mask = 5,
131 }, 121 },
132 [18] = { 122 [18] = {
133 .pend = IPIC_SEPNR, 123 .ack = IPIC_SEPNR,
134 .mask = IPIC_SEMSR, 124 .mask = IPIC_SEMSR,
135 .prio = IPIC_SMPRR_A, 125 .prio = IPIC_SMPRR_A,
136 .force = IPIC_SEFCR, 126 .force = IPIC_SEFCR,
@@ -138,7 +128,7 @@ static struct ipic_info ipic_info[] = {
138 .prio_mask = 6, 128 .prio_mask = 6,
139 }, 129 },
140 [19] = { 130 [19] = {
141 .pend = IPIC_SEPNR, 131 .ack = IPIC_SEPNR,
142 .mask = IPIC_SEMSR, 132 .mask = IPIC_SEMSR,
143 .prio = IPIC_SMPRR_A, 133 .prio = IPIC_SMPRR_A,
144 .force = IPIC_SEFCR, 134 .force = IPIC_SEFCR,
@@ -146,7 +136,7 @@ static struct ipic_info ipic_info[] = {
146 .prio_mask = 7, 136 .prio_mask = 7,
147 }, 137 },
148 [20] = { 138 [20] = {
149 .pend = IPIC_SEPNR, 139 .ack = IPIC_SEPNR,
150 .mask = IPIC_SEMSR, 140 .mask = IPIC_SEMSR,
151 .prio = IPIC_SMPRR_B, 141 .prio = IPIC_SMPRR_B,
152 .force = IPIC_SEFCR, 142 .force = IPIC_SEFCR,
@@ -154,7 +144,7 @@ static struct ipic_info ipic_info[] = {
154 .prio_mask = 4, 144 .prio_mask = 4,
155 }, 145 },
156 [21] = { 146 [21] = {
157 .pend = IPIC_SEPNR, 147 .ack = IPIC_SEPNR,
158 .mask = IPIC_SEMSR, 148 .mask = IPIC_SEMSR,
159 .prio = IPIC_SMPRR_B, 149 .prio = IPIC_SMPRR_B,
160 .force = IPIC_SEFCR, 150 .force = IPIC_SEFCR,
@@ -162,7 +152,7 @@ static struct ipic_info ipic_info[] = {
162 .prio_mask = 5, 152 .prio_mask = 5,
163 }, 153 },
164 [22] = { 154 [22] = {
165 .pend = IPIC_SEPNR, 155 .ack = IPIC_SEPNR,
166 .mask = IPIC_SEMSR, 156 .mask = IPIC_SEMSR,
167 .prio = IPIC_SMPRR_B, 157 .prio = IPIC_SMPRR_B,
168 .force = IPIC_SEFCR, 158 .force = IPIC_SEFCR,
@@ -170,7 +160,7 @@ static struct ipic_info ipic_info[] = {
170 .prio_mask = 6, 160 .prio_mask = 6,
171 }, 161 },
172 [23] = { 162 [23] = {
173 .pend = IPIC_SEPNR, 163 .ack = IPIC_SEPNR,
174 .mask = IPIC_SEMSR, 164 .mask = IPIC_SEMSR,
175 .prio = IPIC_SMPRR_B, 165 .prio = IPIC_SMPRR_B,
176 .force = IPIC_SEFCR, 166 .force = IPIC_SEFCR,
@@ -178,7 +168,6 @@ static struct ipic_info ipic_info[] = {
178 .prio_mask = 7, 168 .prio_mask = 7,
179 }, 169 },
180 [32] = { 170 [32] = {
181 .pend = IPIC_SIPNR_H,
182 .mask = IPIC_SIMSR_H, 171 .mask = IPIC_SIMSR_H,
183 .prio = IPIC_SIPRR_A, 172 .prio = IPIC_SIPRR_A,
184 .force = IPIC_SIFCR_H, 173 .force = IPIC_SIFCR_H,
@@ -186,7 +175,6 @@ static struct ipic_info ipic_info[] = {
186 .prio_mask = 0, 175 .prio_mask = 0,
187 }, 176 },
188 [33] = { 177 [33] = {
189 .pend = IPIC_SIPNR_H,
190 .mask = IPIC_SIMSR_H, 178 .mask = IPIC_SIMSR_H,
191 .prio = IPIC_SIPRR_A, 179 .prio = IPIC_SIPRR_A,
192 .force = IPIC_SIFCR_H, 180 .force = IPIC_SIFCR_H,
@@ -194,7 +182,6 @@ static struct ipic_info ipic_info[] = {
194 .prio_mask = 1, 182 .prio_mask = 1,
195 }, 183 },
196 [34] = { 184 [34] = {
197 .pend = IPIC_SIPNR_H,
198 .mask = IPIC_SIMSR_H, 185 .mask = IPIC_SIMSR_H,
199 .prio = IPIC_SIPRR_A, 186 .prio = IPIC_SIPRR_A,
200 .force = IPIC_SIFCR_H, 187 .force = IPIC_SIFCR_H,
@@ -202,7 +189,6 @@ static struct ipic_info ipic_info[] = {
202 .prio_mask = 2, 189 .prio_mask = 2,
203 }, 190 },
204 [35] = { 191 [35] = {
205 .pend = IPIC_SIPNR_H,
206 .mask = IPIC_SIMSR_H, 192 .mask = IPIC_SIMSR_H,
207 .prio = IPIC_SIPRR_A, 193 .prio = IPIC_SIPRR_A,
208 .force = IPIC_SIFCR_H, 194 .force = IPIC_SIFCR_H,
@@ -210,7 +196,6 @@ static struct ipic_info ipic_info[] = {
210 .prio_mask = 3, 196 .prio_mask = 3,
211 }, 197 },
212 [36] = { 198 [36] = {
213 .pend = IPIC_SIPNR_H,
214 .mask = IPIC_SIMSR_H, 199 .mask = IPIC_SIMSR_H,
215 .prio = IPIC_SIPRR_A, 200 .prio = IPIC_SIPRR_A,
216 .force = IPIC_SIFCR_H, 201 .force = IPIC_SIFCR_H,
@@ -218,7 +203,6 @@ static struct ipic_info ipic_info[] = {
218 .prio_mask = 4, 203 .prio_mask = 4,
219 }, 204 },
220 [37] = { 205 [37] = {
221 .pend = IPIC_SIPNR_H,
222 .mask = IPIC_SIMSR_H, 206 .mask = IPIC_SIMSR_H,
223 .prio = IPIC_SIPRR_A, 207 .prio = IPIC_SIPRR_A,
224 .force = IPIC_SIFCR_H, 208 .force = IPIC_SIFCR_H,
@@ -226,7 +210,6 @@ static struct ipic_info ipic_info[] = {
226 .prio_mask = 5, 210 .prio_mask = 5,
227 }, 211 },
228 [38] = { 212 [38] = {
229 .pend = IPIC_SIPNR_H,
230 .mask = IPIC_SIMSR_H, 213 .mask = IPIC_SIMSR_H,
231 .prio = IPIC_SIPRR_A, 214 .prio = IPIC_SIPRR_A,
232 .force = IPIC_SIFCR_H, 215 .force = IPIC_SIFCR_H,
@@ -234,7 +217,6 @@ static struct ipic_info ipic_info[] = {
234 .prio_mask = 6, 217 .prio_mask = 6,
235 }, 218 },
236 [39] = { 219 [39] = {
237 .pend = IPIC_SIPNR_H,
238 .mask = IPIC_SIMSR_H, 220 .mask = IPIC_SIMSR_H,
239 .prio = IPIC_SIPRR_A, 221 .prio = IPIC_SIPRR_A,
240 .force = IPIC_SIFCR_H, 222 .force = IPIC_SIFCR_H,
@@ -242,7 +224,6 @@ static struct ipic_info ipic_info[] = {
242 .prio_mask = 7, 224 .prio_mask = 7,
243 }, 225 },
244 [42] = { 226 [42] = {
245 .pend = IPIC_SIPNR_H,
246 .mask = IPIC_SIMSR_H, 227 .mask = IPIC_SIMSR_H,
247 .prio = IPIC_SIPRR_B, 228 .prio = IPIC_SIPRR_B,
248 .force = IPIC_SIFCR_H, 229 .force = IPIC_SIFCR_H,
@@ -250,7 +231,6 @@ static struct ipic_info ipic_info[] = {
250 .prio_mask = 2, 231 .prio_mask = 2,
251 }, 232 },
252 [44] = { 233 [44] = {
253 .pend = IPIC_SIPNR_H,
254 .mask = IPIC_SIMSR_H, 234 .mask = IPIC_SIMSR_H,
255 .prio = IPIC_SIPRR_B, 235 .prio = IPIC_SIPRR_B,
256 .force = IPIC_SIFCR_H, 236 .force = IPIC_SIFCR_H,
@@ -258,7 +238,6 @@ static struct ipic_info ipic_info[] = {
258 .prio_mask = 4, 238 .prio_mask = 4,
259 }, 239 },
260 [45] = { 240 [45] = {
261 .pend = IPIC_SIPNR_H,
262 .mask = IPIC_SIMSR_H, 241 .mask = IPIC_SIMSR_H,
263 .prio = IPIC_SIPRR_B, 242 .prio = IPIC_SIPRR_B,
264 .force = IPIC_SIFCR_H, 243 .force = IPIC_SIFCR_H,
@@ -266,7 +245,6 @@ static struct ipic_info ipic_info[] = {
266 .prio_mask = 5, 245 .prio_mask = 5,
267 }, 246 },
268 [46] = { 247 [46] = {
269 .pend = IPIC_SIPNR_H,
270 .mask = IPIC_SIMSR_H, 248 .mask = IPIC_SIMSR_H,
271 .prio = IPIC_SIPRR_B, 249 .prio = IPIC_SIPRR_B,
272 .force = IPIC_SIFCR_H, 250 .force = IPIC_SIFCR_H,
@@ -274,7 +252,6 @@ static struct ipic_info ipic_info[] = {
274 .prio_mask = 6, 252 .prio_mask = 6,
275 }, 253 },
276 [47] = { 254 [47] = {
277 .pend = IPIC_SIPNR_H,
278 .mask = IPIC_SIMSR_H, 255 .mask = IPIC_SIMSR_H,
279 .prio = IPIC_SIPRR_B, 256 .prio = IPIC_SIPRR_B,
280 .force = IPIC_SIFCR_H, 257 .force = IPIC_SIFCR_H,
@@ -282,7 +259,6 @@ static struct ipic_info ipic_info[] = {
282 .prio_mask = 7, 259 .prio_mask = 7,
283 }, 260 },
284 [48] = { 261 [48] = {
285 .pend = IPIC_SEPNR,
286 .mask = IPIC_SEMSR, 262 .mask = IPIC_SEMSR,
287 .prio = IPIC_SMPRR_A, 263 .prio = IPIC_SMPRR_A,
288 .force = IPIC_SEFCR, 264 .force = IPIC_SEFCR,
@@ -290,7 +266,6 @@ static struct ipic_info ipic_info[] = {
290 .prio_mask = 4, 266 .prio_mask = 4,
291 }, 267 },
292 [64] = { 268 [64] = {
293 .pend = IPIC_SIPNR_L,
294 .mask = IPIC_SIMSR_L, 269 .mask = IPIC_SIMSR_L,
295 .prio = IPIC_SMPRR_A, 270 .prio = IPIC_SMPRR_A,
296 .force = IPIC_SIFCR_L, 271 .force = IPIC_SIFCR_L,
@@ -298,7 +273,6 @@ static struct ipic_info ipic_info[] = {
298 .prio_mask = 0, 273 .prio_mask = 0,
299 }, 274 },
300 [65] = { 275 [65] = {
301 .pend = IPIC_SIPNR_L,
302 .mask = IPIC_SIMSR_L, 276 .mask = IPIC_SIMSR_L,
303 .prio = IPIC_SMPRR_A, 277 .prio = IPIC_SMPRR_A,
304 .force = IPIC_SIFCR_L, 278 .force = IPIC_SIFCR_L,
@@ -306,7 +280,6 @@ static struct ipic_info ipic_info[] = {
306 .prio_mask = 1, 280 .prio_mask = 1,
307 }, 281 },
308 [66] = { 282 [66] = {
309 .pend = IPIC_SIPNR_L,
310 .mask = IPIC_SIMSR_L, 283 .mask = IPIC_SIMSR_L,
311 .prio = IPIC_SMPRR_A, 284 .prio = IPIC_SMPRR_A,
312 .force = IPIC_SIFCR_L, 285 .force = IPIC_SIFCR_L,
@@ -314,7 +287,6 @@ static struct ipic_info ipic_info[] = {
314 .prio_mask = 2, 287 .prio_mask = 2,
315 }, 288 },
316 [67] = { 289 [67] = {
317 .pend = IPIC_SIPNR_L,
318 .mask = IPIC_SIMSR_L, 290 .mask = IPIC_SIMSR_L,
319 .prio = IPIC_SMPRR_A, 291 .prio = IPIC_SMPRR_A,
320 .force = IPIC_SIFCR_L, 292 .force = IPIC_SIFCR_L,
@@ -322,7 +294,6 @@ static struct ipic_info ipic_info[] = {
322 .prio_mask = 3, 294 .prio_mask = 3,
323 }, 295 },
324 [68] = { 296 [68] = {
325 .pend = IPIC_SIPNR_L,
326 .mask = IPIC_SIMSR_L, 297 .mask = IPIC_SIMSR_L,
327 .prio = IPIC_SMPRR_B, 298 .prio = IPIC_SMPRR_B,
328 .force = IPIC_SIFCR_L, 299 .force = IPIC_SIFCR_L,
@@ -330,7 +301,6 @@ static struct ipic_info ipic_info[] = {
330 .prio_mask = 0, 301 .prio_mask = 0,
331 }, 302 },
332 [69] = { 303 [69] = {
333 .pend = IPIC_SIPNR_L,
334 .mask = IPIC_SIMSR_L, 304 .mask = IPIC_SIMSR_L,
335 .prio = IPIC_SMPRR_B, 305 .prio = IPIC_SMPRR_B,
336 .force = IPIC_SIFCR_L, 306 .force = IPIC_SIFCR_L,
@@ -338,7 +308,6 @@ static struct ipic_info ipic_info[] = {
338 .prio_mask = 1, 308 .prio_mask = 1,
339 }, 309 },
340 [70] = { 310 [70] = {
341 .pend = IPIC_SIPNR_L,
342 .mask = IPIC_SIMSR_L, 311 .mask = IPIC_SIMSR_L,
343 .prio = IPIC_SMPRR_B, 312 .prio = IPIC_SMPRR_B,
344 .force = IPIC_SIFCR_L, 313 .force = IPIC_SIFCR_L,
@@ -346,7 +315,6 @@ static struct ipic_info ipic_info[] = {
346 .prio_mask = 2, 315 .prio_mask = 2,
347 }, 316 },
348 [71] = { 317 [71] = {
349 .pend = IPIC_SIPNR_L,
350 .mask = IPIC_SIMSR_L, 318 .mask = IPIC_SIMSR_L,
351 .prio = IPIC_SMPRR_B, 319 .prio = IPIC_SMPRR_B,
352 .force = IPIC_SIFCR_L, 320 .force = IPIC_SIFCR_L,
@@ -354,133 +322,114 @@ static struct ipic_info ipic_info[] = {
354 .prio_mask = 3, 322 .prio_mask = 3,
355 }, 323 },
356 [72] = { 324 [72] = {
357 .pend = IPIC_SIPNR_L,
358 .mask = IPIC_SIMSR_L, 325 .mask = IPIC_SIMSR_L,
359 .prio = 0, 326 .prio = 0,
360 .force = IPIC_SIFCR_L, 327 .force = IPIC_SIFCR_L,
361 .bit = 8, 328 .bit = 8,
362 }, 329 },
363 [73] = { 330 [73] = {
364 .pend = IPIC_SIPNR_L,
365 .mask = IPIC_SIMSR_L, 331 .mask = IPIC_SIMSR_L,
366 .prio = 0, 332 .prio = 0,
367 .force = IPIC_SIFCR_L, 333 .force = IPIC_SIFCR_L,
368 .bit = 9, 334 .bit = 9,
369 }, 335 },
370 [74] = { 336 [74] = {
371 .pend = IPIC_SIPNR_L,
372 .mask = IPIC_SIMSR_L, 337 .mask = IPIC_SIMSR_L,
373 .prio = 0, 338 .prio = 0,
374 .force = IPIC_SIFCR_L, 339 .force = IPIC_SIFCR_L,
375 .bit = 10, 340 .bit = 10,
376 }, 341 },
377 [75] = { 342 [75] = {
378 .pend = IPIC_SIPNR_L,
379 .mask = IPIC_SIMSR_L, 343 .mask = IPIC_SIMSR_L,
380 .prio = 0, 344 .prio = 0,
381 .force = IPIC_SIFCR_L, 345 .force = IPIC_SIFCR_L,
382 .bit = 11, 346 .bit = 11,
383 }, 347 },
384 [76] = { 348 [76] = {
385 .pend = IPIC_SIPNR_L,
386 .mask = IPIC_SIMSR_L, 349 .mask = IPIC_SIMSR_L,
387 .prio = 0, 350 .prio = 0,
388 .force = IPIC_SIFCR_L, 351 .force = IPIC_SIFCR_L,
389 .bit = 12, 352 .bit = 12,
390 }, 353 },
391 [77] = { 354 [77] = {
392 .pend = IPIC_SIPNR_L,
393 .mask = IPIC_SIMSR_L, 355 .mask = IPIC_SIMSR_L,
394 .prio = 0, 356 .prio = 0,
395 .force = IPIC_SIFCR_L, 357 .force = IPIC_SIFCR_L,
396 .bit = 13, 358 .bit = 13,
397 }, 359 },
398 [78] = { 360 [78] = {
399 .pend = IPIC_SIPNR_L,
400 .mask = IPIC_SIMSR_L, 361 .mask = IPIC_SIMSR_L,
401 .prio = 0, 362 .prio = 0,
402 .force = IPIC_SIFCR_L, 363 .force = IPIC_SIFCR_L,
403 .bit = 14, 364 .bit = 14,
404 }, 365 },
405 [79] = { 366 [79] = {
406 .pend = IPIC_SIPNR_L,
407 .mask = IPIC_SIMSR_L, 367 .mask = IPIC_SIMSR_L,
408 .prio = 0, 368 .prio = 0,
409 .force = IPIC_SIFCR_L, 369 .force = IPIC_SIFCR_L,
410 .bit = 15, 370 .bit = 15,
411 }, 371 },
412 [80] = { 372 [80] = {
413 .pend = IPIC_SIPNR_L,
414 .mask = IPIC_SIMSR_L, 373 .mask = IPIC_SIMSR_L,
415 .prio = 0, 374 .prio = 0,
416 .force = IPIC_SIFCR_L, 375 .force = IPIC_SIFCR_L,
417 .bit = 16, 376 .bit = 16,
418 }, 377 },
419 [81] = { 378 [81] = {
420 .pend = IPIC_SIPNR_L,
421 .mask = IPIC_SIMSR_L, 379 .mask = IPIC_SIMSR_L,
422 .prio = 0, 380 .prio = 0,
423 .force = IPIC_SIFCR_L, 381 .force = IPIC_SIFCR_L,
424 .bit = 17, 382 .bit = 17,
425 }, 383 },
426 [82] = { 384 [82] = {
427 .pend = IPIC_SIPNR_L,
428 .mask = IPIC_SIMSR_L, 385 .mask = IPIC_SIMSR_L,
429 .prio = 0, 386 .prio = 0,
430 .force = IPIC_SIFCR_L, 387 .force = IPIC_SIFCR_L,
431 .bit = 18, 388 .bit = 18,
432 }, 389 },
433 [84] = { 390 [84] = {
434 .pend = IPIC_SIPNR_L,
435 .mask = IPIC_SIMSR_L, 391 .mask = IPIC_SIMSR_L,
436 .prio = 0, 392 .prio = 0,
437 .force = IPIC_SIFCR_L, 393 .force = IPIC_SIFCR_L,
438 .bit = 20, 394 .bit = 20,
439 }, 395 },
440 [85] = { 396 [85] = {
441 .pend = IPIC_SIPNR_L,
442 .mask = IPIC_SIMSR_L, 397 .mask = IPIC_SIMSR_L,
443 .prio = 0, 398 .prio = 0,
444 .force = IPIC_SIFCR_L, 399 .force = IPIC_SIFCR_L,
445 .bit = 21, 400 .bit = 21,
446 }, 401 },
447 [86] = { 402 [86] = {
448 .pend = IPIC_SIPNR_L,
449 .mask = IPIC_SIMSR_L, 403 .mask = IPIC_SIMSR_L,
450 .prio = 0, 404 .prio = 0,
451 .force = IPIC_SIFCR_L, 405 .force = IPIC_SIFCR_L,
452 .bit = 22, 406 .bit = 22,
453 }, 407 },
454 [87] = { 408 [87] = {
455 .pend = IPIC_SIPNR_L,
456 .mask = IPIC_SIMSR_L, 409 .mask = IPIC_SIMSR_L,
457 .prio = 0, 410 .prio = 0,
458 .force = IPIC_SIFCR_L, 411 .force = IPIC_SIFCR_L,
459 .bit = 23, 412 .bit = 23,
460 }, 413 },
461 [88] = { 414 [88] = {
462 .pend = IPIC_SIPNR_L,
463 .mask = IPIC_SIMSR_L, 415 .mask = IPIC_SIMSR_L,
464 .prio = 0, 416 .prio = 0,
465 .force = IPIC_SIFCR_L, 417 .force = IPIC_SIFCR_L,
466 .bit = 24, 418 .bit = 24,
467 }, 419 },
468 [89] = { 420 [89] = {
469 .pend = IPIC_SIPNR_L,
470 .mask = IPIC_SIMSR_L, 421 .mask = IPIC_SIMSR_L,
471 .prio = 0, 422 .prio = 0,
472 .force = IPIC_SIFCR_L, 423 .force = IPIC_SIFCR_L,
473 .bit = 25, 424 .bit = 25,
474 }, 425 },
475 [90] = { 426 [90] = {
476 .pend = IPIC_SIPNR_L,
477 .mask = IPIC_SIMSR_L, 427 .mask = IPIC_SIMSR_L,
478 .prio = 0, 428 .prio = 0,
479 .force = IPIC_SIFCR_L, 429 .force = IPIC_SIFCR_L,
480 .bit = 26, 430 .bit = 26,
481 }, 431 },
482 [91] = { 432 [91] = {
483 .pend = IPIC_SIPNR_L,
484 .mask = IPIC_SIMSR_L, 433 .mask = IPIC_SIMSR_L,
485 .prio = 0, 434 .prio = 0,
486 .force = IPIC_SIFCR_L, 435 .force = IPIC_SIFCR_L,
@@ -534,6 +483,10 @@ static void ipic_mask_irq(unsigned int virq)
534 temp &= ~(1 << (31 - ipic_info[src].bit)); 483 temp &= ~(1 << (31 - ipic_info[src].bit));
535 ipic_write(ipic->regs, ipic_info[src].mask, temp); 484 ipic_write(ipic->regs, ipic_info[src].mask, temp);
536 485
486 /* mb() can't guarantee that masking is finished. But it does finish
487 * for nearly all cases. */
488 mb();
489
537 spin_unlock_irqrestore(&ipic_lock, flags); 490 spin_unlock_irqrestore(&ipic_lock, flags);
538} 491}
539 492
@@ -546,9 +499,13 @@ static void ipic_ack_irq(unsigned int virq)
546 499
547 spin_lock_irqsave(&ipic_lock, flags); 500 spin_lock_irqsave(&ipic_lock, flags);
548 501
549 temp = ipic_read(ipic->regs, ipic_info[src].pend); 502 temp = ipic_read(ipic->regs, ipic_info[src].ack);
550 temp |= (1 << (31 - ipic_info[src].bit)); 503 temp |= (1 << (31 - ipic_info[src].bit));
551 ipic_write(ipic->regs, ipic_info[src].pend, temp); 504 ipic_write(ipic->regs, ipic_info[src].ack, temp);
505
506 /* mb() can't guarantee that ack is finished. But it does finish
507 * for nearly all cases. */
508 mb();
552 509
553 spin_unlock_irqrestore(&ipic_lock, flags); 510 spin_unlock_irqrestore(&ipic_lock, flags);
554} 511}
@@ -566,9 +523,13 @@ static void ipic_mask_irq_and_ack(unsigned int virq)
566 temp &= ~(1 << (31 - ipic_info[src].bit)); 523 temp &= ~(1 << (31 - ipic_info[src].bit));
567 ipic_write(ipic->regs, ipic_info[src].mask, temp); 524 ipic_write(ipic->regs, ipic_info[src].mask, temp);
568 525
569 temp = ipic_read(ipic->regs, ipic_info[src].pend); 526 temp = ipic_read(ipic->regs, ipic_info[src].ack);
570 temp |= (1 << (31 - ipic_info[src].bit)); 527 temp |= (1 << (31 - ipic_info[src].bit));
571 ipic_write(ipic->regs, ipic_info[src].pend, temp); 528 ipic_write(ipic->regs, ipic_info[src].ack, temp);
529
530 /* mb() can't guarantee that ack is finished. But it does finish
531 * for nearly all cases. */
532 mb();
572 533
573 spin_unlock_irqrestore(&ipic_lock, flags); 534 spin_unlock_irqrestore(&ipic_lock, flags);
574} 535}
@@ -590,14 +551,22 @@ static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
590 flow_type); 551 flow_type);
591 return -EINVAL; 552 return -EINVAL;
592 } 553 }
554 /* ipic supports only edge mode on external interrupts */
555 if ((flow_type & IRQ_TYPE_EDGE_FALLING) && !ipic_info[src].ack) {
556 printk(KERN_ERR "ipic: edge sense not supported on internal "
557 "interrupts\n");
558 return -EINVAL;
559 }
593 560
594 desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); 561 desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
595 desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; 562 desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
596 if (flow_type & IRQ_TYPE_LEVEL_LOW) { 563 if (flow_type & IRQ_TYPE_LEVEL_LOW) {
597 desc->status |= IRQ_LEVEL; 564 desc->status |= IRQ_LEVEL;
598 desc->handle_irq = handle_level_irq; 565 desc->handle_irq = handle_level_irq;
566 desc->chip = &ipic_level_irq_chip;
599 } else { 567 } else {
600 desc->handle_irq = handle_edge_irq; 568 desc->handle_irq = handle_edge_irq;
569 desc->chip = &ipic_edge_irq_chip;
601 } 570 }
602 571
603 /* only EXT IRQ senses are programmable on ipic 572 /* only EXT IRQ senses are programmable on ipic
@@ -622,7 +591,16 @@ static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
622 return 0; 591 return 0;
623} 592}
624 593
625static struct irq_chip ipic_irq_chip = { 594/* level interrupts and edge interrupts have different ack operations */
595static struct irq_chip ipic_level_irq_chip = {
596 .typename = " IPIC ",
597 .unmask = ipic_unmask_irq,
598 .mask = ipic_mask_irq,
599 .mask_ack = ipic_mask_irq,
600 .set_type = ipic_set_irq_type,
601};
602
603static struct irq_chip ipic_edge_irq_chip = {
626 .typename = " IPIC ", 604 .typename = " IPIC ",
627 .unmask = ipic_unmask_irq, 605 .unmask = ipic_unmask_irq,
628 .mask = ipic_mask_irq, 606 .mask = ipic_mask_irq,
@@ -641,13 +619,9 @@ static int ipic_host_map(struct irq_host *h, unsigned int virq,
641 irq_hw_number_t hw) 619 irq_hw_number_t hw)
642{ 620{
643 struct ipic *ipic = h->host_data; 621 struct ipic *ipic = h->host_data;
644 struct irq_chip *chip;
645
646 /* Default chip */
647 chip = &ipic->hc_irq;
648 622
649 set_irq_chip_data(virq, ipic); 623 set_irq_chip_data(virq, ipic);
650 set_irq_chip_and_handler(virq, chip, handle_level_irq); 624 set_irq_chip_and_handler(virq, &ipic_level_irq_chip, handle_level_irq);
651 625
652 /* Set default irq type */ 626 /* Set default irq type */
653 set_irq_type(virq, IRQ_TYPE_NONE); 627 set_irq_type(virq, IRQ_TYPE_NONE);
@@ -706,7 +680,6 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
706 ipic->regs = ioremap(res.start, res.end - res.start + 1); 680 ipic->regs = ioremap(res.start, res.end - res.start + 1);
707 681
708 ipic->irqhost->host_data = ipic; 682 ipic->irqhost->host_data = ipic;
709 ipic->hc_irq = ipic_irq_chip;
710 683
711 /* init hw */ 684 /* init hw */
712 ipic_write(ipic->regs, IPIC_SICNR, 0x0); 685 ipic_write(ipic->regs, IPIC_SICNR, 0x0);
diff --git a/arch/powerpc/sysdev/ipic.h b/arch/powerpc/sysdev/ipic.h
index 1158b8f5cb20..9391c57b0c51 100644
--- a/arch/powerpc/sysdev/ipic.h
+++ b/arch/powerpc/sysdev/ipic.h
@@ -44,13 +44,11 @@ struct ipic {
44 44
45 /* The remapper for this IPIC */ 45 /* The remapper for this IPIC */
46 struct irq_host *irqhost; 46 struct irq_host *irqhost;
47
48 /* The "linux" controller struct */
49 struct irq_chip hc_irq;
50}; 47};
51 48
52struct ipic_info { 49struct ipic_info {
53 u8 pend; /* pending register offset from base */ 50 u8 ack; /* pending register offset from base if the irq
51 supports ack operation */
54 u8 mask; /* mask register offset from base */ 52 u8 mask; /* mask register offset from base */
55 u8 prio; /* priority register offset from base */ 53 u8 prio; /* priority register offset from base */
56 u8 force; /* force register offset from base */ 54 u8 force; /* force register offset from base */