patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / arch / ppc / syslib / ppc4xx_pic.c
1 /*
2  *
3  *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
4  *
5  *    Module name: ppc4xx_pic.c
6  *
7  *    Description:
8  *      Interrupt controller driver for PowerPC 4xx-based processors.
9  */
10
11 /*
12  * The PowerPC 403 cores' Asynchronous Interrupt Controller (AIC) has
13  * 32 possible interrupts, a majority of which are not implemented on
14  * all cores. There are six configurable, external interrupt pins and
15  * there are eight internal interrupts for the on-chip serial port
16  * (SPU), DMA controller, and JTAG controller.
17  *
18  * The PowerPC 405/440 cores' Universal Interrupt Controller (UIC) has
19  * 32 possible interrupts as well.  Depending on the core and SoC
20  * implementation, a portion of the interrrupts are used for on-chip
21  * peripherals and a portion of the interrupts are available to be
22  * configured for external devices generating interrupts.
23  *
24  * The PowerNP and 440GP (and most likely future implementations) have
25  * cascaded UICs.
26  *
27  */
28
29 #include <linux/init.h>
30 #include <linux/sched.h>
31 #include <linux/signal.h>
32 #include <linux/stddef.h>
33
34 #include <asm/processor.h>
35 #include <asm/system.h>
36 #include <asm/irq.h>
37 #include <asm/ppc4xx_pic.h>
38
39 /* Global Variables */
40 struct hw_interrupt_type *ppc4xx_pic;
41 /*
42  * We define 4xxIRQ_InitSenses table thusly:
43  * bit 0x1: sense, 1 for edge and 0 for level.
44  * bit 0x2: polarity, 0 for negative, 1 for positive.
45  */
46 unsigned int ibm4xxPIC_NumInitSenses __initdata = 0;
47 unsigned char *ibm4xxPIC_InitSenses __initdata = NULL;
48
49 /* Six of one, half dozen of the other....#ifdefs, separate files,
50  * other tricks.....
51  *
52  * There are basically two types of interrupt controllers, the 403 AIC
53  * and the "others" with UIC.  I just kept them both here separated
54  * with #ifdefs, but it seems to change depending upon how supporting
55  * files (like ppc4xx.h) change.                -- Dan.
56  */
57
58 #ifdef CONFIG_403
59
60 /* Function Prototypes */
61
62 static void ppc403_aic_enable(unsigned int irq);
63 static void ppc403_aic_disable(unsigned int irq);
64 static void ppc403_aic_disable_and_ack(unsigned int irq);
65
66 static struct hw_interrupt_type ppc403_aic = {
67         "403GC AIC",
68         NULL,
69         NULL,
70         ppc403_aic_enable,
71         ppc403_aic_disable,
72         ppc403_aic_disable_and_ack,
73         0
74 };
75
76 int
77 ppc403_pic_get_irq(struct pt_regs *regs)
78 {
79         int irq;
80         unsigned long bits;
81
82         /*
83          * Only report the status of those interrupts that are actually
84          * enabled.
85          */
86
87         bits = mfdcr(DCRN_EXISR) & mfdcr(DCRN_EXIER);
88
89         /*
90          * Walk through the interrupts from highest priority to lowest, and
91          * report the first pending interrupt found.
92          * We want PPC, not C bit numbering, so just subtract the ffs()
93          * result from 32.
94          */
95         irq = 32 - ffs(bits);
96
97         if (irq == NR_AIC_IRQS)
98                 irq = -1;
99
100         return (irq);
101 }
102
103 static void
104 ppc403_aic_enable(unsigned int irq)
105 {
106         int bit, word;
107
108         bit = irq & 0x1f;
109         word = irq >> 5;
110
111         ppc_cached_irq_mask[word] |= (1 << (31 - bit));
112         mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]);
113 }
114
115 static void
116 ppc403_aic_disable(unsigned int irq)
117 {
118         int bit, word;
119
120         bit = irq & 0x1f;
121         word = irq >> 5;
122
123         ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
124         mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]);
125 }
126
127 static void
128 ppc403_aic_disable_and_ack(unsigned int irq)
129 {
130         int bit, word;
131
132         bit = irq & 0x1f;
133         word = irq >> 5;
134
135         ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
136         mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]);
137         mtdcr(DCRN_EXISR, (1 << (31 - bit)));
138 }
139
140 #else
141
142 #ifndef UIC1
143 #define UIC1 UIC0
144 #endif
145 #ifndef UIC2
146 #define UIC2 UIC1
147 #endif
148
149 static void
150 ppc4xx_uic_enable(unsigned int irq)
151 {
152         int bit, word;
153         irq_desc_t *desc = irq_desc + irq;
154
155         bit = irq & 0x1f;
156         word = irq >> 5;
157
158 #ifdef UIC_DEBUG
159         printk("ppc4xx_uic_enable - irq %d word %d bit 0x%x\n", irq, word, bit);
160 #endif
161         ppc_cached_irq_mask[word] |= 1 << (31 - bit);
162         switch (word) {
163         case 0:
164                 mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[word]);
165                 if ((mfdcr(DCRN_UIC_TR(UIC0)) & (1 << (31 - bit))) == 0)
166                         desc->status |= IRQ_LEVEL;
167                 else
168                         desc->status = desc->status & ~IRQ_LEVEL;
169                 break;
170         case 1:
171                 mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[word]);
172                 if ((mfdcr(DCRN_UIC_TR(UIC1)) & (1 << (31 - bit))) == 0)
173                         desc->status |= IRQ_LEVEL;
174                 else
175                         desc->status = desc->status & ~IRQ_LEVEL;
176                 break;
177         case 2:
178                 mtdcr(DCRN_UIC_ER(UIC2), ppc_cached_irq_mask[word]);
179                 if ((mfdcr(DCRN_UIC_TR(UIC2)) & (1 << (31 - bit))) == 0)
180                         desc->status |= IRQ_LEVEL;
181                 else
182                         desc->status = desc->status & ~IRQ_LEVEL;
183                 break;
184         }
185
186 }
187
188 static void
189 ppc4xx_uic_disable(unsigned int irq)
190 {
191         int bit, word;
192
193         bit = irq & 0x1f;
194         word = irq >> 5;
195 #ifdef UIC_DEBUG
196         printk("ppc4xx_uic_disable - irq %d word %d bit 0x%x\n", irq, word,
197                bit);
198 #endif
199         ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
200         switch (word) {
201         case 0:
202                 mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[word]);
203                 break;
204         case 1:
205                 mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[word]);
206                 break;
207         case 2:
208                 mtdcr(DCRN_UIC_ER(UIC2), ppc_cached_irq_mask[word]);
209                 break;
210         }
211 }
212
213 static void
214 ppc4xx_uic_disable_and_ack(unsigned int irq)
215 {
216         int bit, word;
217
218         bit = irq & 0x1f;
219         word = irq >> 5;
220
221 #ifdef UIC_DEBUG
222         printk("ppc4xx_uic_disable_and_ack - irq %d word %d bit 0x%x\n", irq,
223                word, bit);
224 #endif
225         ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
226         switch (word) {
227         case 0:
228                 mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[word]);
229                 mtdcr(DCRN_UIC_SR(UIC0), (1 << (31 - bit)));
230 #if (NR_UICS > 2)
231                 mtdcr(DCRN_UIC_SR(UICB), UICB_UIC0NC);
232 #endif
233                 break;
234         case 1:
235                 mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[word]);
236                 mtdcr(DCRN_UIC_SR(UIC1), (1 << (31 - bit)));
237 #if (NR_UICS > 2)
238                 mtdcr(DCRN_UIC_SR(UICB), UICB_UIC1NC);
239 #endif
240                 break;
241         case 2:
242                 mtdcr(DCRN_UIC_ER(UIC2), ppc_cached_irq_mask[word]);
243                 mtdcr(DCRN_UIC_SR(UIC2), (1 << (31 - bit)));
244 #if (NR_UICS > 2)
245                 mtdcr(DCRN_UIC_SR(UICB), UICB_UIC2NC);
246 #endif
247                 break;
248         }
249
250 }
251
252 static void
253 ppc4xx_uic_end(unsigned int irq)
254 {
255         int bit, word;
256         unsigned int tr_bits;
257
258         bit = irq & 0x1f;
259         word = irq >> 5;
260
261 #ifdef UIC_DEBUG
262         printk("ppc4xx_uic_end - irq %d word %d bit 0x%x\n", irq, word, bit);
263 #endif
264
265         switch (word) {
266         case 0:
267                 tr_bits = mfdcr(DCRN_UIC_TR(UIC0));
268                 break;
269         case 1:
270                 tr_bits = mfdcr(DCRN_UIC_TR(UIC1));
271                 break;
272         case 2:
273                 tr_bits = mfdcr(DCRN_UIC_TR(UIC2));
274                 break;
275         }
276
277         if ((tr_bits & (1 << (31 - bit))) == 0) {
278                 /* level trigger */
279                 switch (word) {
280                 case 0:
281                         mtdcr(DCRN_UIC_SR(UIC0), 1 << (31 - bit));
282 #if (NR_UICS > 2)
283                         mtdcr(DCRN_UIC_SR(UICB),  UICB_UIC0NC);
284 #endif
285                         break;
286                 case 1:
287                         mtdcr(DCRN_UIC_SR(UIC1), 1 << (31 - bit));
288 #if (NR_UICS > 2)
289                         mtdcr(DCRN_UIC_SR(UICB),  UICB_UIC1NC);
290 #endif
291                         break;
292                 case 2:
293                         mtdcr(DCRN_UIC_SR(UIC2), 1 << (31 - bit));
294 #if (NR_UICS > 2)
295                         mtdcr(DCRN_UIC_SR(UICB),  UICB_UIC2NC);
296 #endif
297                         break;
298                 }
299         }
300
301         if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
302                 ppc_cached_irq_mask[word] |= 1 << (31 - bit);
303                 switch (word) {
304                 case 0:
305                         mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[word]);
306                         break;
307                 case 1:
308                         mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[word]);
309                         break;
310                 case 2:
311                         mtdcr(DCRN_UIC_ER(UIC2), ppc_cached_irq_mask[word]);
312                         break;
313                 }
314         }
315 }
316
317 static struct hw_interrupt_type ppc4xx_uic = {
318 #if (NR_UICS == 1)
319         "IBM UIC",
320 #else
321         "IBM UIC Cascade",
322 #endif
323         NULL,
324         NULL,
325         ppc4xx_uic_enable,
326         ppc4xx_uic_disable,
327         ppc4xx_uic_disable_and_ack,
328         ppc4xx_uic_end,
329         0
330 };
331
332 int
333 ppc4xx_pic_get_irq(struct pt_regs *regs)
334 {
335         int irq, cas_irq;
336         unsigned long bits;
337         cas_irq = 0;
338         /*
339          * Only report the status of those interrupts that are actually
340          * enabled.
341          */
342
343 #if (NR_UICS > 2)
344         bits = mfdcr(DCRN_UIC_MSR(UICB));
345 #else
346         bits = mfdcr(DCRN_UIC_MSR(UIC0));
347 #endif
348 #if (NR_UICS > 2)
349         if (bits & UICB_UIC0NC) {
350                 bits = mfdcr(DCRN_UIC_MSR(UIC0));
351                 irq = 32 - ffs(bits);
352         } else if (bits & UICB_UIC1NC) {
353                 bits = mfdcr(DCRN_UIC_MSR(UIC1));
354                 irq = 64 - ffs(bits);
355         } else if (bits & UICB_UIC2NC) {
356                 bits = mfdcr(DCRN_UIC_MSR(UIC2));
357                 irq = 96 - ffs(bits);
358         } else {
359                 irq = -1;
360         }
361 #elif (NR_UICS > 1)
362         if (bits & UIC_CASCADE_MASK) {
363                 bits = mfdcr(DCRN_UIC_MSR(UIC1));
364                 cas_irq = 32 - ffs(bits);
365                 irq = 32 + cas_irq;
366         } else {
367                 irq = 32 - ffs(bits);
368                 if (irq == 32)
369                         irq = -1;
370         }
371 #else
372         /*
373          * Walk through the interrupts from highest priority to lowest, and
374          * report the first pending interrupt found.
375          * We want PPC, not C bit numbering, so just subtract the ffs()
376          * result from 32.
377          */
378         irq = 32 - ffs(bits);
379 #endif
380         if (irq == (NR_UIC_IRQS * NR_UICS))
381                 irq = -1;
382
383 #ifdef UIC_DEBUG
384         printk("ppc4xx_pic_get_irq - irq %d bit 0x%x\n", irq, bits);
385 #endif
386
387         return (irq);
388 }
389 #endif
390
391 void __init
392 ppc4xx_extpic_init(void)
393 {
394         /* set polarity
395          * 1 = default/pos/rising  , 0= neg/falling internal
396          * 1 = neg/falling , 0= pos/rising external
397          * Sense
398          * 0 = default level internal
399          * 0 = level, 1 = edge external
400          */
401
402         unsigned int sense, irq;
403         int bit, word;
404         unsigned long ppc_cached_sense_mask[NR_MASK_WORDS];
405         unsigned long ppc_cached_pol_mask[NR_MASK_WORDS];
406         ppc_cached_sense_mask[0] = 0;
407         ppc_cached_sense_mask[1] = 0;
408         ppc_cached_sense_mask[2] = 0;
409         ppc_cached_pol_mask[0] = 0;
410         ppc_cached_pol_mask[1] = 0;
411         ppc_cached_pol_mask[2] = 0;
412
413         for (irq = 0; irq < NR_IRQS; irq++) {
414
415                 bit = irq & 0x1f;
416                 word = irq >> 5;
417
418                 sense =
419                     (irq <
420                      ibm4xxPIC_NumInitSenses) ? ibm4xxPIC_InitSenses[irq] : 3;
421 #ifdef PPC4xx_PIC_DEBUG
422                 printk("PPC4xx_picext %d word:%x bit:%x sense:%x", irq, word,
423                        bit, sense);
424 #endif
425                 ppc_cached_sense_mask[word] |=
426                     (sense & IRQ_SENSE_MASK) << (31 - bit);
427                 ppc_cached_pol_mask[word] |=
428                     ((sense & IRQ_POLARITY_MASK) >> 1) << (31 - bit);
429                 switch (word) {
430                 case 0:
431 #ifdef PPC4xx_PIC_DEBUG
432                         printk("Pol %x ", mfdcr(DCRN_UIC_PR(UIC0)));
433                         printk("Level %x\n", mfdcr(DCRN_UIC_TR(UIC0)));
434 #endif
435                         /* polarity  setting */
436                         mtdcr(DCRN_UIC_PR(UIC0), ppc_cached_pol_mask[word]);
437
438                         /* Level setting */
439                         mtdcr(DCRN_UIC_TR(UIC0), ppc_cached_sense_mask[word]);
440
441                         break;
442                 case 1:
443 #ifdef PPC4xx_PIC_DEBUG
444                         printk("Pol %x ", mfdcr(DCRN_UIC_PR(UIC1)));
445                         printk("Level %x\n", mfdcr(DCRN_UIC_TR(UIC1)));
446 #endif
447                         /* polarity  setting */
448                         mtdcr(DCRN_UIC_PR(UIC1), ppc_cached_pol_mask[word]);
449
450                         /* Level setting */
451                         mtdcr(DCRN_UIC_TR(UIC1), ppc_cached_sense_mask[word]);
452
453                         break;
454                 case 2:
455 #ifdef PPC4xx_PIC_DEBUG
456                         printk("Pol %x ", mfdcr(DCRN_UIC_PR(UIC2)));
457                         printk("Level %x\n", mfdcr(DCRN_UIC_TR(UIC2)));
458 #endif
459                         /* polarity  setting */
460                         mtdcr(DCRN_UIC_PR(UIC2), ppc_cached_pol_mask[word]);
461
462                         /* Level setting */
463                         mtdcr(DCRN_UIC_TR(UIC2), ppc_cached_sense_mask[word]);
464
465                         break;
466                 }
467         }
468
469 }
470 void __init
471 ppc4xx_pic_init(void)
472 {
473         /*
474          * Disable all external interrupts until they are
475          * explicity requested.
476          */
477         ppc_cached_irq_mask[0] = 0;
478         ppc_cached_irq_mask[1] = 0;
479         ppc_cached_irq_mask[2] = 0;
480
481 #if defined CONFIG_403
482         mtdcr(DCRN_EXIER, ppc_cached_irq_mask[0]);
483
484         ppc4xx_pic = &ppc403_aic;
485         ppc_md.get_irq = ppc403_pic_get_irq;
486 #else
487 #if  (NR_UICS > 2)
488         mtdcr(DCRN_UIC_ER(UICB), UICB_UIC0NC | UICB_UIC1NC | UICB_UIC2NC);
489         mtdcr(DCRN_UIC_CR(UICB), 0);
490
491         mtdcr(DCRN_UIC_ER(UIC2), ppc_cached_irq_mask[2]);
492         mtdcr(DCRN_UIC_CR(UIC2), 0);
493
494 #endif
495 #if  (NR_UICS > 1)
496 #if  (NR_UICS == 2)
497         /* enable cascading interrupt */
498         ppc_cached_irq_mask[0] |= 1 << (31 - UIC0_UIC1NC);
499 #endif
500         mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[1]);
501         mtdcr(DCRN_UIC_CR(UIC1), 0);
502 #endif
503         mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[0]);
504         mtdcr(DCRN_UIC_CR(UIC0), 0);
505
506         if (ibm4xxPIC_InitSenses != NULL)
507                 ppc4xx_extpic_init();
508
509         /* Clear any pending interrupts */
510 #if (NR_UICS > 2)
511         mtdcr(DCRN_UIC_SR(UICB), 0xffffffff);
512         mtdcr(DCRN_UIC_SR(UIC2), 0xffffffff);
513 #endif
514 #if (NR_UICS > 1)
515         mtdcr(DCRN_UIC_SR(UIC1), 0xffffffff);
516 #endif
517         mtdcr(DCRN_UIC_SR(UIC0), 0xffffffff);
518
519         ppc4xx_pic = &ppc4xx_uic;
520         ppc_md.get_irq = ppc4xx_pic_get_irq;
521 #endif
522 }