aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/ipic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/sysdev/ipic.c')
-rw-r--r--arch/powerpc/sysdev/ipic.c287
1 files changed, 228 insertions, 59 deletions
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index e898ff4d2b97..ae0dbf4c1d66 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -30,11 +30,67 @@
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[] = {
37 [1] = {
38 .mask = IPIC_SIMSR_H,
39 .prio = IPIC_SIPRR_C,
40 .force = IPIC_SIFCR_H,
41 .bit = 16,
42 .prio_mask = 0,
43 },
44 [2] = {
45 .mask = IPIC_SIMSR_H,
46 .prio = IPIC_SIPRR_C,
47 .force = IPIC_SIFCR_H,
48 .bit = 17,
49 .prio_mask = 1,
50 },
51 [3] = {
52 .mask = IPIC_SIMSR_H,
53 .prio = IPIC_SIPRR_C,
54 .force = IPIC_SIFCR_H,
55 .bit = 18,
56 .prio_mask = 2,
57 },
58 [4] = {
59 .mask = IPIC_SIMSR_H,
60 .prio = IPIC_SIPRR_C,
61 .force = IPIC_SIFCR_H,
62 .bit = 19,
63 .prio_mask = 3,
64 },
65 [5] = {
66 .mask = IPIC_SIMSR_H,
67 .prio = IPIC_SIPRR_C,
68 .force = IPIC_SIFCR_H,
69 .bit = 20,
70 .prio_mask = 4,
71 },
72 [6] = {
73 .mask = IPIC_SIMSR_H,
74 .prio = IPIC_SIPRR_C,
75 .force = IPIC_SIFCR_H,
76 .bit = 21,
77 .prio_mask = 5,
78 },
79 [7] = {
80 .mask = IPIC_SIMSR_H,
81 .prio = IPIC_SIPRR_C,
82 .force = IPIC_SIFCR_H,
83 .bit = 22,
84 .prio_mask = 6,
85 },
86 [8] = {
87 .mask = IPIC_SIMSR_H,
88 .prio = IPIC_SIPRR_C,
89 .force = IPIC_SIFCR_H,
90 .bit = 23,
91 .prio_mask = 7,
92 },
36 [9] = { 93 [9] = {
37 .pend = IPIC_SIPNR_H,
38 .mask = IPIC_SIMSR_H, 94 .mask = IPIC_SIMSR_H,
39 .prio = IPIC_SIPRR_D, 95 .prio = IPIC_SIPRR_D,
40 .force = IPIC_SIFCR_H, 96 .force = IPIC_SIFCR_H,
@@ -42,7 +98,6 @@ static struct ipic_info ipic_info[] = {
42 .prio_mask = 0, 98 .prio_mask = 0,
43 }, 99 },
44 [10] = { 100 [10] = {
45 .pend = IPIC_SIPNR_H,
46 .mask = IPIC_SIMSR_H, 101 .mask = IPIC_SIMSR_H,
47 .prio = IPIC_SIPRR_D, 102 .prio = IPIC_SIPRR_D,
48 .force = IPIC_SIFCR_H, 103 .force = IPIC_SIFCR_H,
@@ -50,15 +105,27 @@ static struct ipic_info ipic_info[] = {
50 .prio_mask = 1, 105 .prio_mask = 1,
51 }, 106 },
52 [11] = { 107 [11] = {
53 .pend = IPIC_SIPNR_H,
54 .mask = IPIC_SIMSR_H, 108 .mask = IPIC_SIMSR_H,
55 .prio = IPIC_SIPRR_D, 109 .prio = IPIC_SIPRR_D,
56 .force = IPIC_SIFCR_H, 110 .force = IPIC_SIFCR_H,
57 .bit = 26, 111 .bit = 26,
58 .prio_mask = 2, 112 .prio_mask = 2,
59 }, 113 },
114 [12] = {
115 .mask = IPIC_SIMSR_H,
116 .prio = IPIC_SIPRR_D,
117 .force = IPIC_SIFCR_H,
118 .bit = 27,
119 .prio_mask = 3,
120 },
121 [13] = {
122 .mask = IPIC_SIMSR_H,
123 .prio = IPIC_SIPRR_D,
124 .force = IPIC_SIFCR_H,
125 .bit = 28,
126 .prio_mask = 4,
127 },
60 [14] = { 128 [14] = {
61 .pend = IPIC_SIPNR_H,
62 .mask = IPIC_SIMSR_H, 129 .mask = IPIC_SIMSR_H,
63 .prio = IPIC_SIPRR_D, 130 .prio = IPIC_SIPRR_D,
64 .force = IPIC_SIFCR_H, 131 .force = IPIC_SIFCR_H,
@@ -66,7 +133,6 @@ static struct ipic_info ipic_info[] = {
66 .prio_mask = 5, 133 .prio_mask = 5,
67 }, 134 },
68 [15] = { 135 [15] = {
69 .pend = IPIC_SIPNR_H,
70 .mask = IPIC_SIMSR_H, 136 .mask = IPIC_SIMSR_H,
71 .prio = IPIC_SIPRR_D, 137 .prio = IPIC_SIPRR_D,
72 .force = IPIC_SIFCR_H, 138 .force = IPIC_SIFCR_H,
@@ -74,7 +140,6 @@ static struct ipic_info ipic_info[] = {
74 .prio_mask = 6, 140 .prio_mask = 6,
75 }, 141 },
76 [16] = { 142 [16] = {
77 .pend = IPIC_SIPNR_H,
78 .mask = IPIC_SIMSR_H, 143 .mask = IPIC_SIMSR_H,
79 .prio = IPIC_SIPRR_D, 144 .prio = IPIC_SIPRR_D,
80 .force = IPIC_SIFCR_H, 145 .force = IPIC_SIFCR_H,
@@ -82,7 +147,7 @@ static struct ipic_info ipic_info[] = {
82 .prio_mask = 7, 147 .prio_mask = 7,
83 }, 148 },
84 [17] = { 149 [17] = {
85 .pend = IPIC_SEPNR, 150 .ack = IPIC_SEPNR,
86 .mask = IPIC_SEMSR, 151 .mask = IPIC_SEMSR,
87 .prio = IPIC_SMPRR_A, 152 .prio = IPIC_SMPRR_A,
88 .force = IPIC_SEFCR, 153 .force = IPIC_SEFCR,
@@ -90,7 +155,7 @@ static struct ipic_info ipic_info[] = {
90 .prio_mask = 5, 155 .prio_mask = 5,
91 }, 156 },
92 [18] = { 157 [18] = {
93 .pend = IPIC_SEPNR, 158 .ack = IPIC_SEPNR,
94 .mask = IPIC_SEMSR, 159 .mask = IPIC_SEMSR,
95 .prio = IPIC_SMPRR_A, 160 .prio = IPIC_SMPRR_A,
96 .force = IPIC_SEFCR, 161 .force = IPIC_SEFCR,
@@ -98,7 +163,7 @@ static struct ipic_info ipic_info[] = {
98 .prio_mask = 6, 163 .prio_mask = 6,
99 }, 164 },
100 [19] = { 165 [19] = {
101 .pend = IPIC_SEPNR, 166 .ack = IPIC_SEPNR,
102 .mask = IPIC_SEMSR, 167 .mask = IPIC_SEMSR,
103 .prio = IPIC_SMPRR_A, 168 .prio = IPIC_SMPRR_A,
104 .force = IPIC_SEFCR, 169 .force = IPIC_SEFCR,
@@ -106,7 +171,7 @@ static struct ipic_info ipic_info[] = {
106 .prio_mask = 7, 171 .prio_mask = 7,
107 }, 172 },
108 [20] = { 173 [20] = {
109 .pend = IPIC_SEPNR, 174 .ack = IPIC_SEPNR,
110 .mask = IPIC_SEMSR, 175 .mask = IPIC_SEMSR,
111 .prio = IPIC_SMPRR_B, 176 .prio = IPIC_SMPRR_B,
112 .force = IPIC_SEFCR, 177 .force = IPIC_SEFCR,
@@ -114,7 +179,7 @@ static struct ipic_info ipic_info[] = {
114 .prio_mask = 4, 179 .prio_mask = 4,
115 }, 180 },
116 [21] = { 181 [21] = {
117 .pend = IPIC_SEPNR, 182 .ack = IPIC_SEPNR,
118 .mask = IPIC_SEMSR, 183 .mask = IPIC_SEMSR,
119 .prio = IPIC_SMPRR_B, 184 .prio = IPIC_SMPRR_B,
120 .force = IPIC_SEFCR, 185 .force = IPIC_SEFCR,
@@ -122,7 +187,7 @@ static struct ipic_info ipic_info[] = {
122 .prio_mask = 5, 187 .prio_mask = 5,
123 }, 188 },
124 [22] = { 189 [22] = {
125 .pend = IPIC_SEPNR, 190 .ack = IPIC_SEPNR,
126 .mask = IPIC_SEMSR, 191 .mask = IPIC_SEMSR,
127 .prio = IPIC_SMPRR_B, 192 .prio = IPIC_SMPRR_B,
128 .force = IPIC_SEFCR, 193 .force = IPIC_SEFCR,
@@ -130,7 +195,7 @@ static struct ipic_info ipic_info[] = {
130 .prio_mask = 6, 195 .prio_mask = 6,
131 }, 196 },
132 [23] = { 197 [23] = {
133 .pend = IPIC_SEPNR, 198 .ack = IPIC_SEPNR,
134 .mask = IPIC_SEMSR, 199 .mask = IPIC_SEMSR,
135 .prio = IPIC_SMPRR_B, 200 .prio = IPIC_SMPRR_B,
136 .force = IPIC_SEFCR, 201 .force = IPIC_SEFCR,
@@ -138,7 +203,6 @@ static struct ipic_info ipic_info[] = {
138 .prio_mask = 7, 203 .prio_mask = 7,
139 }, 204 },
140 [32] = { 205 [32] = {
141 .pend = IPIC_SIPNR_H,
142 .mask = IPIC_SIMSR_H, 206 .mask = IPIC_SIMSR_H,
143 .prio = IPIC_SIPRR_A, 207 .prio = IPIC_SIPRR_A,
144 .force = IPIC_SIFCR_H, 208 .force = IPIC_SIFCR_H,
@@ -146,7 +210,6 @@ static struct ipic_info ipic_info[] = {
146 .prio_mask = 0, 210 .prio_mask = 0,
147 }, 211 },
148 [33] = { 212 [33] = {
149 .pend = IPIC_SIPNR_H,
150 .mask = IPIC_SIMSR_H, 213 .mask = IPIC_SIMSR_H,
151 .prio = IPIC_SIPRR_A, 214 .prio = IPIC_SIPRR_A,
152 .force = IPIC_SIFCR_H, 215 .force = IPIC_SIFCR_H,
@@ -154,7 +217,6 @@ static struct ipic_info ipic_info[] = {
154 .prio_mask = 1, 217 .prio_mask = 1,
155 }, 218 },
156 [34] = { 219 [34] = {
157 .pend = IPIC_SIPNR_H,
158 .mask = IPIC_SIMSR_H, 220 .mask = IPIC_SIMSR_H,
159 .prio = IPIC_SIPRR_A, 221 .prio = IPIC_SIPRR_A,
160 .force = IPIC_SIFCR_H, 222 .force = IPIC_SIFCR_H,
@@ -162,7 +224,6 @@ static struct ipic_info ipic_info[] = {
162 .prio_mask = 2, 224 .prio_mask = 2,
163 }, 225 },
164 [35] = { 226 [35] = {
165 .pend = IPIC_SIPNR_H,
166 .mask = IPIC_SIMSR_H, 227 .mask = IPIC_SIMSR_H,
167 .prio = IPIC_SIPRR_A, 228 .prio = IPIC_SIPRR_A,
168 .force = IPIC_SIFCR_H, 229 .force = IPIC_SIFCR_H,
@@ -170,7 +231,6 @@ static struct ipic_info ipic_info[] = {
170 .prio_mask = 3, 231 .prio_mask = 3,
171 }, 232 },
172 [36] = { 233 [36] = {
173 .pend = IPIC_SIPNR_H,
174 .mask = IPIC_SIMSR_H, 234 .mask = IPIC_SIMSR_H,
175 .prio = IPIC_SIPRR_A, 235 .prio = IPIC_SIPRR_A,
176 .force = IPIC_SIFCR_H, 236 .force = IPIC_SIFCR_H,
@@ -178,7 +238,6 @@ static struct ipic_info ipic_info[] = {
178 .prio_mask = 4, 238 .prio_mask = 4,
179 }, 239 },
180 [37] = { 240 [37] = {
181 .pend = IPIC_SIPNR_H,
182 .mask = IPIC_SIMSR_H, 241 .mask = IPIC_SIMSR_H,
183 .prio = IPIC_SIPRR_A, 242 .prio = IPIC_SIPRR_A,
184 .force = IPIC_SIFCR_H, 243 .force = IPIC_SIFCR_H,
@@ -186,7 +245,6 @@ static struct ipic_info ipic_info[] = {
186 .prio_mask = 5, 245 .prio_mask = 5,
187 }, 246 },
188 [38] = { 247 [38] = {
189 .pend = IPIC_SIPNR_H,
190 .mask = IPIC_SIMSR_H, 248 .mask = IPIC_SIMSR_H,
191 .prio = IPIC_SIPRR_A, 249 .prio = IPIC_SIPRR_A,
192 .force = IPIC_SIFCR_H, 250 .force = IPIC_SIFCR_H,
@@ -194,15 +252,69 @@ static struct ipic_info ipic_info[] = {
194 .prio_mask = 6, 252 .prio_mask = 6,
195 }, 253 },
196 [39] = { 254 [39] = {
197 .pend = IPIC_SIPNR_H,
198 .mask = IPIC_SIMSR_H, 255 .mask = IPIC_SIMSR_H,
199 .prio = IPIC_SIPRR_A, 256 .prio = IPIC_SIPRR_A,
200 .force = IPIC_SIFCR_H, 257 .force = IPIC_SIFCR_H,
201 .bit = 7, 258 .bit = 7,
202 .prio_mask = 7, 259 .prio_mask = 7,
203 }, 260 },
261 [40] = {
262 .mask = IPIC_SIMSR_H,
263 .prio = IPIC_SIPRR_B,
264 .force = IPIC_SIFCR_H,
265 .bit = 8,
266 .prio_mask = 0,
267 },
268 [41] = {
269 .mask = IPIC_SIMSR_H,
270 .prio = IPIC_SIPRR_B,
271 .force = IPIC_SIFCR_H,
272 .bit = 9,
273 .prio_mask = 1,
274 },
275 [42] = {
276 .mask = IPIC_SIMSR_H,
277 .prio = IPIC_SIPRR_B,
278 .force = IPIC_SIFCR_H,
279 .bit = 10,
280 .prio_mask = 2,
281 },
282 [43] = {
283 .mask = IPIC_SIMSR_H,
284 .prio = IPIC_SIPRR_B,
285 .force = IPIC_SIFCR_H,
286 .bit = 11,
287 .prio_mask = 3,
288 },
289 [44] = {
290 .mask = IPIC_SIMSR_H,
291 .prio = IPIC_SIPRR_B,
292 .force = IPIC_SIFCR_H,
293 .bit = 12,
294 .prio_mask = 4,
295 },
296 [45] = {
297 .mask = IPIC_SIMSR_H,
298 .prio = IPIC_SIPRR_B,
299 .force = IPIC_SIFCR_H,
300 .bit = 13,
301 .prio_mask = 5,
302 },
303 [46] = {
304 .mask = IPIC_SIMSR_H,
305 .prio = IPIC_SIPRR_B,
306 .force = IPIC_SIFCR_H,
307 .bit = 14,
308 .prio_mask = 6,
309 },
310 [47] = {
311 .mask = IPIC_SIMSR_H,
312 .prio = IPIC_SIPRR_B,
313 .force = IPIC_SIFCR_H,
314 .bit = 15,
315 .prio_mask = 7,
316 },
204 [48] = { 317 [48] = {
205 .pend = IPIC_SEPNR,
206 .mask = IPIC_SEMSR, 318 .mask = IPIC_SEMSR,
207 .prio = IPIC_SMPRR_A, 319 .prio = IPIC_SMPRR_A,
208 .force = IPIC_SEFCR, 320 .force = IPIC_SEFCR,
@@ -210,7 +322,6 @@ static struct ipic_info ipic_info[] = {
210 .prio_mask = 4, 322 .prio_mask = 4,
211 }, 323 },
212 [64] = { 324 [64] = {
213 .pend = IPIC_SIPNR_L,
214 .mask = IPIC_SIMSR_L, 325 .mask = IPIC_SIMSR_L,
215 .prio = IPIC_SMPRR_A, 326 .prio = IPIC_SMPRR_A,
216 .force = IPIC_SIFCR_L, 327 .force = IPIC_SIFCR_L,
@@ -218,7 +329,6 @@ static struct ipic_info ipic_info[] = {
218 .prio_mask = 0, 329 .prio_mask = 0,
219 }, 330 },
220 [65] = { 331 [65] = {
221 .pend = IPIC_SIPNR_L,
222 .mask = IPIC_SIMSR_L, 332 .mask = IPIC_SIMSR_L,
223 .prio = IPIC_SMPRR_A, 333 .prio = IPIC_SMPRR_A,
224 .force = IPIC_SIFCR_L, 334 .force = IPIC_SIFCR_L,
@@ -226,7 +336,6 @@ static struct ipic_info ipic_info[] = {
226 .prio_mask = 1, 336 .prio_mask = 1,
227 }, 337 },
228 [66] = { 338 [66] = {
229 .pend = IPIC_SIPNR_L,
230 .mask = IPIC_SIMSR_L, 339 .mask = IPIC_SIMSR_L,
231 .prio = IPIC_SMPRR_A, 340 .prio = IPIC_SMPRR_A,
232 .force = IPIC_SIFCR_L, 341 .force = IPIC_SIFCR_L,
@@ -234,7 +343,6 @@ static struct ipic_info ipic_info[] = {
234 .prio_mask = 2, 343 .prio_mask = 2,
235 }, 344 },
236 [67] = { 345 [67] = {
237 .pend = IPIC_SIPNR_L,
238 .mask = IPIC_SIMSR_L, 346 .mask = IPIC_SIMSR_L,
239 .prio = IPIC_SMPRR_A, 347 .prio = IPIC_SMPRR_A,
240 .force = IPIC_SIFCR_L, 348 .force = IPIC_SIFCR_L,
@@ -242,7 +350,6 @@ static struct ipic_info ipic_info[] = {
242 .prio_mask = 3, 350 .prio_mask = 3,
243 }, 351 },
244 [68] = { 352 [68] = {
245 .pend = IPIC_SIPNR_L,
246 .mask = IPIC_SIMSR_L, 353 .mask = IPIC_SIMSR_L,
247 .prio = IPIC_SMPRR_B, 354 .prio = IPIC_SMPRR_B,
248 .force = IPIC_SIFCR_L, 355 .force = IPIC_SIFCR_L,
@@ -250,7 +357,6 @@ static struct ipic_info ipic_info[] = {
250 .prio_mask = 0, 357 .prio_mask = 0,
251 }, 358 },
252 [69] = { 359 [69] = {
253 .pend = IPIC_SIPNR_L,
254 .mask = IPIC_SIMSR_L, 360 .mask = IPIC_SIMSR_L,
255 .prio = IPIC_SMPRR_B, 361 .prio = IPIC_SMPRR_B,
256 .force = IPIC_SIFCR_L, 362 .force = IPIC_SIFCR_L,
@@ -258,7 +364,6 @@ static struct ipic_info ipic_info[] = {
258 .prio_mask = 1, 364 .prio_mask = 1,
259 }, 365 },
260 [70] = { 366 [70] = {
261 .pend = IPIC_SIPNR_L,
262 .mask = IPIC_SIMSR_L, 367 .mask = IPIC_SIMSR_L,
263 .prio = IPIC_SMPRR_B, 368 .prio = IPIC_SMPRR_B,
264 .force = IPIC_SIFCR_L, 369 .force = IPIC_SIFCR_L,
@@ -266,7 +371,6 @@ static struct ipic_info ipic_info[] = {
266 .prio_mask = 2, 371 .prio_mask = 2,
267 }, 372 },
268 [71] = { 373 [71] = {
269 .pend = IPIC_SIPNR_L,
270 .mask = IPIC_SIMSR_L, 374 .mask = IPIC_SIMSR_L,
271 .prio = IPIC_SMPRR_B, 375 .prio = IPIC_SMPRR_B,
272 .force = IPIC_SIFCR_L, 376 .force = IPIC_SIFCR_L,
@@ -274,96 +378,131 @@ static struct ipic_info ipic_info[] = {
274 .prio_mask = 3, 378 .prio_mask = 3,
275 }, 379 },
276 [72] = { 380 [72] = {
277 .pend = IPIC_SIPNR_L,
278 .mask = IPIC_SIMSR_L, 381 .mask = IPIC_SIMSR_L,
279 .prio = 0, 382 .prio = 0,
280 .force = IPIC_SIFCR_L, 383 .force = IPIC_SIFCR_L,
281 .bit = 8, 384 .bit = 8,
282 }, 385 },
283 [73] = { 386 [73] = {
284 .pend = IPIC_SIPNR_L,
285 .mask = IPIC_SIMSR_L, 387 .mask = IPIC_SIMSR_L,
286 .prio = 0, 388 .prio = 0,
287 .force = IPIC_SIFCR_L, 389 .force = IPIC_SIFCR_L,
288 .bit = 9, 390 .bit = 9,
289 }, 391 },
290 [74] = { 392 [74] = {
291 .pend = IPIC_SIPNR_L,
292 .mask = IPIC_SIMSR_L, 393 .mask = IPIC_SIMSR_L,
293 .prio = 0, 394 .prio = 0,
294 .force = IPIC_SIFCR_L, 395 .force = IPIC_SIFCR_L,
295 .bit = 10, 396 .bit = 10,
296 }, 397 },
297 [75] = { 398 [75] = {
298 .pend = IPIC_SIPNR_L,
299 .mask = IPIC_SIMSR_L, 399 .mask = IPIC_SIMSR_L,
300 .prio = 0, 400 .prio = 0,
301 .force = IPIC_SIFCR_L, 401 .force = IPIC_SIFCR_L,
302 .bit = 11, 402 .bit = 11,
303 }, 403 },
304 [76] = { 404 [76] = {
305 .pend = IPIC_SIPNR_L,
306 .mask = IPIC_SIMSR_L, 405 .mask = IPIC_SIMSR_L,
307 .prio = 0, 406 .prio = 0,
308 .force = IPIC_SIFCR_L, 407 .force = IPIC_SIFCR_L,
309 .bit = 12, 408 .bit = 12,
310 }, 409 },
311 [77] = { 410 [77] = {
312 .pend = IPIC_SIPNR_L,
313 .mask = IPIC_SIMSR_L, 411 .mask = IPIC_SIMSR_L,
314 .prio = 0, 412 .prio = 0,
315 .force = IPIC_SIFCR_L, 413 .force = IPIC_SIFCR_L,
316 .bit = 13, 414 .bit = 13,
317 }, 415 },
318 [78] = { 416 [78] = {
319 .pend = IPIC_SIPNR_L,
320 .mask = IPIC_SIMSR_L, 417 .mask = IPIC_SIMSR_L,
321 .prio = 0, 418 .prio = 0,
322 .force = IPIC_SIFCR_L, 419 .force = IPIC_SIFCR_L,
323 .bit = 14, 420 .bit = 14,
324 }, 421 },
325 [79] = { 422 [79] = {
326 .pend = IPIC_SIPNR_L,
327 .mask = IPIC_SIMSR_L, 423 .mask = IPIC_SIMSR_L,
328 .prio = 0, 424 .prio = 0,
329 .force = IPIC_SIFCR_L, 425 .force = IPIC_SIFCR_L,
330 .bit = 15, 426 .bit = 15,
331 }, 427 },
332 [80] = { 428 [80] = {
333 .pend = IPIC_SIPNR_L,
334 .mask = IPIC_SIMSR_L, 429 .mask = IPIC_SIMSR_L,
335 .prio = 0, 430 .prio = 0,
336 .force = IPIC_SIFCR_L, 431 .force = IPIC_SIFCR_L,
337 .bit = 16, 432 .bit = 16,
338 }, 433 },
434 [81] = {
435 .mask = IPIC_SIMSR_L,
436 .prio = 0,
437 .force = IPIC_SIFCR_L,
438 .bit = 17,
439 },
440 [82] = {
441 .mask = IPIC_SIMSR_L,
442 .prio = 0,
443 .force = IPIC_SIFCR_L,
444 .bit = 18,
445 },
446 [83] = {
447 .mask = IPIC_SIMSR_L,
448 .prio = 0,
449 .force = IPIC_SIFCR_L,
450 .bit = 19,
451 },
339 [84] = { 452 [84] = {
340 .pend = IPIC_SIPNR_L,
341 .mask = IPIC_SIMSR_L, 453 .mask = IPIC_SIMSR_L,
342 .prio = 0, 454 .prio = 0,
343 .force = IPIC_SIFCR_L, 455 .force = IPIC_SIFCR_L,
344 .bit = 20, 456 .bit = 20,
345 }, 457 },
346 [85] = { 458 [85] = {
347 .pend = IPIC_SIPNR_L,
348 .mask = IPIC_SIMSR_L, 459 .mask = IPIC_SIMSR_L,
349 .prio = 0, 460 .prio = 0,
350 .force = IPIC_SIFCR_L, 461 .force = IPIC_SIFCR_L,
351 .bit = 21, 462 .bit = 21,
352 }, 463 },
464 [86] = {
465 .mask = IPIC_SIMSR_L,
466 .prio = 0,
467 .force = IPIC_SIFCR_L,
468 .bit = 22,
469 },
470 [87] = {
471 .mask = IPIC_SIMSR_L,
472 .prio = 0,
473 .force = IPIC_SIFCR_L,
474 .bit = 23,
475 },
476 [88] = {
477 .mask = IPIC_SIMSR_L,
478 .prio = 0,
479 .force = IPIC_SIFCR_L,
480 .bit = 24,
481 },
482 [89] = {
483 .mask = IPIC_SIMSR_L,
484 .prio = 0,
485 .force = IPIC_SIFCR_L,
486 .bit = 25,
487 },
353 [90] = { 488 [90] = {
354 .pend = IPIC_SIPNR_L,
355 .mask = IPIC_SIMSR_L, 489 .mask = IPIC_SIMSR_L,
356 .prio = 0, 490 .prio = 0,
357 .force = IPIC_SIFCR_L, 491 .force = IPIC_SIFCR_L,
358 .bit = 26, 492 .bit = 26,
359 }, 493 },
360 [91] = { 494 [91] = {
361 .pend = IPIC_SIPNR_L,
362 .mask = IPIC_SIMSR_L, 495 .mask = IPIC_SIMSR_L,
363 .prio = 0, 496 .prio = 0,
364 .force = IPIC_SIFCR_L, 497 .force = IPIC_SIFCR_L,
365 .bit = 27, 498 .bit = 27,
366 }, 499 },
500 [94] = {
501 .mask = IPIC_SIMSR_L,
502 .prio = 0,
503 .force = IPIC_SIFCR_L,
504 .bit = 30,
505 },
367}; 506};
368 507
369static inline u32 ipic_read(volatile u32 __iomem *base, unsigned int reg) 508static inline u32 ipic_read(volatile u32 __iomem *base, unsigned int reg)
@@ -412,6 +551,10 @@ static void ipic_mask_irq(unsigned int virq)
412 temp &= ~(1 << (31 - ipic_info[src].bit)); 551 temp &= ~(1 << (31 - ipic_info[src].bit));
413 ipic_write(ipic->regs, ipic_info[src].mask, temp); 552 ipic_write(ipic->regs, ipic_info[src].mask, temp);
414 553
554 /* mb() can't guarantee that masking is finished. But it does finish
555 * for nearly all cases. */
556 mb();
557
415 spin_unlock_irqrestore(&ipic_lock, flags); 558 spin_unlock_irqrestore(&ipic_lock, flags);
416} 559}
417 560
@@ -424,9 +567,13 @@ static void ipic_ack_irq(unsigned int virq)
424 567
425 spin_lock_irqsave(&ipic_lock, flags); 568 spin_lock_irqsave(&ipic_lock, flags);
426 569
427 temp = ipic_read(ipic->regs, ipic_info[src].pend); 570 temp = ipic_read(ipic->regs, ipic_info[src].ack);
428 temp |= (1 << (31 - ipic_info[src].bit)); 571 temp |= (1 << (31 - ipic_info[src].bit));
429 ipic_write(ipic->regs, ipic_info[src].pend, temp); 572 ipic_write(ipic->regs, ipic_info[src].ack, temp);
573
574 /* mb() can't guarantee that ack is finished. But it does finish
575 * for nearly all cases. */
576 mb();
430 577
431 spin_unlock_irqrestore(&ipic_lock, flags); 578 spin_unlock_irqrestore(&ipic_lock, flags);
432} 579}
@@ -444,9 +591,13 @@ static void ipic_mask_irq_and_ack(unsigned int virq)
444 temp &= ~(1 << (31 - ipic_info[src].bit)); 591 temp &= ~(1 << (31 - ipic_info[src].bit));
445 ipic_write(ipic->regs, ipic_info[src].mask, temp); 592 ipic_write(ipic->regs, ipic_info[src].mask, temp);
446 593
447 temp = ipic_read(ipic->regs, ipic_info[src].pend); 594 temp = ipic_read(ipic->regs, ipic_info[src].ack);
448 temp |= (1 << (31 - ipic_info[src].bit)); 595 temp |= (1 << (31 - ipic_info[src].bit));
449 ipic_write(ipic->regs, ipic_info[src].pend, temp); 596 ipic_write(ipic->regs, ipic_info[src].ack, temp);
597
598 /* mb() can't guarantee that ack is finished. But it does finish
599 * for nearly all cases. */
600 mb();
450 601
451 spin_unlock_irqrestore(&ipic_lock, flags); 602 spin_unlock_irqrestore(&ipic_lock, flags);
452} 603}
@@ -468,14 +619,22 @@ static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
468 flow_type); 619 flow_type);
469 return -EINVAL; 620 return -EINVAL;
470 } 621 }
622 /* ipic supports only edge mode on external interrupts */
623 if ((flow_type & IRQ_TYPE_EDGE_FALLING) && !ipic_info[src].ack) {
624 printk(KERN_ERR "ipic: edge sense not supported on internal "
625 "interrupts\n");
626 return -EINVAL;
627 }
471 628
472 desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); 629 desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
473 desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; 630 desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
474 if (flow_type & IRQ_TYPE_LEVEL_LOW) { 631 if (flow_type & IRQ_TYPE_LEVEL_LOW) {
475 desc->status |= IRQ_LEVEL; 632 desc->status |= IRQ_LEVEL;
476 desc->handle_irq = handle_level_irq; 633 desc->handle_irq = handle_level_irq;
634 desc->chip = &ipic_level_irq_chip;
477 } else { 635 } else {
478 desc->handle_irq = handle_edge_irq; 636 desc->handle_irq = handle_edge_irq;
637 desc->chip = &ipic_edge_irq_chip;
479 } 638 }
480 639
481 /* only EXT IRQ senses are programmable on ipic 640 /* only EXT IRQ senses are programmable on ipic
@@ -500,7 +659,16 @@ static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
500 return 0; 659 return 0;
501} 660}
502 661
503static struct irq_chip ipic_irq_chip = { 662/* level interrupts and edge interrupts have different ack operations */
663static struct irq_chip ipic_level_irq_chip = {
664 .typename = " IPIC ",
665 .unmask = ipic_unmask_irq,
666 .mask = ipic_mask_irq,
667 .mask_ack = ipic_mask_irq,
668 .set_type = ipic_set_irq_type,
669};
670
671static struct irq_chip ipic_edge_irq_chip = {
504 .typename = " IPIC ", 672 .typename = " IPIC ",
505 .unmask = ipic_unmask_irq, 673 .unmask = ipic_unmask_irq,
506 .mask = ipic_mask_irq, 674 .mask = ipic_mask_irq,
@@ -519,13 +687,9 @@ static int ipic_host_map(struct irq_host *h, unsigned int virq,
519 irq_hw_number_t hw) 687 irq_hw_number_t hw)
520{ 688{
521 struct ipic *ipic = h->host_data; 689 struct ipic *ipic = h->host_data;
522 struct irq_chip *chip;
523
524 /* Default chip */
525 chip = &ipic->hc_irq;
526 690
527 set_irq_chip_data(virq, ipic); 691 set_irq_chip_data(virq, ipic);
528 set_irq_chip_and_handler(virq, chip, handle_level_irq); 692 set_irq_chip_and_handler(virq, &ipic_level_irq_chip, handle_level_irq);
529 693
530 /* Set default irq type */ 694 /* Set default irq type */
531 set_irq_type(virq, IRQ_TYPE_NONE); 695 set_irq_type(virq, IRQ_TYPE_NONE);
@@ -584,7 +748,6 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
584 ipic->regs = ioremap(res.start, res.end - res.start + 1); 748 ipic->regs = ioremap(res.start, res.end - res.start + 1);
585 749
586 ipic->irqhost->host_data = ipic; 750 ipic->irqhost->host_data = ipic;
587 ipic->hc_irq = ipic_irq_chip;
588 751
589 /* init hw */ 752 /* init hw */
590 ipic_write(ipic->regs, IPIC_SICNR, 0x0); 753 ipic_write(ipic->regs, IPIC_SICNR, 0x0);
@@ -593,6 +756,10 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
593 * configure SICFR accordingly */ 756 * configure SICFR accordingly */
594 if (flags & IPIC_SPREADMODE_GRP_A) 757 if (flags & IPIC_SPREADMODE_GRP_A)
595 temp |= SICFR_IPSA; 758 temp |= SICFR_IPSA;
759 if (flags & IPIC_SPREADMODE_GRP_B)
760 temp |= SICFR_IPSB;
761 if (flags & IPIC_SPREADMODE_GRP_C)
762 temp |= SICFR_IPSC;
596 if (flags & IPIC_SPREADMODE_GRP_D) 763 if (flags & IPIC_SPREADMODE_GRP_D)
597 temp |= SICFR_IPSD; 764 temp |= SICFR_IPSD;
598 if (flags & IPIC_SPREADMODE_MIX_A) 765 if (flags & IPIC_SPREADMODE_MIX_A)
@@ -600,7 +767,7 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
600 if (flags & IPIC_SPREADMODE_MIX_B) 767 if (flags & IPIC_SPREADMODE_MIX_B)
601 temp |= SICFR_MPSB; 768 temp |= SICFR_MPSB;
602 769
603 ipic_write(ipic->regs, IPIC_SICNR, temp); 770 ipic_write(ipic->regs, IPIC_SICFR, temp);
604 771
605 /* handle MCP route */ 772 /* handle MCP route */
606 temp = 0; 773 temp = 0;
@@ -672,10 +839,12 @@ void ipic_set_highest_priority(unsigned int virq)
672 839
673void ipic_set_default_priority(void) 840void ipic_set_default_priority(void)
674{ 841{
675 ipic_write(primary_ipic->regs, IPIC_SIPRR_A, IPIC_SIPRR_A_DEFAULT); 842 ipic_write(primary_ipic->regs, IPIC_SIPRR_A, IPIC_PRIORITY_DEFAULT);
676 ipic_write(primary_ipic->regs, IPIC_SIPRR_D, IPIC_SIPRR_D_DEFAULT); 843 ipic_write(primary_ipic->regs, IPIC_SIPRR_B, IPIC_PRIORITY_DEFAULT);
677 ipic_write(primary_ipic->regs, IPIC_SMPRR_A, IPIC_SMPRR_A_DEFAULT); 844 ipic_write(primary_ipic->regs, IPIC_SIPRR_C, IPIC_PRIORITY_DEFAULT);
678 ipic_write(primary_ipic->regs, IPIC_SMPRR_B, IPIC_SMPRR_B_DEFAULT); 845 ipic_write(primary_ipic->regs, IPIC_SIPRR_D, IPIC_PRIORITY_DEFAULT);
846 ipic_write(primary_ipic->regs, IPIC_SMPRR_A, IPIC_PRIORITY_DEFAULT);
847 ipic_write(primary_ipic->regs, IPIC_SMPRR_B, IPIC_PRIORITY_DEFAULT);
679} 848}
680 849
681void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq) 850void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq)