diff options
Diffstat (limited to 'arch/powerpc/sysdev/ipic.c')
-rw-r--r-- | arch/powerpc/sysdev/ipic.c | 287 |
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 | ||
32 | static struct ipic * primary_ipic; | 32 | static struct ipic * primary_ipic; |
33 | static struct irq_chip ipic_level_irq_chip, ipic_edge_irq_chip; | ||
33 | static DEFINE_SPINLOCK(ipic_lock); | 34 | static DEFINE_SPINLOCK(ipic_lock); |
34 | 35 | ||
35 | static struct ipic_info ipic_info[] = { | 36 | static 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 | ||
369 | static inline u32 ipic_read(volatile u32 __iomem *base, unsigned int reg) | 508 | static 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 | ||
503 | static struct irq_chip ipic_irq_chip = { | 662 | /* level interrupts and edge interrupts have different ack operations */ |
663 | static 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 | |||
671 | static 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 | ||
673 | void ipic_set_default_priority(void) | 840 | void 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 | ||
681 | void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq) | 850 | void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq) |