vserver 1.9.3
[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(UIC0), (1 << (31 - UIC0_UIC1NC)));
239 #endif
240 #if (NR_UICS > 2)
241                 mtdcr(DCRN_UIC_SR(UICB), UICB_UIC1NC);
242 #endif
243                 break;
244         case 2:
245                 mtdcr(DCRN_UIC_ER(UIC2), ppc_cached_irq_mask[word]);
246                 mtdcr(DCRN_UIC_SR(UIC2), (1 << (31 - bit)));
247 #if (NR_UICS > 2)
248                 mtdcr(DCRN_UIC_SR(UICB), UICB_UIC2NC);
249 #endif
250                 break;
251         }
252
253 }
254
255 static void
256 ppc4xx_uic_end(unsigned int irq)
257 {
258         int bit, word;
259         unsigned int tr_bits = 0;
260
261         bit = irq & 0x1f;
262         word = irq >> 5;
263
264 #ifdef UIC_DEBUG
265         printk("ppc4xx_uic_end - irq %d word %d bit 0x%x\n", irq, word, bit);
266 #endif
267
268         switch (word) {
269         case 0:
270                 tr_bits = mfdcr(DCRN_UIC_TR(UIC0));
271                 break;
272         case 1:
273                 tr_bits = mfdcr(DCRN_UIC_TR(UIC1));
274                 break;
275         case 2:
276                 tr_bits = mfdcr(DCRN_UIC_TR(UIC2));
277                 break;
278         }
279
280         if ((tr_bits & (1 << (31 - bit))) == 0) {
281                 /* level trigger */
282                 switch (word) {
283                 case 0:
284                         mtdcr(DCRN_UIC_SR(UIC0), 1 << (31 - bit));
285 #if (NR_UICS > 2)
286                         mtdcr(DCRN_UIC_SR(UICB),  UICB_UIC0NC);
287 #endif
288                         break;
289                 case 1:
290                         mtdcr(DCRN_UIC_SR(UIC1), 1 << (31 - bit));
291 #if (NR_UICS == 2)
292                         mtdcr(DCRN_UIC_SR(UIC0), (1 << (31 - UIC0_UIC1NC)));
293 #endif
294 #if (NR_UICS > 2)
295                         mtdcr(DCRN_UIC_SR(UICB),  UICB_UIC1NC);
296 #endif
297                         break;
298                 case 2:
299                         mtdcr(DCRN_UIC_SR(UIC2), 1 << (31 - bit));
300 #if (NR_UICS > 2)
301                         mtdcr(DCRN_UIC_SR(UICB),  UICB_UIC2NC);
302 #endif
303                         break;
304                 }
305         }
306
307         if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
308                 ppc_cached_irq_mask[word] |= 1 << (31 - bit);
309                 switch (word) {
310                 case 0:
311                         mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[word]);
312                         break;
313                 case 1:
314                         mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[word]);
315                         break;
316                 case 2:
317                         mtdcr(DCRN_UIC_ER(UIC2), ppc_cached_irq_mask[word]);
318                         break;
319                 }
320         }
321 }
322
323 static struct hw_interrupt_type ppc4xx_uic = {
324 #if (NR_UICS == 1)
325         "IBM UIC",
326 #else
327         "IBM UIC Cascade",
328 #endif
329         NULL,
330         NULL,
331         ppc4xx_uic_enable,
332         ppc4xx_uic_disable,
333         ppc4xx_uic_disable_and_ack,
334         ppc4xx_uic_end,
335         0
336 };
337
338 int
339 ppc4xx_pic_get_irq(struct pt_regs *regs)
340 {
341         int irq, cas_irq;
342         unsigned long bits;
343         cas_irq = 0;
344         /*
345          * Only report the status of those interrupts that are actually
346          * enabled.
347          */
348
349 #if (NR_UICS > 2)
350         bits = mfdcr(DCRN_UIC_MSR(UICB));
351 #else
352         bits = mfdcr(DCRN_UIC_MSR(UIC0));
353 #endif
354 #if (NR_UICS > 2)
355         if (bits & UICB_UIC0NC) {
356                 bits = mfdcr(DCRN_UIC_MSR(UIC0));
357                 irq = 32 - ffs(bits);
358         } else if (bits & UICB_UIC1NC) {
359                 bits = mfdcr(DCRN_UIC_MSR(UIC1));
360                 irq = 64 - ffs(bits);
361         } else if (bits & UICB_UIC2NC) {
362                 bits = mfdcr(DCRN_UIC_MSR(UIC2));
363                 irq = 96 - ffs(bits);
364         } else {
365                 irq = -1;
366         }
367 #elif (NR_UICS > 1)
368         if (bits & UIC_CASCADE_MASK) {
369                 bits = mfdcr(DCRN_UIC_MSR(UIC1));
370                 cas_irq = 32 - ffs(bits);
371                 irq = 32 + cas_irq;
372         } else {
373                 irq = 32 - ffs(bits);
374                 if (irq == 32)
375                         irq = -1;
376         }
377 #else
378         /*
379          * Walk through the interrupts from highest priority to lowest, and
380          * report the first pending interrupt found.
381          * We want PPC, not C bit numbering, so just subtract the ffs()
382          * result from 32.
383          */
384         irq = 32 - ffs(bits);
385 #endif
386         if (irq == (NR_UIC_IRQS * NR_UICS))
387                 irq = -1;
388
389 #ifdef UIC_DEBUG
390         printk("ppc4xx_pic_get_irq - irq %d bit 0x%x\n", irq, bits);
391 #endif
392
393         return (irq);
394 }
395 #endif
396
397 void __init
398 ppc4xx_extpic_init(void)
399 {
400         /* set polarity
401          * 1 = default/pos/rising  , 0= neg/falling internal
402          * 1 = neg/falling , 0= pos/rising external
403          * Sense
404          * 0 = default level internal
405          * 0 = level, 1 = edge external
406          */
407
408         unsigned int sense, irq;
409         int bit, word;
410         unsigned long ppc_cached_sense_mask[NR_MASK_WORDS];
411         unsigned long ppc_cached_pol_mask[NR_MASK_WORDS];
412         ppc_cached_sense_mask[0] = 0;
413         ppc_cached_sense_mask[1] = 0;
414         ppc_cached_sense_mask[2] = 0;
415         ppc_cached_pol_mask[0] = 0;
416         ppc_cached_pol_mask[1] = 0;
417         ppc_cached_pol_mask[2] = 0;
418
419         for (irq = 0; irq < NR_IRQS; irq++) {
420
421                 bit = irq & 0x1f;
422                 word = irq >> 5;
423
424                 sense =
425                     (irq <
426                      ibm4xxPIC_NumInitSenses) ? ibm4xxPIC_InitSenses[irq] : 3;
427 #ifdef PPC4xx_PIC_DEBUG
428                 printk("PPC4xx_picext %d word:%x bit:%x sense:%x", irq, word,
429                        bit, sense);
430 #endif
431                 ppc_cached_sense_mask[word] |=
432                     (~sense & IRQ_SENSE_MASK) << (31 - bit);
433                 ppc_cached_pol_mask[word] |=
434                     ((sense & IRQ_POLARITY_MASK) >> 1) << (31 - bit);
435                 switch (word) {
436                 case 0:
437 #ifdef PPC4xx_PIC_DEBUG
438                         printk("Pol %x ", mfdcr(DCRN_UIC_PR(UIC0)));
439                         printk("Level %x\n", mfdcr(DCRN_UIC_TR(UIC0)));
440 #endif
441                         /* polarity  setting */
442                         mtdcr(DCRN_UIC_PR(UIC0), ppc_cached_pol_mask[word]);
443
444                         /* Level setting */
445                         mtdcr(DCRN_UIC_TR(UIC0), ppc_cached_sense_mask[word]);
446
447                         break;
448                 case 1:
449 #ifdef PPC4xx_PIC_DEBUG
450                         printk("Pol %x ", mfdcr(DCRN_UIC_PR(UIC1)));
451                         printk("Level %x\n", mfdcr(DCRN_UIC_TR(UIC1)));
452 #endif
453                         /* polarity  setting */
454                         mtdcr(DCRN_UIC_PR(UIC1), ppc_cached_pol_mask[word]);
455
456                         /* Level setting */
457                         mtdcr(DCRN_UIC_TR(UIC1), ppc_cached_sense_mask[word]);
458
459                         break;
460                 case 2:
461 #ifdef PPC4xx_PIC_DEBUG
462                         printk("Pol %x ", mfdcr(DCRN_UIC_PR(UIC2)));
463                         printk("Level %x\n", mfdcr(DCRN_UIC_TR(UIC2)));
464 #endif
465                         /* polarity  setting */
466                         mtdcr(DCRN_UIC_PR(UIC2), ppc_cached_pol_mask[word]);
467
468                         /* Level setting */
469                         mtdcr(DCRN_UIC_TR(UIC2), ppc_cached_sense_mask[word]);
470
471                         break;
472                 }
473         }
474
475 }
476 void __init
477 ppc4xx_pic_init(void)
478 {
479         /*
480          * Disable all external interrupts until they are
481          * explicity requested.
482          */
483         ppc_cached_irq_mask[0] = 0;
484         ppc_cached_irq_mask[1] = 0;
485         ppc_cached_irq_mask[2] = 0;
486
487 #if defined CONFIG_403
488         mtdcr(DCRN_EXIER, ppc_cached_irq_mask[0]);
489
490         ppc4xx_pic = &ppc403_aic;
491         ppc_md.get_irq = ppc403_pic_get_irq;
492 #else
493 #if  (NR_UICS > 2)
494         mtdcr(DCRN_UIC_ER(UICB), UICB_UIC0NC | UICB_UIC1NC | UICB_UIC2NC);
495         mtdcr(DCRN_UIC_CR(UICB), 0);
496
497         mtdcr(DCRN_UIC_ER(UIC2), ppc_cached_irq_mask[2]);
498         mtdcr(DCRN_UIC_CR(UIC2), 0);
499
500 #endif
501 #if  (NR_UICS > 1)
502 #if  (NR_UICS == 2)
503         /* enable cascading interrupt */
504         ppc_cached_irq_mask[0] |= 1 << (31 - UIC0_UIC1NC);
505 #endif
506         mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[1]);
507         mtdcr(DCRN_UIC_CR(UIC1), 0);
508 #endif
509         mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[0]);
510         mtdcr(DCRN_UIC_CR(UIC0), 0);
511
512         if (ibm4xxPIC_InitSenses != NULL)
513                 ppc4xx_extpic_init();
514
515         /* Clear any pending interrupts */
516 #if (NR_UICS > 2)
517         mtdcr(DCRN_UIC_SR(UICB), 0xffffffff);
518         mtdcr(DCRN_UIC_SR(UIC2), 0xffffffff);
519 #endif
520 #if (NR_UICS > 1)
521         mtdcr(DCRN_UIC_SR(UIC1), 0xffffffff);
522 #endif
523         mtdcr(DCRN_UIC_SR(UIC0), 0xffffffff);
524
525         ppc4xx_pic = &ppc4xx_uic;
526         ppc_md.get_irq = ppc4xx_pic_get_irq;
527 #endif
528 }