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.c219
1 files changed, 160 insertions, 59 deletions
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index 05a56e55804c..7274750fd9c6 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -30,11 +30,32 @@
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 [4] = {
52 .mask = IPIC_SIMSR_H,
53 .prio = IPIC_SIPRR_C,
54 .force = IPIC_SIFCR_H,
55 .bit = 19,
56 .prio_mask = 3,
57 },
36 [9] = { 58 [9] = {
37 .pend = IPIC_SIPNR_H,
38 .mask = IPIC_SIMSR_H, 59 .mask = IPIC_SIMSR_H,
39 .prio = IPIC_SIPRR_D, 60 .prio = IPIC_SIPRR_D,
40 .force = IPIC_SIFCR_H, 61 .force = IPIC_SIFCR_H,
@@ -42,7 +63,6 @@ static struct ipic_info ipic_info[] = {
42 .prio_mask = 0, 63 .prio_mask = 0,
43 }, 64 },
44 [10] = { 65 [10] = {
45 .pend = IPIC_SIPNR_H,
46 .mask = IPIC_SIMSR_H, 66 .mask = IPIC_SIMSR_H,
47 .prio = IPIC_SIPRR_D, 67 .prio = IPIC_SIPRR_D,
48 .force = IPIC_SIFCR_H, 68 .force = IPIC_SIFCR_H,
@@ -50,15 +70,27 @@ static struct ipic_info ipic_info[] = {
50 .prio_mask = 1, 70 .prio_mask = 1,
51 }, 71 },
52 [11] = { 72 [11] = {
53 .pend = IPIC_SIPNR_H,
54 .mask = IPIC_SIMSR_H, 73 .mask = IPIC_SIMSR_H,
55 .prio = IPIC_SIPRR_D, 74 .prio = IPIC_SIPRR_D,
56 .force = IPIC_SIFCR_H, 75 .force = IPIC_SIFCR_H,
57 .bit = 26, 76 .bit = 26,
58 .prio_mask = 2, 77 .prio_mask = 2,
59 }, 78 },
79 [12] = {
80 .mask = IPIC_SIMSR_H,
81 .prio = IPIC_SIPRR_D,
82 .force = IPIC_SIFCR_H,
83 .bit = 27,
84 .prio_mask = 3,
85 },
86 [13] = {
87 .mask = IPIC_SIMSR_H,
88 .prio = IPIC_SIPRR_D,
89 .force = IPIC_SIFCR_H,
90 .bit = 28,
91 .prio_mask = 4,
92 },
60 [14] = { 93 [14] = {
61 .pend = IPIC_SIPNR_H,
62 .mask = IPIC_SIMSR_H, 94 .mask = IPIC_SIMSR_H,
63 .prio = IPIC_SIPRR_D, 95 .prio = IPIC_SIPRR_D,
64 .force = IPIC_SIFCR_H, 96 .force = IPIC_SIFCR_H,
@@ -66,7 +98,6 @@ static struct ipic_info ipic_info[] = {
66 .prio_mask = 5, 98 .prio_mask = 5,
67 }, 99 },
68 [15] = { 100 [15] = {
69 .pend = IPIC_SIPNR_H,
70 .mask = IPIC_SIMSR_H, 101 .mask = IPIC_SIMSR_H,
71 .prio = IPIC_SIPRR_D, 102 .prio = IPIC_SIPRR_D,
72 .force = IPIC_SIFCR_H, 103 .force = IPIC_SIFCR_H,
@@ -74,7 +105,6 @@ static struct ipic_info ipic_info[] = {
74 .prio_mask = 6, 105 .prio_mask = 6,
75 }, 106 },
76 [16] = { 107 [16] = {
77 .pend = IPIC_SIPNR_H,
78 .mask = IPIC_SIMSR_H, 108 .mask = IPIC_SIMSR_H,
79 .prio = IPIC_SIPRR_D, 109 .prio = IPIC_SIPRR_D,
80 .force = IPIC_SIFCR_H, 110 .force = IPIC_SIFCR_H,
@@ -82,7 +112,7 @@ static struct ipic_info ipic_info[] = {
82 .prio_mask = 7, 112 .prio_mask = 7,
83 }, 113 },
84 [17] = { 114 [17] = {
85 .pend = IPIC_SEPNR, 115 .ack = IPIC_SEPNR,
86 .mask = IPIC_SEMSR, 116 .mask = IPIC_SEMSR,
87 .prio = IPIC_SMPRR_A, 117 .prio = IPIC_SMPRR_A,
88 .force = IPIC_SEFCR, 118 .force = IPIC_SEFCR,
@@ -90,7 +120,7 @@ static struct ipic_info ipic_info[] = {
90 .prio_mask = 5, 120 .prio_mask = 5,
91 }, 121 },
92 [18] = { 122 [18] = {
93 .pend = IPIC_SEPNR, 123 .ack = IPIC_SEPNR,
94 .mask = IPIC_SEMSR, 124 .mask = IPIC_SEMSR,
95 .prio = IPIC_SMPRR_A, 125 .prio = IPIC_SMPRR_A,
96 .force = IPIC_SEFCR, 126 .force = IPIC_SEFCR,
@@ -98,7 +128,7 @@ static struct ipic_info ipic_info[] = {
98 .prio_mask = 6, 128 .prio_mask = 6,
99 }, 129 },
100 [19] = { 130 [19] = {
101 .pend = IPIC_SEPNR, 131 .ack = IPIC_SEPNR,
102 .mask = IPIC_SEMSR, 132 .mask = IPIC_SEMSR,
103 .prio = IPIC_SMPRR_A, 133 .prio = IPIC_SMPRR_A,
104 .force = IPIC_SEFCR, 134 .force = IPIC_SEFCR,
@@ -106,7 +136,7 @@ static struct ipic_info ipic_info[] = {
106 .prio_mask = 7, 136 .prio_mask = 7,
107 }, 137 },
108 [20] = { 138 [20] = {
109 .pend = IPIC_SEPNR, 139 .ack = IPIC_SEPNR,
110 .mask = IPIC_SEMSR, 140 .mask = IPIC_SEMSR,
111 .prio = IPIC_SMPRR_B, 141 .prio = IPIC_SMPRR_B,
112 .force = IPIC_SEFCR, 142 .force = IPIC_SEFCR,
@@ -114,7 +144,7 @@ static struct ipic_info ipic_info[] = {
114 .prio_mask = 4, 144 .prio_mask = 4,
115 }, 145 },
116 [21] = { 146 [21] = {
117 .pend = IPIC_SEPNR, 147 .ack = IPIC_SEPNR,
118 .mask = IPIC_SEMSR, 148 .mask = IPIC_SEMSR,
119 .prio = IPIC_SMPRR_B, 149 .prio = IPIC_SMPRR_B,
120 .force = IPIC_SEFCR, 150 .force = IPIC_SEFCR,
@@ -122,7 +152,7 @@ static struct ipic_info ipic_info[] = {
122 .prio_mask = 5, 152 .prio_mask = 5,
123 }, 153 },
124 [22] = { 154 [22] = {
125 .pend = IPIC_SEPNR, 155 .ack = IPIC_SEPNR,
126 .mask = IPIC_SEMSR, 156 .mask = IPIC_SEMSR,
127 .prio = IPIC_SMPRR_B, 157 .prio = IPIC_SMPRR_B,
128 .force = IPIC_SEFCR, 158 .force = IPIC_SEFCR,
@@ -130,7 +160,7 @@ static struct ipic_info ipic_info[] = {
130 .prio_mask = 6, 160 .prio_mask = 6,
131 }, 161 },
132 [23] = { 162 [23] = {
133 .pend = IPIC_SEPNR, 163 .ack = IPIC_SEPNR,
134 .mask = IPIC_SEMSR, 164 .mask = IPIC_SEMSR,
135 .prio = IPIC_SMPRR_B, 165 .prio = IPIC_SMPRR_B,
136 .force = IPIC_SEFCR, 166 .force = IPIC_SEFCR,
@@ -138,7 +168,6 @@ static struct ipic_info ipic_info[] = {
138 .prio_mask = 7, 168 .prio_mask = 7,
139 }, 169 },
140 [32] = { 170 [32] = {
141 .pend = IPIC_SIPNR_H,
142 .mask = IPIC_SIMSR_H, 171 .mask = IPIC_SIMSR_H,
143 .prio = IPIC_SIPRR_A, 172 .prio = IPIC_SIPRR_A,
144 .force = IPIC_SIFCR_H, 173 .force = IPIC_SIFCR_H,
@@ -146,7 +175,6 @@ static struct ipic_info ipic_info[] = {
146 .prio_mask = 0, 175 .prio_mask = 0,
147 }, 176 },
148 [33] = { 177 [33] = {
149 .pend = IPIC_SIPNR_H,
150 .mask = IPIC_SIMSR_H, 178 .mask = IPIC_SIMSR_H,
151 .prio = IPIC_SIPRR_A, 179 .prio = IPIC_SIPRR_A,
152 .force = IPIC_SIFCR_H, 180 .force = IPIC_SIFCR_H,
@@ -154,7 +182,6 @@ static struct ipic_info ipic_info[] = {
154 .prio_mask = 1, 182 .prio_mask = 1,
155 }, 183 },
156 [34] = { 184 [34] = {
157 .pend = IPIC_SIPNR_H,
158 .mask = IPIC_SIMSR_H, 185 .mask = IPIC_SIMSR_H,
159 .prio = IPIC_SIPRR_A, 186 .prio = IPIC_SIPRR_A,
160 .force = IPIC_SIFCR_H, 187 .force = IPIC_SIFCR_H,
@@ -162,7 +189,6 @@ static struct ipic_info ipic_info[] = {
162 .prio_mask = 2, 189 .prio_mask = 2,
163 }, 190 },
164 [35] = { 191 [35] = {
165 .pend = IPIC_SIPNR_H,
166 .mask = IPIC_SIMSR_H, 192 .mask = IPIC_SIMSR_H,
167 .prio = IPIC_SIPRR_A, 193 .prio = IPIC_SIPRR_A,
168 .force = IPIC_SIFCR_H, 194 .force = IPIC_SIFCR_H,
@@ -170,7 +196,6 @@ static struct ipic_info ipic_info[] = {
170 .prio_mask = 3, 196 .prio_mask = 3,
171 }, 197 },
172 [36] = { 198 [36] = {
173 .pend = IPIC_SIPNR_H,
174 .mask = IPIC_SIMSR_H, 199 .mask = IPIC_SIMSR_H,
175 .prio = IPIC_SIPRR_A, 200 .prio = IPIC_SIPRR_A,
176 .force = IPIC_SIFCR_H, 201 .force = IPIC_SIFCR_H,
@@ -178,7 +203,6 @@ static struct ipic_info ipic_info[] = {
178 .prio_mask = 4, 203 .prio_mask = 4,
179 }, 204 },
180 [37] = { 205 [37] = {
181 .pend = IPIC_SIPNR_H,
182 .mask = IPIC_SIMSR_H, 206 .mask = IPIC_SIMSR_H,
183 .prio = IPIC_SIPRR_A, 207 .prio = IPIC_SIPRR_A,
184 .force = IPIC_SIFCR_H, 208 .force = IPIC_SIFCR_H,
@@ -186,7 +210,6 @@ static struct ipic_info ipic_info[] = {
186 .prio_mask = 5, 210 .prio_mask = 5,
187 }, 211 },
188 [38] = { 212 [38] = {
189 .pend = IPIC_SIPNR_H,
190 .mask = IPIC_SIMSR_H, 213 .mask = IPIC_SIMSR_H,
191 .prio = IPIC_SIPRR_A, 214 .prio = IPIC_SIPRR_A,
192 .force = IPIC_SIFCR_H, 215 .force = IPIC_SIFCR_H,
@@ -194,15 +217,48 @@ static struct ipic_info ipic_info[] = {
194 .prio_mask = 6, 217 .prio_mask = 6,
195 }, 218 },
196 [39] = { 219 [39] = {
197 .pend = IPIC_SIPNR_H,
198 .mask = IPIC_SIMSR_H, 220 .mask = IPIC_SIMSR_H,
199 .prio = IPIC_SIPRR_A, 221 .prio = IPIC_SIPRR_A,
200 .force = IPIC_SIFCR_H, 222 .force = IPIC_SIFCR_H,
201 .bit = 7, 223 .bit = 7,
202 .prio_mask = 7, 224 .prio_mask = 7,
203 }, 225 },
226 [42] = {
227 .mask = IPIC_SIMSR_H,
228 .prio = IPIC_SIPRR_B,
229 .force = IPIC_SIFCR_H,
230 .bit = 10,
231 .prio_mask = 2,
232 },
233 [44] = {
234 .mask = IPIC_SIMSR_H,
235 .prio = IPIC_SIPRR_B,
236 .force = IPIC_SIFCR_H,
237 .bit = 12,
238 .prio_mask = 4,
239 },
240 [45] = {
241 .mask = IPIC_SIMSR_H,
242 .prio = IPIC_SIPRR_B,
243 .force = IPIC_SIFCR_H,
244 .bit = 13,
245 .prio_mask = 5,
246 },
247 [46] = {
248 .mask = IPIC_SIMSR_H,
249 .prio = IPIC_SIPRR_B,
250 .force = IPIC_SIFCR_H,
251 .bit = 14,
252 .prio_mask = 6,
253 },
254 [47] = {
255 .mask = IPIC_SIMSR_H,
256 .prio = IPIC_SIPRR_B,
257 .force = IPIC_SIFCR_H,
258 .bit = 15,
259 .prio_mask = 7,
260 },
204 [48] = { 261 [48] = {
205 .pend = IPIC_SEPNR,
206 .mask = IPIC_SEMSR, 262 .mask = IPIC_SEMSR,
207 .prio = IPIC_SMPRR_A, 263 .prio = IPIC_SMPRR_A,
208 .force = IPIC_SEFCR, 264 .force = IPIC_SEFCR,
@@ -210,7 +266,6 @@ static struct ipic_info ipic_info[] = {
210 .prio_mask = 4, 266 .prio_mask = 4,
211 }, 267 },
212 [64] = { 268 [64] = {
213 .pend = IPIC_SIPNR_L,
214 .mask = IPIC_SIMSR_L, 269 .mask = IPIC_SIMSR_L,
215 .prio = IPIC_SMPRR_A, 270 .prio = IPIC_SMPRR_A,
216 .force = IPIC_SIFCR_L, 271 .force = IPIC_SIFCR_L,
@@ -218,7 +273,6 @@ static struct ipic_info ipic_info[] = {
218 .prio_mask = 0, 273 .prio_mask = 0,
219 }, 274 },
220 [65] = { 275 [65] = {
221 .pend = IPIC_SIPNR_L,
222 .mask = IPIC_SIMSR_L, 276 .mask = IPIC_SIMSR_L,
223 .prio = IPIC_SMPRR_A, 277 .prio = IPIC_SMPRR_A,
224 .force = IPIC_SIFCR_L, 278 .force = IPIC_SIFCR_L,
@@ -226,7 +280,6 @@ static struct ipic_info ipic_info[] = {
226 .prio_mask = 1, 280 .prio_mask = 1,
227 }, 281 },
228 [66] = { 282 [66] = {
229 .pend = IPIC_SIPNR_L,
230 .mask = IPIC_SIMSR_L, 283 .mask = IPIC_SIMSR_L,
231 .prio = IPIC_SMPRR_A, 284 .prio = IPIC_SMPRR_A,
232 .force = IPIC_SIFCR_L, 285 .force = IPIC_SIFCR_L,
@@ -234,7 +287,6 @@ static struct ipic_info ipic_info[] = {
234 .prio_mask = 2, 287 .prio_mask = 2,
235 }, 288 },
236 [67] = { 289 [67] = {
237 .pend = IPIC_SIPNR_L,
238 .mask = IPIC_SIMSR_L, 290 .mask = IPIC_SIMSR_L,
239 .prio = IPIC_SMPRR_A, 291 .prio = IPIC_SMPRR_A,
240 .force = IPIC_SIFCR_L, 292 .force = IPIC_SIFCR_L,
@@ -242,7 +294,6 @@ static struct ipic_info ipic_info[] = {
242 .prio_mask = 3, 294 .prio_mask = 3,
243 }, 295 },
244 [68] = { 296 [68] = {
245 .pend = IPIC_SIPNR_L,
246 .mask = IPIC_SIMSR_L, 297 .mask = IPIC_SIMSR_L,
247 .prio = IPIC_SMPRR_B, 298 .prio = IPIC_SMPRR_B,
248 .force = IPIC_SIFCR_L, 299 .force = IPIC_SIFCR_L,
@@ -250,7 +301,6 @@ static struct ipic_info ipic_info[] = {
250 .prio_mask = 0, 301 .prio_mask = 0,
251 }, 302 },
252 [69] = { 303 [69] = {
253 .pend = IPIC_SIPNR_L,
254 .mask = IPIC_SIMSR_L, 304 .mask = IPIC_SIMSR_L,
255 .prio = IPIC_SMPRR_B, 305 .prio = IPIC_SMPRR_B,
256 .force = IPIC_SIFCR_L, 306 .force = IPIC_SIFCR_L,
@@ -258,7 +308,6 @@ static struct ipic_info ipic_info[] = {
258 .prio_mask = 1, 308 .prio_mask = 1,
259 }, 309 },
260 [70] = { 310 [70] = {
261 .pend = IPIC_SIPNR_L,
262 .mask = IPIC_SIMSR_L, 311 .mask = IPIC_SIMSR_L,
263 .prio = IPIC_SMPRR_B, 312 .prio = IPIC_SMPRR_B,
264 .force = IPIC_SIFCR_L, 313 .force = IPIC_SIFCR_L,
@@ -266,7 +315,6 @@ static struct ipic_info ipic_info[] = {
266 .prio_mask = 2, 315 .prio_mask = 2,
267 }, 316 },
268 [71] = { 317 [71] = {
269 .pend = IPIC_SIPNR_L,
270 .mask = IPIC_SIMSR_L, 318 .mask = IPIC_SIMSR_L,
271 .prio = IPIC_SMPRR_B, 319 .prio = IPIC_SMPRR_B,
272 .force = IPIC_SIFCR_L, 320 .force = IPIC_SIFCR_L,
@@ -274,91 +322,114 @@ static struct ipic_info ipic_info[] = {
274 .prio_mask = 3, 322 .prio_mask = 3,
275 }, 323 },
276 [72] = { 324 [72] = {
277 .pend = IPIC_SIPNR_L,
278 .mask = IPIC_SIMSR_L, 325 .mask = IPIC_SIMSR_L,
279 .prio = 0, 326 .prio = 0,
280 .force = IPIC_SIFCR_L, 327 .force = IPIC_SIFCR_L,
281 .bit = 8, 328 .bit = 8,
282 }, 329 },
283 [73] = { 330 [73] = {
284 .pend = IPIC_SIPNR_L,
285 .mask = IPIC_SIMSR_L, 331 .mask = IPIC_SIMSR_L,
286 .prio = 0, 332 .prio = 0,
287 .force = IPIC_SIFCR_L, 333 .force = IPIC_SIFCR_L,
288 .bit = 9, 334 .bit = 9,
289 }, 335 },
290 [74] = { 336 [74] = {
291 .pend = IPIC_SIPNR_L,
292 .mask = IPIC_SIMSR_L, 337 .mask = IPIC_SIMSR_L,
293 .prio = 0, 338 .prio = 0,
294 .force = IPIC_SIFCR_L, 339 .force = IPIC_SIFCR_L,
295 .bit = 10, 340 .bit = 10,
296 }, 341 },
297 [75] = { 342 [75] = {
298 .pend = IPIC_SIPNR_L,
299 .mask = IPIC_SIMSR_L, 343 .mask = IPIC_SIMSR_L,
300 .prio = 0, 344 .prio = 0,
301 .force = IPIC_SIFCR_L, 345 .force = IPIC_SIFCR_L,
302 .bit = 11, 346 .bit = 11,
303 }, 347 },
304 [76] = { 348 [76] = {
305 .pend = IPIC_SIPNR_L,
306 .mask = IPIC_SIMSR_L, 349 .mask = IPIC_SIMSR_L,
307 .prio = 0, 350 .prio = 0,
308 .force = IPIC_SIFCR_L, 351 .force = IPIC_SIFCR_L,
309 .bit = 12, 352 .bit = 12,
310 }, 353 },
311 [77] = { 354 [77] = {
312 .pend = IPIC_SIPNR_L,
313 .mask = IPIC_SIMSR_L, 355 .mask = IPIC_SIMSR_L,
314 .prio = 0, 356 .prio = 0,
315 .force = IPIC_SIFCR_L, 357 .force = IPIC_SIFCR_L,
316 .bit = 13, 358 .bit = 13,
317 }, 359 },
318 [78] = { 360 [78] = {
319 .pend = IPIC_SIPNR_L,
320 .mask = IPIC_SIMSR_L, 361 .mask = IPIC_SIMSR_L,
321 .prio = 0, 362 .prio = 0,
322 .force = IPIC_SIFCR_L, 363 .force = IPIC_SIFCR_L,
323 .bit = 14, 364 .bit = 14,
324 }, 365 },
325 [79] = { 366 [79] = {
326 .pend = IPIC_SIPNR_L,
327 .mask = IPIC_SIMSR_L, 367 .mask = IPIC_SIMSR_L,
328 .prio = 0, 368 .prio = 0,
329 .force = IPIC_SIFCR_L, 369 .force = IPIC_SIFCR_L,
330 .bit = 15, 370 .bit = 15,
331 }, 371 },
332 [80] = { 372 [80] = {
333 .pend = IPIC_SIPNR_L,
334 .mask = IPIC_SIMSR_L, 373 .mask = IPIC_SIMSR_L,
335 .prio = 0, 374 .prio = 0,
336 .force = IPIC_SIFCR_L, 375 .force = IPIC_SIFCR_L,
337 .bit = 16, 376 .bit = 16,
338 }, 377 },
378 [81] = {
379 .mask = IPIC_SIMSR_L,
380 .prio = 0,
381 .force = IPIC_SIFCR_L,
382 .bit = 17,
383 },
384 [82] = {
385 .mask = IPIC_SIMSR_L,
386 .prio = 0,
387 .force = IPIC_SIFCR_L,
388 .bit = 18,
389 },
339 [84] = { 390 [84] = {
340 .pend = IPIC_SIPNR_L,
341 .mask = IPIC_SIMSR_L, 391 .mask = IPIC_SIMSR_L,
342 .prio = 0, 392 .prio = 0,
343 .force = IPIC_SIFCR_L, 393 .force = IPIC_SIFCR_L,
344 .bit = 20, 394 .bit = 20,
345 }, 395 },
346 [85] = { 396 [85] = {
347 .pend = IPIC_SIPNR_L,
348 .mask = IPIC_SIMSR_L, 397 .mask = IPIC_SIMSR_L,
349 .prio = 0, 398 .prio = 0,
350 .force = IPIC_SIFCR_L, 399 .force = IPIC_SIFCR_L,
351 .bit = 21, 400 .bit = 21,
352 }, 401 },
402 [86] = {
403 .mask = IPIC_SIMSR_L,
404 .prio = 0,
405 .force = IPIC_SIFCR_L,
406 .bit = 22,
407 },
408 [87] = {
409 .mask = IPIC_SIMSR_L,
410 .prio = 0,
411 .force = IPIC_SIFCR_L,
412 .bit = 23,
413 },
414 [88] = {
415 .mask = IPIC_SIMSR_L,
416 .prio = 0,
417 .force = IPIC_SIFCR_L,
418 .bit = 24,
419 },
420 [89] = {
421 .mask = IPIC_SIMSR_L,
422 .prio = 0,
423 .force = IPIC_SIFCR_L,
424 .bit = 25,
425 },
353 [90] = { 426 [90] = {
354 .pend = IPIC_SIPNR_L,
355 .mask = IPIC_SIMSR_L, 427 .mask = IPIC_SIMSR_L,
356 .prio = 0, 428 .prio = 0,
357 .force = IPIC_SIFCR_L, 429 .force = IPIC_SIFCR_L,
358 .bit = 26, 430 .bit = 26,
359 }, 431 },
360 [91] = { 432 [91] = {
361 .pend = IPIC_SIPNR_L,
362 .mask = IPIC_SIMSR_L, 433 .mask = IPIC_SIMSR_L,
363 .prio = 0, 434 .prio = 0,
364 .force = IPIC_SIFCR_L, 435 .force = IPIC_SIFCR_L,
@@ -412,6 +483,10 @@ static void ipic_mask_irq(unsigned int virq)
412 temp &= ~(1 << (31 - ipic_info[src].bit)); 483 temp &= ~(1 << (31 - ipic_info[src].bit));
413 ipic_write(ipic->regs, ipic_info[src].mask, temp); 484 ipic_write(ipic->regs, ipic_info[src].mask, temp);
414 485
486 /* mb() can't guarantee that masking is finished. But it does finish
487 * for nearly all cases. */
488 mb();
489
415 spin_unlock_irqrestore(&ipic_lock, flags); 490 spin_unlock_irqrestore(&ipic_lock, flags);
416} 491}
417 492
@@ -424,9 +499,13 @@ static void ipic_ack_irq(unsigned int virq)
424 499
425 spin_lock_irqsave(&ipic_lock, flags); 500 spin_lock_irqsave(&ipic_lock, flags);
426 501
427 temp = ipic_read(ipic->regs, ipic_info[src].pend); 502 temp = ipic_read(ipic->regs, ipic_info[src].ack);
428 temp |= (1 << (31 - ipic_info[src].bit)); 503 temp |= (1 << (31 - ipic_info[src].bit));
429 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();
430 509
431 spin_unlock_irqrestore(&ipic_lock, flags); 510 spin_unlock_irqrestore(&ipic_lock, flags);
432} 511}
@@ -444,9 +523,13 @@ static void ipic_mask_irq_and_ack(unsigned int virq)
444 temp &= ~(1 << (31 - ipic_info[src].bit)); 523 temp &= ~(1 << (31 - ipic_info[src].bit));
445 ipic_write(ipic->regs, ipic_info[src].mask, temp); 524 ipic_write(ipic->regs, ipic_info[src].mask, temp);
446 525
447 temp = ipic_read(ipic->regs, ipic_info[src].pend); 526 temp = ipic_read(ipic->regs, ipic_info[src].ack);
448 temp |= (1 << (31 - ipic_info[src].bit)); 527 temp |= (1 << (31 - ipic_info[src].bit));
449 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();
450 533
451 spin_unlock_irqrestore(&ipic_lock, flags); 534 spin_unlock_irqrestore(&ipic_lock, flags);
452} 535}
@@ -468,14 +551,22 @@ static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
468 flow_type); 551 flow_type);
469 return -EINVAL; 552 return -EINVAL;
470 } 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 }
471 560
472 desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); 561 desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
473 desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; 562 desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
474 if (flow_type & IRQ_TYPE_LEVEL_LOW) { 563 if (flow_type & IRQ_TYPE_LEVEL_LOW) {
475 desc->status |= IRQ_LEVEL; 564 desc->status |= IRQ_LEVEL;
476 desc->handle_irq = handle_level_irq; 565 desc->handle_irq = handle_level_irq;
566 desc->chip = &ipic_level_irq_chip;
477 } else { 567 } else {
478 desc->handle_irq = handle_edge_irq; 568 desc->handle_irq = handle_edge_irq;
569 desc->chip = &ipic_edge_irq_chip;
479 } 570 }
480 571
481 /* only EXT IRQ senses are programmable on ipic 572 /* only EXT IRQ senses are programmable on ipic
@@ -500,7 +591,16 @@ static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
500 return 0; 591 return 0;
501} 592}
502 593
503static 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 = {
504 .typename = " IPIC ", 604 .typename = " IPIC ",
505 .unmask = ipic_unmask_irq, 605 .unmask = ipic_unmask_irq,
506 .mask = ipic_mask_irq, 606 .mask = ipic_mask_irq,
@@ -519,13 +619,9 @@ static int ipic_host_map(struct irq_host *h, unsigned int virq,
519 irq_hw_number_t hw) 619 irq_hw_number_t hw)
520{ 620{
521 struct ipic *ipic = h->host_data; 621 struct ipic *ipic = h->host_data;
522 struct irq_chip *chip;
523
524 /* Default chip */
525 chip = &ipic->hc_irq;
526 622
527 set_irq_chip_data(virq, ipic); 623 set_irq_chip_data(virq, ipic);
528 set_irq_chip_and_handler(virq, chip, handle_level_irq); 624 set_irq_chip_and_handler(virq, &ipic_level_irq_chip, handle_level_irq);
529 625
530 /* Set default irq type */ 626 /* Set default irq type */
531 set_irq_type(virq, IRQ_TYPE_NONE); 627 set_irq_type(virq, IRQ_TYPE_NONE);
@@ -584,7 +680,6 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
584 ipic->regs = ioremap(res.start, res.end - res.start + 1); 680 ipic->regs = ioremap(res.start, res.end - res.start + 1);
585 681
586 ipic->irqhost->host_data = ipic; 682 ipic->irqhost->host_data = ipic;
587 ipic->hc_irq = ipic_irq_chip;
588 683
589 /* init hw */ 684 /* init hw */
590 ipic_write(ipic->regs, IPIC_SICNR, 0x0); 685 ipic_write(ipic->regs, IPIC_SICNR, 0x0);
@@ -593,6 +688,10 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
593 * configure SICFR accordingly */ 688 * configure SICFR accordingly */
594 if (flags & IPIC_SPREADMODE_GRP_A) 689 if (flags & IPIC_SPREADMODE_GRP_A)
595 temp |= SICFR_IPSA; 690 temp |= SICFR_IPSA;
691 if (flags & IPIC_SPREADMODE_GRP_B)
692 temp |= SICFR_IPSB;
693 if (flags & IPIC_SPREADMODE_GRP_C)
694 temp |= SICFR_IPSC;
596 if (flags & IPIC_SPREADMODE_GRP_D) 695 if (flags & IPIC_SPREADMODE_GRP_D)
597 temp |= SICFR_IPSD; 696 temp |= SICFR_IPSD;
598 if (flags & IPIC_SPREADMODE_MIX_A) 697 if (flags & IPIC_SPREADMODE_MIX_A)
@@ -600,7 +699,7 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
600 if (flags & IPIC_SPREADMODE_MIX_B) 699 if (flags & IPIC_SPREADMODE_MIX_B)
601 temp |= SICFR_MPSB; 700 temp |= SICFR_MPSB;
602 701
603 ipic_write(ipic->regs, IPIC_SICNR, temp); 702 ipic_write(ipic->regs, IPIC_SICFR, temp);
604 703
605 /* handle MCP route */ 704 /* handle MCP route */
606 temp = 0; 705 temp = 0;
@@ -672,10 +771,12 @@ void ipic_set_highest_priority(unsigned int virq)
672 771
673void ipic_set_default_priority(void) 772void ipic_set_default_priority(void)
674{ 773{
675 ipic_write(primary_ipic->regs, IPIC_SIPRR_A, IPIC_SIPRR_A_DEFAULT); 774 ipic_write(primary_ipic->regs, IPIC_SIPRR_A, IPIC_PRIORITY_DEFAULT);
676 ipic_write(primary_ipic->regs, IPIC_SIPRR_D, IPIC_SIPRR_D_DEFAULT); 775 ipic_write(primary_ipic->regs, IPIC_SIPRR_B, IPIC_PRIORITY_DEFAULT);
677 ipic_write(primary_ipic->regs, IPIC_SMPRR_A, IPIC_SMPRR_A_DEFAULT); 776 ipic_write(primary_ipic->regs, IPIC_SIPRR_C, IPIC_PRIORITY_DEFAULT);
678 ipic_write(primary_ipic->regs, IPIC_SMPRR_B, IPIC_SMPRR_B_DEFAULT); 777 ipic_write(primary_ipic->regs, IPIC_SIPRR_D, IPIC_PRIORITY_DEFAULT);
778 ipic_write(primary_ipic->regs, IPIC_SMPRR_A, IPIC_PRIORITY_DEFAULT);
779 ipic_write(primary_ipic->regs, IPIC_SMPRR_B, IPIC_PRIORITY_DEFAULT);
679} 780}
680 781
681void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq) 782void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq)