diff options
author | Steven Miao <realmz6@gmail.com> | 2012-05-16 05:56:51 -0400 |
---|---|---|
committer | Bob Liu <lliubbo@gmail.com> | 2012-05-21 02:54:15 -0400 |
commit | 4f6b600fdc1771efbb01d7a66328ac714e898bcb (patch) | |
tree | 317860db4041b0e77895a882f861f3996cdb3d1b /arch/blackfin/mach-common | |
parent | 969003152aa9085e50ce23822c60fab82222ecef (diff) |
blackfin: mach-common: add sec support for bf60x
Add system event controller support for bf60x so that interrupt can be
handled.
Signed-off-by: Steven Miao <realmz6@gmail.com>
Signed-off-by: Bob Liu <lliubbo@gmail.com>
Diffstat (limited to 'arch/blackfin/mach-common')
-rw-r--r-- | arch/blackfin/mach-common/ints-priority.c | 418 |
1 files changed, 380 insertions, 38 deletions
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 332dace6af34..bf5dc5f76824 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c | |||
@@ -16,6 +16,8 @@ | |||
16 | #include <linux/seq_file.h> | 16 | #include <linux/seq_file.h> |
17 | #include <linux/irq.h> | 17 | #include <linux/irq.h> |
18 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
19 | #include <linux/syscore_ops.h> | ||
20 | #include <asm/delay.h> | ||
19 | #ifdef CONFIG_IPIPE | 21 | #ifdef CONFIG_IPIPE |
20 | #include <linux/ipipe.h> | 22 | #include <linux/ipipe.h> |
21 | #endif | 23 | #endif |
@@ -25,7 +27,11 @@ | |||
25 | #include <asm/irq_handler.h> | 27 | #include <asm/irq_handler.h> |
26 | #include <asm/dpmc.h> | 28 | #include <asm/dpmc.h> |
27 | 29 | ||
28 | #define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1)) | 30 | #ifndef CONFIG_BF60x |
31 | # define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1)) | ||
32 | #else | ||
33 | # define SIC_SYSIRQ(irq) ((irq) - IVG15) | ||
34 | #endif | ||
29 | 35 | ||
30 | /* | 36 | /* |
31 | * NOTES: | 37 | * NOTES: |
@@ -50,6 +56,7 @@ unsigned long bfin_sic_iwr[3]; /* Up to 3 SIC_IWRx registers */ | |||
50 | unsigned vr_wakeup; | 56 | unsigned vr_wakeup; |
51 | #endif | 57 | #endif |
52 | 58 | ||
59 | #ifndef CONFIG_BF60x | ||
53 | static struct ivgx { | 60 | static struct ivgx { |
54 | /* irq number for request_irq, available in mach-bf5xx/irq.h */ | 61 | /* irq number for request_irq, available in mach-bf5xx/irq.h */ |
55 | unsigned int irqno; | 62 | unsigned int irqno; |
@@ -78,7 +85,8 @@ static void __init search_IAR(void) | |||
78 | 85 | ||
79 | for (irqN = 0; irqN < NR_PERI_INTS; irqN += 4) { | 86 | for (irqN = 0; irqN < NR_PERI_INTS; irqN += 4) { |
80 | int irqn; | 87 | int irqn; |
81 | u32 iar = bfin_read32((unsigned long *)SIC_IAR0 + | 88 | u32 iar = |
89 | bfin_read32((unsigned long *)SIC_IAR0 + | ||
82 | #if defined(CONFIG_BF51x) || defined(CONFIG_BF52x) || \ | 90 | #if defined(CONFIG_BF51x) || defined(CONFIG_BF52x) || \ |
83 | defined(CONFIG_BF538) || defined(CONFIG_BF539) | 91 | defined(CONFIG_BF538) || defined(CONFIG_BF539) |
84 | ((irqN % 32) >> 3) + ((irqN / 32) * ((SIC_IAR4 - SIC_IAR0) / 4)) | 92 | ((irqN % 32) >> 3) + ((irqN / 32) * ((SIC_IAR4 - SIC_IAR0) / 4)) |
@@ -86,7 +94,6 @@ static void __init search_IAR(void) | |||
86 | (irqN >> 3) | 94 | (irqN >> 3) |
87 | #endif | 95 | #endif |
88 | ); | 96 | ); |
89 | |||
90 | for (irqn = irqN; irqn < irqN + 4; ++irqn) { | 97 | for (irqn = irqN; irqn < irqN + 4; ++irqn) { |
91 | int iar_shift = (irqn & 7) * 4; | 98 | int iar_shift = (irqn & 7) * 4; |
92 | if (ivg == (0xf & (iar >> iar_shift))) { | 99 | if (ivg == (0xf & (iar >> iar_shift))) { |
@@ -99,11 +106,11 @@ static void __init search_IAR(void) | |||
99 | } | 106 | } |
100 | } | 107 | } |
101 | } | 108 | } |
109 | #endif | ||
102 | 110 | ||
103 | /* | 111 | /* |
104 | * This is for core internal IRQs | 112 | * This is for core internal IRQs |
105 | */ | 113 | */ |
106 | |||
107 | void bfin_ack_noop(struct irq_data *d) | 114 | void bfin_ack_noop(struct irq_data *d) |
108 | { | 115 | { |
109 | /* Dummy function. */ | 116 | /* Dummy function. */ |
@@ -136,21 +143,21 @@ static void bfin_core_unmask_irq(struct irq_data *d) | |||
136 | void bfin_internal_mask_irq(unsigned int irq) | 143 | void bfin_internal_mask_irq(unsigned int irq) |
137 | { | 144 | { |
138 | unsigned long flags = hard_local_irq_save(); | 145 | unsigned long flags = hard_local_irq_save(); |
139 | 146 | #ifndef CONFIG_BF60x | |
140 | #ifdef SIC_IMASK0 | 147 | #ifdef SIC_IMASK0 |
141 | unsigned mask_bank = SIC_SYSIRQ(irq) / 32; | 148 | unsigned mask_bank = SIC_SYSIRQ(irq) / 32; |
142 | unsigned mask_bit = SIC_SYSIRQ(irq) % 32; | 149 | unsigned mask_bit = SIC_SYSIRQ(irq) % 32; |
143 | bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) & | 150 | bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) & |
144 | ~(1 << mask_bit)); | 151 | ~(1 << mask_bit)); |
145 | # ifdef CONFIG_SMP | 152 | # if defined(CONFIG_SMP) || defined(CONFIG_ICC) |
146 | bfin_write_SICB_IMASK(mask_bank, bfin_read_SICB_IMASK(mask_bank) & | 153 | bfin_write_SICB_IMASK(mask_bank, bfin_read_SICB_IMASK(mask_bank) & |
147 | ~(1 << mask_bit)); | 154 | ~(1 << mask_bit)); |
148 | # endif | 155 | # endif |
149 | #else | 156 | #else |
150 | bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & | 157 | bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & |
151 | ~(1 << SIC_SYSIRQ(irq))); | 158 | ~(1 << SIC_SYSIRQ(irq))); |
159 | #endif /* end of SIC_IMASK0 */ | ||
152 | #endif | 160 | #endif |
153 | |||
154 | hard_local_irq_restore(flags); | 161 | hard_local_irq_restore(flags); |
155 | } | 162 | } |
156 | 163 | ||
@@ -160,7 +167,7 @@ static void bfin_internal_mask_irq_chip(struct irq_data *d) | |||
160 | } | 167 | } |
161 | 168 | ||
162 | #ifdef CONFIG_SMP | 169 | #ifdef CONFIG_SMP |
163 | static void bfin_internal_unmask_irq_affinity(unsigned int irq, | 170 | void bfin_internal_unmask_irq_affinity(unsigned int irq, |
164 | const struct cpumask *affinity) | 171 | const struct cpumask *affinity) |
165 | #else | 172 | #else |
166 | void bfin_internal_unmask_irq(unsigned int irq) | 173 | void bfin_internal_unmask_irq(unsigned int irq) |
@@ -168,6 +175,7 @@ void bfin_internal_unmask_irq(unsigned int irq) | |||
168 | { | 175 | { |
169 | unsigned long flags = hard_local_irq_save(); | 176 | unsigned long flags = hard_local_irq_save(); |
170 | 177 | ||
178 | #ifndef CONFIG_BF60x | ||
171 | #ifdef SIC_IMASK0 | 179 | #ifdef SIC_IMASK0 |
172 | unsigned mask_bank = SIC_SYSIRQ(irq) / 32; | 180 | unsigned mask_bank = SIC_SYSIRQ(irq) / 32; |
173 | unsigned mask_bit = SIC_SYSIRQ(irq) % 32; | 181 | unsigned mask_bit = SIC_SYSIRQ(irq) % 32; |
@@ -175,22 +183,239 @@ void bfin_internal_unmask_irq(unsigned int irq) | |||
175 | if (cpumask_test_cpu(0, affinity)) | 183 | if (cpumask_test_cpu(0, affinity)) |
176 | # endif | 184 | # endif |
177 | bfin_write_SIC_IMASK(mask_bank, | 185 | bfin_write_SIC_IMASK(mask_bank, |
178 | bfin_read_SIC_IMASK(mask_bank) | | 186 | bfin_read_SIC_IMASK(mask_bank) | |
179 | (1 << mask_bit)); | 187 | (1 << mask_bit)); |
180 | # ifdef CONFIG_SMP | 188 | # ifdef CONFIG_SMP |
181 | if (cpumask_test_cpu(1, affinity)) | 189 | if (cpumask_test_cpu(1, affinity)) |
182 | bfin_write_SICB_IMASK(mask_bank, | 190 | bfin_write_SICB_IMASK(mask_bank, |
183 | bfin_read_SICB_IMASK(mask_bank) | | 191 | bfin_read_SICB_IMASK(mask_bank) | |
184 | (1 << mask_bit)); | 192 | (1 << mask_bit)); |
185 | # endif | 193 | # endif |
186 | #else | 194 | #else |
187 | bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | | 195 | bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | |
188 | (1 << SIC_SYSIRQ(irq))); | 196 | (1 << SIC_SYSIRQ(irq))); |
197 | #endif | ||
189 | #endif | 198 | #endif |
199 | hard_local_irq_restore(flags); | ||
200 | } | ||
201 | |||
202 | #ifdef CONFIG_BF60x | ||
203 | static void bfin_sec_preflow_handler(struct irq_data *d) | ||
204 | { | ||
205 | unsigned long flags = hard_local_irq_save(); | ||
206 | unsigned int sid = SIC_SYSIRQ(d->irq); | ||
207 | |||
208 | bfin_write_SEC_SCI(0, SEC_CSID, sid); | ||
209 | |||
210 | hard_local_irq_restore(flags); | ||
211 | } | ||
212 | |||
213 | static void bfin_sec_mask_ack_irq(struct irq_data *d) | ||
214 | { | ||
215 | unsigned long flags = hard_local_irq_save(); | ||
216 | unsigned int sid = SIC_SYSIRQ(d->irq); | ||
217 | |||
218 | bfin_write_SEC_SCI(0, SEC_CSID, sid); | ||
219 | |||
220 | hard_local_irq_restore(flags); | ||
221 | } | ||
222 | |||
223 | static void bfin_sec_unmask_irq(struct irq_data *d) | ||
224 | { | ||
225 | unsigned long flags = hard_local_irq_save(); | ||
226 | unsigned int sid = SIC_SYSIRQ(d->irq); | ||
227 | |||
228 | bfin_write32(SEC_END, sid); | ||
229 | |||
230 | hard_local_irq_restore(flags); | ||
231 | } | ||
232 | |||
233 | static void bfin_sec_enable_ssi(unsigned int sid) | ||
234 | { | ||
235 | unsigned long flags = hard_local_irq_save(); | ||
236 | uint32_t reg_sctl = bfin_read_SEC_SCTL(sid); | ||
237 | |||
238 | reg_sctl |= SEC_SCTL_SRC_EN; | ||
239 | bfin_write_SEC_SCTL(sid, reg_sctl); | ||
240 | |||
241 | hard_local_irq_restore(flags); | ||
242 | } | ||
243 | |||
244 | static void bfin_sec_disable_ssi(unsigned int sid) | ||
245 | { | ||
246 | unsigned long flags = hard_local_irq_save(); | ||
247 | uint32_t reg_sctl = bfin_read_SEC_SCTL(sid); | ||
248 | |||
249 | reg_sctl &= ((uint32_t)~SEC_SCTL_SRC_EN); | ||
250 | bfin_write_SEC_SCTL(sid, reg_sctl); | ||
251 | |||
252 | hard_local_irq_restore(flags); | ||
253 | } | ||
254 | |||
255 | static void bfin_sec_set_ssi_coreid(unsigned int sid, unsigned int coreid) | ||
256 | { | ||
257 | unsigned long flags = hard_local_irq_save(); | ||
258 | uint32_t reg_sctl = bfin_read_SEC_SCTL(sid); | ||
259 | |||
260 | reg_sctl &= ((uint32_t)~SEC_SCTL_CTG); | ||
261 | bfin_write_SEC_SCTL(sid, reg_sctl | ((coreid << 20) & SEC_SCTL_CTG)); | ||
262 | |||
263 | hard_local_irq_restore(flags); | ||
264 | } | ||
265 | |||
266 | static void bfin_sec_enable_sci(unsigned int sid) | ||
267 | { | ||
268 | unsigned long flags = hard_local_irq_save(); | ||
269 | uint32_t reg_sctl = bfin_read_SEC_SCTL(sid); | ||
270 | |||
271 | if (sid == SIC_SYSIRQ(IRQ_WATCH0)) | ||
272 | reg_sctl |= SEC_SCTL_FAULT_EN; | ||
273 | else | ||
274 | reg_sctl |= SEC_SCTL_INT_EN; | ||
275 | bfin_write_SEC_SCTL(sid, reg_sctl); | ||
276 | |||
277 | hard_local_irq_restore(flags); | ||
278 | } | ||
279 | |||
280 | static void bfin_sec_disable_sci(unsigned int sid) | ||
281 | { | ||
282 | unsigned long flags = hard_local_irq_save(); | ||
283 | uint32_t reg_sctl = bfin_read_SEC_SCTL(sid); | ||
284 | |||
285 | reg_sctl &= ((uint32_t)~SEC_SCTL_INT_EN); | ||
286 | bfin_write_SEC_SCTL(sid, reg_sctl); | ||
287 | |||
288 | hard_local_irq_restore(flags); | ||
289 | } | ||
290 | |||
291 | static void bfin_sec_enable(struct irq_data *d) | ||
292 | { | ||
293 | unsigned long flags = hard_local_irq_save(); | ||
294 | unsigned int sid = SIC_SYSIRQ(d->irq); | ||
295 | |||
296 | bfin_sec_enable_sci(sid); | ||
297 | bfin_sec_enable_ssi(sid); | ||
190 | 298 | ||
191 | hard_local_irq_restore(flags); | 299 | hard_local_irq_restore(flags); |
192 | } | 300 | } |
193 | 301 | ||
302 | static void bfin_sec_disable(struct irq_data *d) | ||
303 | { | ||
304 | unsigned long flags = hard_local_irq_save(); | ||
305 | unsigned int sid = SIC_SYSIRQ(d->irq); | ||
306 | |||
307 | bfin_sec_disable_sci(sid); | ||
308 | bfin_sec_disable_ssi(sid); | ||
309 | |||
310 | hard_local_irq_restore(flags); | ||
311 | } | ||
312 | |||
313 | static void bfin_sec_raise_irq(unsigned int sid) | ||
314 | { | ||
315 | unsigned long flags = hard_local_irq_save(); | ||
316 | |||
317 | bfin_write32(SEC_RAISE, sid); | ||
318 | |||
319 | hard_local_irq_restore(flags); | ||
320 | } | ||
321 | |||
322 | static void init_software_driven_irq(void) | ||
323 | { | ||
324 | bfin_sec_set_ssi_coreid(34, 0); | ||
325 | bfin_sec_set_ssi_coreid(35, 1); | ||
326 | bfin_sec_set_ssi_coreid(36, 0); | ||
327 | bfin_sec_set_ssi_coreid(37, 1); | ||
328 | } | ||
329 | |||
330 | void bfin_sec_resume(void) | ||
331 | { | ||
332 | bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_RESET); | ||
333 | udelay(100); | ||
334 | bfin_write_SEC_GCTL(SEC_GCTL_EN); | ||
335 | bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN); | ||
336 | } | ||
337 | |||
338 | void handle_sec_sfi_fault(uint32_t gstat) | ||
339 | { | ||
340 | |||
341 | } | ||
342 | |||
343 | void handle_sec_sci_fault(uint32_t gstat) | ||
344 | { | ||
345 | uint32_t core_id; | ||
346 | uint32_t cstat; | ||
347 | |||
348 | core_id = gstat & SEC_GSTAT_SCI; | ||
349 | cstat = bfin_read_SEC_SCI(core_id, SEC_CSTAT); | ||
350 | if (cstat & SEC_CSTAT_ERR) { | ||
351 | switch (cstat & SEC_CSTAT_ERRC) { | ||
352 | case SEC_CSTAT_ACKERR: | ||
353 | printk(KERN_DEBUG "sec ack err\n"); | ||
354 | break; | ||
355 | default: | ||
356 | printk(KERN_DEBUG "sec sci unknow err\n"); | ||
357 | } | ||
358 | } | ||
359 | |||
360 | } | ||
361 | |||
362 | void handle_sec_ssi_fault(uint32_t gstat) | ||
363 | { | ||
364 | uint32_t sid; | ||
365 | uint32_t sstat; | ||
366 | |||
367 | sid = gstat & SEC_GSTAT_SID; | ||
368 | sstat = bfin_read_SEC_SSTAT(sid); | ||
369 | |||
370 | } | ||
371 | |||
372 | void handle_sec_fault(unsigned int irq, struct irq_desc *desc) | ||
373 | { | ||
374 | uint32_t sec_gstat; | ||
375 | |||
376 | raw_spin_lock(&desc->lock); | ||
377 | |||
378 | sec_gstat = bfin_read32(SEC_GSTAT); | ||
379 | if (sec_gstat & SEC_GSTAT_ERR) { | ||
380 | |||
381 | switch (sec_gstat & SEC_GSTAT_ERRC) { | ||
382 | case 0: | ||
383 | handle_sec_sfi_fault(sec_gstat); | ||
384 | break; | ||
385 | case SEC_GSTAT_SCIERR: | ||
386 | handle_sec_sci_fault(sec_gstat); | ||
387 | break; | ||
388 | case SEC_GSTAT_SSIERR: | ||
389 | handle_sec_ssi_fault(sec_gstat); | ||
390 | break; | ||
391 | } | ||
392 | |||
393 | |||
394 | } | ||
395 | |||
396 | raw_spin_unlock(&desc->lock); | ||
397 | } | ||
398 | |||
399 | static int sec_suspend(void) | ||
400 | { | ||
401 | return 0; | ||
402 | } | ||
403 | |||
404 | static void sec_resume(void) | ||
405 | { | ||
406 | bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_RESET); | ||
407 | udelay(100); | ||
408 | bfin_write_SEC_GCTL(SEC_GCTL_EN); | ||
409 | bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN); | ||
410 | } | ||
411 | |||
412 | static struct syscore_ops sec_pm_syscore_ops = { | ||
413 | .suspend = sec_suspend, | ||
414 | .resume = sec_resume, | ||
415 | }; | ||
416 | |||
417 | #endif | ||
418 | |||
194 | #ifdef CONFIG_SMP | 419 | #ifdef CONFIG_SMP |
195 | static void bfin_internal_unmask_irq_chip(struct irq_data *d) | 420 | static void bfin_internal_unmask_irq_chip(struct irq_data *d) |
196 | { | 421 | { |
@@ -276,17 +501,14 @@ static int bfin_internal_set_wake_chip(struct irq_data *d, unsigned int state) | |||
276 | 501 | ||
277 | static struct irq_chip bfin_core_irqchip = { | 502 | static struct irq_chip bfin_core_irqchip = { |
278 | .name = "CORE", | 503 | .name = "CORE", |
279 | .irq_ack = bfin_ack_noop, | ||
280 | .irq_mask = bfin_core_mask_irq, | 504 | .irq_mask = bfin_core_mask_irq, |
281 | .irq_unmask = bfin_core_unmask_irq, | 505 | .irq_unmask = bfin_core_unmask_irq, |
282 | }; | 506 | }; |
283 | 507 | ||
284 | static struct irq_chip bfin_internal_irqchip = { | 508 | static struct irq_chip bfin_internal_irqchip = { |
285 | .name = "INTN", | 509 | .name = "INTN", |
286 | .irq_ack = bfin_ack_noop, | ||
287 | .irq_mask = bfin_internal_mask_irq_chip, | 510 | .irq_mask = bfin_internal_mask_irq_chip, |
288 | .irq_unmask = bfin_internal_unmask_irq_chip, | 511 | .irq_unmask = bfin_internal_unmask_irq_chip, |
289 | .irq_mask_ack = bfin_internal_mask_irq_chip, | ||
290 | .irq_disable = bfin_internal_mask_irq_chip, | 512 | .irq_disable = bfin_internal_mask_irq_chip, |
291 | .irq_enable = bfin_internal_unmask_irq_chip, | 513 | .irq_enable = bfin_internal_unmask_irq_chip, |
292 | #ifdef CONFIG_SMP | 514 | #ifdef CONFIG_SMP |
@@ -295,6 +517,18 @@ static struct irq_chip bfin_internal_irqchip = { | |||
295 | .irq_set_wake = bfin_internal_set_wake_chip, | 517 | .irq_set_wake = bfin_internal_set_wake_chip, |
296 | }; | 518 | }; |
297 | 519 | ||
520 | #ifdef CONFIG_BF60x | ||
521 | static struct irq_chip bfin_sec_irqchip = { | ||
522 | .name = "SEC", | ||
523 | .irq_mask_ack = bfin_sec_mask_ack_irq, | ||
524 | .irq_mask = bfin_sec_mask_ack_irq, | ||
525 | .irq_unmask = bfin_sec_unmask_irq, | ||
526 | .irq_eoi = bfin_sec_unmask_irq, | ||
527 | .irq_disable = bfin_sec_disable, | ||
528 | .irq_enable = bfin_sec_enable, | ||
529 | }; | ||
530 | #endif | ||
531 | |||
298 | void bfin_handle_irq(unsigned irq) | 532 | void bfin_handle_irq(unsigned irq) |
299 | { | 533 | { |
300 | #ifdef CONFIG_IPIPE | 534 | #ifdef CONFIG_IPIPE |
@@ -396,8 +630,6 @@ int bfin_mac_status_set_wake(struct irq_data *d, unsigned int state) | |||
396 | 630 | ||
397 | static struct irq_chip bfin_mac_status_irqchip = { | 631 | static struct irq_chip bfin_mac_status_irqchip = { |
398 | .name = "MACST", | 632 | .name = "MACST", |
399 | .irq_ack = bfin_ack_noop, | ||
400 | .irq_mask_ack = bfin_mac_status_mask_irq, | ||
401 | .irq_mask = bfin_mac_status_mask_irq, | 633 | .irq_mask = bfin_mac_status_mask_irq, |
402 | .irq_unmask = bfin_mac_status_unmask_irq, | 634 | .irq_unmask = bfin_mac_status_unmask_irq, |
403 | .irq_set_wake = bfin_mac_status_set_wake, | 635 | .irq_set_wake = bfin_mac_status_set_wake, |
@@ -421,15 +653,15 @@ void bfin_demux_mac_status_irq(unsigned int int_err_irq, | |||
421 | } else { | 653 | } else { |
422 | bfin_mac_status_ack_irq(irq); | 654 | bfin_mac_status_ack_irq(irq); |
423 | pr_debug("IRQ %d:" | 655 | pr_debug("IRQ %d:" |
424 | " MASKED MAC ERROR INTERRUPT ASSERTED\n", | 656 | " MASKED MAC ERROR INTERRUPT ASSERTED\n", |
425 | irq); | 657 | irq); |
426 | } | 658 | } |
427 | } else | 659 | } else |
428 | printk(KERN_ERR | 660 | printk(KERN_ERR |
429 | "%s : %s : LINE %d :\nIRQ ?: MAC ERROR" | 661 | "%s : %s : LINE %d :\nIRQ ?: MAC ERROR" |
430 | " INTERRUPT ASSERTED BUT NO SOURCE FOUND" | 662 | " INTERRUPT ASSERTED BUT NO SOURCE FOUND" |
431 | "(EMAC_SYSTAT=0x%X)\n", | 663 | "(EMAC_SYSTAT=0x%X)\n", |
432 | __func__, __FILE__, __LINE__, status); | 664 | __func__, __FILE__, __LINE__, status); |
433 | } | 665 | } |
434 | #endif | 666 | #endif |
435 | 667 | ||
@@ -583,7 +815,7 @@ static void bfin_demux_gpio_block(unsigned int irq) | |||
583 | } | 815 | } |
584 | 816 | ||
585 | void bfin_demux_gpio_irq(unsigned int inta_irq, | 817 | void bfin_demux_gpio_irq(unsigned int inta_irq, |
586 | struct irq_desc *desc) | 818 | struct irq_desc *desc) |
587 | { | 819 | { |
588 | unsigned int irq; | 820 | unsigned int irq; |
589 | 821 | ||
@@ -635,9 +867,15 @@ void bfin_demux_gpio_irq(unsigned int inta_irq, | |||
635 | 867 | ||
636 | #else | 868 | #else |
637 | 869 | ||
870 | # ifndef CONFIG_BF60x | ||
638 | #define NR_PINT_SYS_IRQS 4 | 871 | #define NR_PINT_SYS_IRQS 4 |
639 | #define NR_PINT_BITS 32 | ||
640 | #define NR_PINTS 160 | 872 | #define NR_PINTS 160 |
873 | # else | ||
874 | #define NR_PINT_SYS_IRQS 6 | ||
875 | #define NR_PINTS 112 | ||
876 | #endif | ||
877 | |||
878 | #define NR_PINT_BITS 32 | ||
641 | #define IRQ_NOT_AVAIL 0xFF | 879 | #define IRQ_NOT_AVAIL 0xFF |
642 | 880 | ||
643 | #define PINT_2_BANK(x) ((x) >> 5) | 881 | #define PINT_2_BANK(x) ((x) >> 5) |
@@ -652,8 +890,13 @@ static struct bfin_pint_regs * const pint[NR_PINT_SYS_IRQS] = { | |||
652 | (struct bfin_pint_regs *)PINT1_MASK_SET, | 890 | (struct bfin_pint_regs *)PINT1_MASK_SET, |
653 | (struct bfin_pint_regs *)PINT2_MASK_SET, | 891 | (struct bfin_pint_regs *)PINT2_MASK_SET, |
654 | (struct bfin_pint_regs *)PINT3_MASK_SET, | 892 | (struct bfin_pint_regs *)PINT3_MASK_SET, |
893 | #ifdef CONFIG_BF60x | ||
894 | (struct bfin_pint_regs *)PINT4_MASK_SET, | ||
895 | (struct bfin_pint_regs *)PINT5_MASK_SET, | ||
896 | #endif | ||
655 | }; | 897 | }; |
656 | 898 | ||
899 | #ifndef CONFIG_BF60x | ||
657 | inline unsigned int get_irq_base(u32 bank, u8 bmap) | 900 | inline unsigned int get_irq_base(u32 bank, u8 bmap) |
658 | { | 901 | { |
659 | unsigned int irq_base; | 902 | unsigned int irq_base; |
@@ -666,6 +909,16 @@ inline unsigned int get_irq_base(u32 bank, u8 bmap) | |||
666 | 909 | ||
667 | return irq_base; | 910 | return irq_base; |
668 | } | 911 | } |
912 | #else | ||
913 | inline unsigned int get_irq_base(u32 bank, u8 bmap) | ||
914 | { | ||
915 | unsigned int irq_base; | ||
916 | |||
917 | irq_base = IRQ_PA0 + bank * 16 + bmap * 16; | ||
918 | |||
919 | return irq_base; | ||
920 | } | ||
921 | #endif | ||
669 | 922 | ||
670 | /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ | 923 | /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ |
671 | void init_pint_lut(void) | 924 | void init_pint_lut(void) |
@@ -854,6 +1107,12 @@ static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state) | |||
854 | case 1: | 1107 | case 1: |
855 | pint_irq = IRQ_PINT1; | 1108 | pint_irq = IRQ_PINT1; |
856 | break; | 1109 | break; |
1110 | case 4: | ||
1111 | pint_irq = IRQ_PINT4; | ||
1112 | break; | ||
1113 | case 5: | ||
1114 | pint_irq = IRQ_PINT5; | ||
1115 | break; | ||
857 | default: | 1116 | default: |
858 | return -EINVAL; | 1117 | return -EINVAL; |
859 | } | 1118 | } |
@@ -867,10 +1126,21 @@ static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state) | |||
867 | #endif | 1126 | #endif |
868 | 1127 | ||
869 | void bfin_demux_gpio_irq(unsigned int inta_irq, | 1128 | void bfin_demux_gpio_irq(unsigned int inta_irq, |
870 | struct irq_desc *desc) | 1129 | struct irq_desc *desc) |
871 | { | 1130 | { |
872 | u32 bank, pint_val; | 1131 | u32 bank, pint_val; |
873 | u32 request, irq; | 1132 | u32 request, irq; |
1133 | u32 level_mask; | ||
1134 | int umask = 0; | ||
1135 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
1136 | |||
1137 | if (chip->irq_mask_ack) { | ||
1138 | chip->irq_mask_ack(&desc->irq_data); | ||
1139 | } else { | ||
1140 | chip->irq_mask(&desc->irq_data); | ||
1141 | if (chip->irq_ack) | ||
1142 | chip->irq_ack(&desc->irq_data); | ||
1143 | } | ||
874 | 1144 | ||
875 | switch (inta_irq) { | 1145 | switch (inta_irq) { |
876 | case IRQ_PINT0: | 1146 | case IRQ_PINT0: |
@@ -885,6 +1155,14 @@ void bfin_demux_gpio_irq(unsigned int inta_irq, | |||
885 | case IRQ_PINT1: | 1155 | case IRQ_PINT1: |
886 | bank = 1; | 1156 | bank = 1; |
887 | break; | 1157 | break; |
1158 | #ifdef CONFIG_BF60x | ||
1159 | case IRQ_PINT4: | ||
1160 | bank = 4; | ||
1161 | break; | ||
1162 | case IRQ_PINT5: | ||
1163 | bank = 5; | ||
1164 | break; | ||
1165 | #endif | ||
888 | default: | 1166 | default: |
889 | return; | 1167 | return; |
890 | } | 1168 | } |
@@ -893,15 +1171,23 @@ void bfin_demux_gpio_irq(unsigned int inta_irq, | |||
893 | 1171 | ||
894 | request = pint[bank]->request; | 1172 | request = pint[bank]->request; |
895 | 1173 | ||
1174 | level_mask = pint[bank]->edge_set & request; | ||
1175 | |||
896 | while (request) { | 1176 | while (request) { |
897 | if (request & 1) { | 1177 | if (request & 1) { |
898 | irq = pint2irq_lut[pint_val] + SYS_IRQS; | 1178 | irq = pint2irq_lut[pint_val] + SYS_IRQS; |
1179 | if (level_mask & PINT_BIT(pint_val)) { | ||
1180 | umask = 1; | ||
1181 | chip->irq_unmask(&desc->irq_data); | ||
1182 | } | ||
899 | bfin_handle_irq(irq); | 1183 | bfin_handle_irq(irq); |
900 | } | 1184 | } |
901 | pint_val++; | 1185 | pint_val++; |
902 | request >>= 1; | 1186 | request >>= 1; |
903 | } | 1187 | } |
904 | 1188 | ||
1189 | if (!umask) | ||
1190 | chip->irq_unmask(&desc->irq_data); | ||
905 | } | 1191 | } |
906 | #endif | 1192 | #endif |
907 | 1193 | ||
@@ -951,6 +1237,7 @@ int __init init_arch_irq(void) | |||
951 | int irq; | 1237 | int irq; |
952 | unsigned long ilat = 0; | 1238 | unsigned long ilat = 0; |
953 | 1239 | ||
1240 | #ifndef CONFIG_BF60x | ||
954 | /* Disable all the peripheral intrs - page 4-29 HW Ref manual */ | 1241 | /* Disable all the peripheral intrs - page 4-29 HW Ref manual */ |
955 | #ifdef SIC_IMASK0 | 1242 | #ifdef SIC_IMASK0 |
956 | bfin_write_SIC_IMASK0(SIC_UNMASK_ALL); | 1243 | bfin_write_SIC_IMASK0(SIC_UNMASK_ALL); |
@@ -958,13 +1245,16 @@ int __init init_arch_irq(void) | |||
958 | # ifdef SIC_IMASK2 | 1245 | # ifdef SIC_IMASK2 |
959 | bfin_write_SIC_IMASK2(SIC_UNMASK_ALL); | 1246 | bfin_write_SIC_IMASK2(SIC_UNMASK_ALL); |
960 | # endif | 1247 | # endif |
961 | # ifdef CONFIG_SMP | 1248 | # if defined(CONFIG_SMP) || defined(CONFIG_ICC) |
962 | bfin_write_SICB_IMASK0(SIC_UNMASK_ALL); | 1249 | bfin_write_SICB_IMASK0(SIC_UNMASK_ALL); |
963 | bfin_write_SICB_IMASK1(SIC_UNMASK_ALL); | 1250 | bfin_write_SICB_IMASK1(SIC_UNMASK_ALL); |
964 | # endif | 1251 | # endif |
965 | #else | 1252 | #else |
966 | bfin_write_SIC_IMASK(SIC_UNMASK_ALL); | 1253 | bfin_write_SIC_IMASK(SIC_UNMASK_ALL); |
967 | #endif | 1254 | #endif |
1255 | #else /* CONFIG_BF60x */ | ||
1256 | bfin_write_SEC_GCTL(SEC_GCTL_RESET); | ||
1257 | #endif | ||
968 | 1258 | ||
969 | local_irq_disable(); | 1259 | local_irq_disable(); |
970 | 1260 | ||
@@ -974,6 +1264,10 @@ int __init init_arch_irq(void) | |||
974 | pint[1]->assign = CONFIG_PINT1_ASSIGN; | 1264 | pint[1]->assign = CONFIG_PINT1_ASSIGN; |
975 | pint[2]->assign = CONFIG_PINT2_ASSIGN; | 1265 | pint[2]->assign = CONFIG_PINT2_ASSIGN; |
976 | pint[3]->assign = CONFIG_PINT3_ASSIGN; | 1266 | pint[3]->assign = CONFIG_PINT3_ASSIGN; |
1267 | # ifdef CONFIG_BF60x | ||
1268 | pint[4]->assign = CONFIG_PINT4_ASSIGN; | ||
1269 | pint[5]->assign = CONFIG_PINT5_ASSIGN; | ||
1270 | # endif | ||
977 | # endif | 1271 | # endif |
978 | /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ | 1272 | /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ |
979 | init_pint_lut(); | 1273 | init_pint_lut(); |
@@ -986,6 +1280,7 @@ int __init init_arch_irq(void) | |||
986 | irq_set_chip(irq, &bfin_internal_irqchip); | 1280 | irq_set_chip(irq, &bfin_internal_irqchip); |
987 | 1281 | ||
988 | switch (irq) { | 1282 | switch (irq) { |
1283 | #ifndef CONFIG_BF60x | ||
989 | #if BFIN_GPIO_PINT | 1284 | #if BFIN_GPIO_PINT |
990 | case IRQ_PINT0: | 1285 | case IRQ_PINT0: |
991 | case IRQ_PINT1: | 1286 | case IRQ_PINT1: |
@@ -1015,12 +1310,13 @@ int __init init_arch_irq(void) | |||
1015 | bfin_demux_mac_status_irq); | 1310 | bfin_demux_mac_status_irq); |
1016 | break; | 1311 | break; |
1017 | #endif | 1312 | #endif |
1018 | #ifdef CONFIG_SMP | 1313 | #if defined(CONFIG_SMP) || defined(CONFIG_ICC) |
1019 | case IRQ_SUPPLE_0: | 1314 | case IRQ_SUPPLE_0: |
1020 | case IRQ_SUPPLE_1: | 1315 | case IRQ_SUPPLE_1: |
1021 | irq_set_handler(irq, handle_percpu_irq); | 1316 | irq_set_handler(irq, handle_percpu_irq); |
1022 | break; | 1317 | break; |
1023 | #endif | 1318 | #endif |
1319 | #endif | ||
1024 | 1320 | ||
1025 | #ifdef CONFIG_TICKSOURCE_CORETMR | 1321 | #ifdef CONFIG_TICKSOURCE_CORETMR |
1026 | case IRQ_CORETMR: | 1322 | case IRQ_CORETMR: |
@@ -1050,7 +1346,8 @@ int __init init_arch_irq(void) | |||
1050 | 1346 | ||
1051 | init_mach_irq(); | 1347 | init_mach_irq(); |
1052 | 1348 | ||
1053 | #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) | 1349 | #ifndef CONFIG_BF60x |
1350 | #if (defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)) && !defined(CONFIG_BF60x) | ||
1054 | for (irq = IRQ_MAC_PHYINT; irq <= IRQ_MAC_STMDONE; irq++) | 1351 | for (irq = IRQ_MAC_PHYINT; irq <= IRQ_MAC_STMDONE; irq++) |
1055 | irq_set_chip_and_handler(irq, &bfin_mac_status_irqchip, | 1352 | irq_set_chip_and_handler(irq, &bfin_mac_status_irqchip, |
1056 | handle_level_irq); | 1353 | handle_level_irq); |
@@ -1060,7 +1357,28 @@ int __init init_arch_irq(void) | |||
1060 | irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++) | 1357 | irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++) |
1061 | irq_set_chip_and_handler(irq, &bfin_gpio_irqchip, | 1358 | irq_set_chip_and_handler(irq, &bfin_gpio_irqchip, |
1062 | handle_level_irq); | 1359 | handle_level_irq); |
1063 | 1360 | #else | |
1361 | for (irq = BFIN_IRQ(0); irq <= SYS_IRQS; irq++) { | ||
1362 | if (irq < CORE_IRQS) { | ||
1363 | irq_set_chip(irq, &bfin_sec_irqchip); | ||
1364 | __irq_set_handler(irq, handle_sec_fault, 0, NULL); | ||
1365 | } else if (irq >= BFIN_IRQ(21) && irq <= BFIN_IRQ(26)) { | ||
1366 | irq_set_chip(irq, &bfin_sec_irqchip); | ||
1367 | irq_set_chained_handler(irq, bfin_demux_gpio_irq); | ||
1368 | } else if (irq >= BFIN_IRQ(34) && irq <= BFIN_IRQ(37)) { | ||
1369 | irq_set_chip(irq, &bfin_sec_irqchip); | ||
1370 | irq_set_handler(irq, handle_percpu_irq); | ||
1371 | } else { | ||
1372 | irq_set_chip_and_handler(irq, &bfin_sec_irqchip, | ||
1373 | handle_fasteoi_irq); | ||
1374 | __irq_set_preflow_handler(irq, bfin_sec_preflow_handler); | ||
1375 | } | ||
1376 | } | ||
1377 | for (irq = GPIO_IRQ_BASE; | ||
1378 | irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++) | ||
1379 | irq_set_chip_and_handler(irq, &bfin_gpio_irqchip, | ||
1380 | handle_level_irq); | ||
1381 | #endif | ||
1064 | bfin_write_IMASK(0); | 1382 | bfin_write_IMASK(0); |
1065 | CSYNC(); | 1383 | CSYNC(); |
1066 | ilat = bfin_read_ILAT(); | 1384 | ilat = bfin_read_ILAT(); |
@@ -1072,14 +1390,17 @@ int __init init_arch_irq(void) | |||
1072 | /* IMASK=xxx is equivalent to STI xx or bfin_irq_flags=xx, | 1390 | /* IMASK=xxx is equivalent to STI xx or bfin_irq_flags=xx, |
1073 | * local_irq_enable() | 1391 | * local_irq_enable() |
1074 | */ | 1392 | */ |
1393 | #ifndef CONFIG_BF60x | ||
1075 | program_IAR(); | 1394 | program_IAR(); |
1076 | /* Therefore it's better to setup IARs before interrupts enabled */ | 1395 | /* Therefore it's better to setup IARs before interrupts enabled */ |
1077 | search_IAR(); | 1396 | search_IAR(); |
1078 | 1397 | ||
1079 | /* Enable interrupts IVG7-15 */ | 1398 | /* Enable interrupts IVG7-15 */ |
1080 | bfin_irq_flags |= IMASK_IVG15 | | 1399 | bfin_irq_flags |= IMASK_IVG15 | |
1081 | IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | | 1400 | IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | |
1082 | IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; | 1401 | IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; |
1402 | |||
1403 | bfin_sti(bfin_irq_flags); | ||
1083 | 1404 | ||
1084 | /* This implicitly covers ANOMALY_05000171 | 1405 | /* This implicitly covers ANOMALY_05000171 |
1085 | * Boot-ROM code modifies SICA_IWRx wakeup registers | 1406 | * Boot-ROM code modifies SICA_IWRx wakeup registers |
@@ -1103,7 +1424,23 @@ int __init init_arch_irq(void) | |||
1103 | #else | 1424 | #else |
1104 | bfin_write_SIC_IWR(IWR_DISABLE_ALL); | 1425 | bfin_write_SIC_IWR(IWR_DISABLE_ALL); |
1105 | #endif | 1426 | #endif |
1427 | #else /* CONFIG_BF60x */ | ||
1428 | /* Enable interrupts IVG7-15 */ | ||
1429 | bfin_irq_flags |= IMASK_IVG15 | | ||
1430 | IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | | ||
1431 | IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; | ||
1106 | 1432 | ||
1433 | |||
1434 | bfin_write_SEC_FCTL(SEC_FCTL_EN | SEC_FCTL_SYSRST_EN | SEC_FCTL_FLTIN_EN); | ||
1435 | bfin_sec_enable_sci(SIC_SYSIRQ(IRQ_WATCH0)); | ||
1436 | bfin_sec_enable_ssi(SIC_SYSIRQ(IRQ_WATCH0)); | ||
1437 | bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_RESET); | ||
1438 | udelay(100); | ||
1439 | bfin_write_SEC_GCTL(SEC_GCTL_EN); | ||
1440 | bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN); | ||
1441 | init_software_driven_irq(); | ||
1442 | register_syscore_ops(&sec_pm_syscore_ops); | ||
1443 | #endif | ||
1107 | return 0; | 1444 | return 0; |
1108 | } | 1445 | } |
1109 | 1446 | ||
@@ -1112,13 +1449,14 @@ __attribute__((l1_text)) | |||
1112 | #endif | 1449 | #endif |
1113 | static int vec_to_irq(int vec) | 1450 | static int vec_to_irq(int vec) |
1114 | { | 1451 | { |
1452 | #ifndef CONFIG_BF60x | ||
1115 | struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst; | 1453 | struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst; |
1116 | struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop; | 1454 | struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop; |
1117 | unsigned long sic_status[3]; | 1455 | unsigned long sic_status[3]; |
1118 | 1456 | #endif | |
1119 | if (likely(vec == EVT_IVTMR_P)) | 1457 | if (likely(vec == EVT_IVTMR_P)) |
1120 | return IRQ_CORETMR; | 1458 | return IRQ_CORETMR; |
1121 | 1459 | #ifndef CONFIG_BF60x | |
1122 | #ifdef SIC_ISR | 1460 | #ifdef SIC_ISR |
1123 | sic_status[0] = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR(); | 1461 | sic_status[0] = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR(); |
1124 | #else | 1462 | #else |
@@ -1147,6 +1485,10 @@ static int vec_to_irq(int vec) | |||
1147 | #endif | 1485 | #endif |
1148 | return ivg->irqno; | 1486 | return ivg->irqno; |
1149 | } | 1487 | } |
1488 | #else | ||
1489 | /* for bf60x read */ | ||
1490 | return BFIN_IRQ(bfin_read_SEC_SCI(0, SEC_CSID)); | ||
1491 | #endif /* end of CONFIG_BF60x */ | ||
1150 | } | 1492 | } |
1151 | 1493 | ||
1152 | #ifdef CONFIG_DO_IRQ_L1 | 1494 | #ifdef CONFIG_DO_IRQ_L1 |