diff options
Diffstat (limited to 'arch/powerpc/sysdev/ipic.c')
-rw-r--r-- | arch/powerpc/sysdev/ipic.c | 219 |
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 | ||
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 | [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 | ||
503 | static struct irq_chip ipic_irq_chip = { | 594 | /* level interrupts and edge interrupts have different ack operations */ |
595 | static 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 | |||
603 | static 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 | ||
673 | void ipic_set_default_priority(void) | 772 | void 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 | ||
681 | void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq) | 782 | void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq) |