3 * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
5 * Module name: ppc4xx_pic.c
8 * Interrupt controller driver for PowerPC 4xx-based processors.
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.
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.
24 * The PowerNP and 440GP (and most likely future implementations) have
29 #include <linux/init.h>
30 #include <linux/sched.h>
31 #include <linux/signal.h>
32 #include <linux/stddef.h>
34 #include <asm/processor.h>
35 #include <asm/system.h>
37 #include <asm/ppc4xx_pic.h>
39 /* Global Variables */
40 struct hw_interrupt_type
*ppc4xx_pic
;
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.
46 unsigned int ibm4xxPIC_NumInitSenses __initdata
= 0;
47 unsigned char *ibm4xxPIC_InitSenses __initdata
= NULL
;
49 /* Six of one, half dozen of the other....#ifdefs, separate files,
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.
60 /* Function Prototypes */
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
);
66 static struct hw_interrupt_type ppc403_aic
= {
72 ppc403_aic_disable_and_ack
,
77 ppc403_pic_get_irq(struct pt_regs
*regs
)
83 * Only report the status of those interrupts that are actually
87 bits
= mfdcr(DCRN_EXISR
) & mfdcr(DCRN_EXIER
);
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()
97 if (irq
== NR_AIC_IRQS
)
104 ppc403_aic_enable(unsigned int irq
)
111 ppc_cached_irq_mask
[word
] |= (1 << (31 - bit
));
112 mtdcr(DCRN_EXIER
, ppc_cached_irq_mask
[word
]);
116 ppc403_aic_disable(unsigned int irq
)
123 ppc_cached_irq_mask
[word
] &= ~(1 << (31 - bit
));
124 mtdcr(DCRN_EXIER
, ppc_cached_irq_mask
[word
]);
128 ppc403_aic_disable_and_ack(unsigned int irq
)
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
)));
150 ppc4xx_uic_enable(unsigned int irq
)
153 irq_desc_t
*desc
= irq_desc
+ irq
;
159 printk("ppc4xx_uic_enable - irq %d word %d bit 0x%x\n", irq
, word
, bit
);
161 ppc_cached_irq_mask
[word
] |= 1 << (31 - bit
);
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
;
168 desc
->status
= desc
->status
& ~IRQ_LEVEL
;
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
;
175 desc
->status
= desc
->status
& ~IRQ_LEVEL
;
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
;
182 desc
->status
= desc
->status
& ~IRQ_LEVEL
;
189 ppc4xx_uic_disable(unsigned int irq
)
196 printk("ppc4xx_uic_disable - irq %d word %d bit 0x%x\n", irq
, word
,
199 ppc_cached_irq_mask
[word
] &= ~(1 << (31 - bit
));
202 mtdcr(DCRN_UIC_ER(UIC0
), ppc_cached_irq_mask
[word
]);
205 mtdcr(DCRN_UIC_ER(UIC1
), ppc_cached_irq_mask
[word
]);
208 mtdcr(DCRN_UIC_ER(UIC2
), ppc_cached_irq_mask
[word
]);
214 ppc4xx_uic_disable_and_ack(unsigned int irq
)
222 printk("ppc4xx_uic_disable_and_ack - irq %d word %d bit 0x%x\n", irq
,
225 ppc_cached_irq_mask
[word
] &= ~(1 << (31 - bit
));
228 mtdcr(DCRN_UIC_ER(UIC0
), ppc_cached_irq_mask
[word
]);
229 mtdcr(DCRN_UIC_SR(UIC0
), (1 << (31 - bit
)));
231 mtdcr(DCRN_UIC_SR(UICB
), UICB_UIC0NC
);
235 mtdcr(DCRN_UIC_ER(UIC1
), ppc_cached_irq_mask
[word
]);
236 mtdcr(DCRN_UIC_SR(UIC1
), (1 << (31 - bit
)));
238 mtdcr(DCRN_UIC_SR(UIC0
), (1 << (31 - UIC0_UIC1NC
)));
241 mtdcr(DCRN_UIC_SR(UICB
), UICB_UIC1NC
);
245 mtdcr(DCRN_UIC_ER(UIC2
), ppc_cached_irq_mask
[word
]);
246 mtdcr(DCRN_UIC_SR(UIC2
), (1 << (31 - bit
)));
248 mtdcr(DCRN_UIC_SR(UICB
), UICB_UIC2NC
);
256 ppc4xx_uic_end(unsigned int irq
)
259 unsigned int tr_bits
= 0;
265 printk("ppc4xx_uic_end - irq %d word %d bit 0x%x\n", irq
, word
, bit
);
270 tr_bits
= mfdcr(DCRN_UIC_TR(UIC0
));
273 tr_bits
= mfdcr(DCRN_UIC_TR(UIC1
));
276 tr_bits
= mfdcr(DCRN_UIC_TR(UIC2
));
280 if ((tr_bits
& (1 << (31 - bit
))) == 0) {
284 mtdcr(DCRN_UIC_SR(UIC0
), 1 << (31 - bit
));
286 mtdcr(DCRN_UIC_SR(UICB
), UICB_UIC0NC
);
290 mtdcr(DCRN_UIC_SR(UIC1
), 1 << (31 - bit
));
292 mtdcr(DCRN_UIC_SR(UIC0
), (1 << (31 - UIC0_UIC1NC
)));
295 mtdcr(DCRN_UIC_SR(UICB
), UICB_UIC1NC
);
299 mtdcr(DCRN_UIC_SR(UIC2
), 1 << (31 - bit
));
301 mtdcr(DCRN_UIC_SR(UICB
), UICB_UIC2NC
);
307 if (!(irq_desc
[irq
].status
& (IRQ_DISABLED
| IRQ_INPROGRESS
))) {
308 ppc_cached_irq_mask
[word
] |= 1 << (31 - bit
);
311 mtdcr(DCRN_UIC_ER(UIC0
), ppc_cached_irq_mask
[word
]);
314 mtdcr(DCRN_UIC_ER(UIC1
), ppc_cached_irq_mask
[word
]);
317 mtdcr(DCRN_UIC_ER(UIC2
), ppc_cached_irq_mask
[word
]);
323 static struct hw_interrupt_type ppc4xx_uic
= {
333 ppc4xx_uic_disable_and_ack
,
339 ppc4xx_pic_get_irq(struct pt_regs
*regs
)
345 * Only report the status of those interrupts that are actually
350 bits
= mfdcr(DCRN_UIC_MSR(UICB
));
352 bits
= mfdcr(DCRN_UIC_MSR(UIC0
));
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
);
368 if (bits
& UIC_CASCADE_MASK
) {
369 bits
= mfdcr(DCRN_UIC_MSR(UIC1
));
370 cas_irq
= 32 - ffs(bits
);
373 irq
= 32 - ffs(bits
);
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()
384 irq
= 32 - ffs(bits
);
386 if (irq
== (NR_UIC_IRQS
* NR_UICS
))
390 printk("ppc4xx_pic_get_irq - irq %d bit 0x%x\n", irq
, bits
);
398 ppc4xx_extpic_init(void)
401 * 1 = default/pos/rising , 0= neg/falling internal
402 * 1 = neg/falling , 0= pos/rising external
404 * 0 = default level internal
405 * 0 = level, 1 = edge external
408 unsigned int sense
, irq
;
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;
419 for (irq
= 0; irq
< NR_IRQS
; 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
,
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
);
437 #ifdef PPC4xx_PIC_DEBUG
438 printk("Pol %x ", mfdcr(DCRN_UIC_PR(UIC0
)));
439 printk("Level %x\n", mfdcr(DCRN_UIC_TR(UIC0
)));
441 /* polarity setting */
442 mtdcr(DCRN_UIC_PR(UIC0
), ppc_cached_pol_mask
[word
]);
445 mtdcr(DCRN_UIC_TR(UIC0
), ppc_cached_sense_mask
[word
]);
449 #ifdef PPC4xx_PIC_DEBUG
450 printk("Pol %x ", mfdcr(DCRN_UIC_PR(UIC1
)));
451 printk("Level %x\n", mfdcr(DCRN_UIC_TR(UIC1
)));
453 /* polarity setting */
454 mtdcr(DCRN_UIC_PR(UIC1
), ppc_cached_pol_mask
[word
]);
457 mtdcr(DCRN_UIC_TR(UIC1
), ppc_cached_sense_mask
[word
]);
461 #ifdef PPC4xx_PIC_DEBUG
462 printk("Pol %x ", mfdcr(DCRN_UIC_PR(UIC2
)));
463 printk("Level %x\n", mfdcr(DCRN_UIC_TR(UIC2
)));
465 /* polarity setting */
466 mtdcr(DCRN_UIC_PR(UIC2
), ppc_cached_pol_mask
[word
]);
469 mtdcr(DCRN_UIC_TR(UIC2
), ppc_cached_sense_mask
[word
]);
477 ppc4xx_pic_init(void)
480 * Disable all external interrupts until they are
481 * explicity requested.
483 ppc_cached_irq_mask
[0] = 0;
484 ppc_cached_irq_mask
[1] = 0;
485 ppc_cached_irq_mask
[2] = 0;
487 #if defined CONFIG_403
488 mtdcr(DCRN_EXIER
, ppc_cached_irq_mask
[0]);
490 ppc4xx_pic
= &ppc403_aic
;
491 ppc_md
.get_irq
= ppc403_pic_get_irq
;
494 mtdcr(DCRN_UIC_ER(UICB
), UICB_UIC0NC
| UICB_UIC1NC
| UICB_UIC2NC
);
495 mtdcr(DCRN_UIC_CR(UICB
), 0);
497 mtdcr(DCRN_UIC_ER(UIC2
), ppc_cached_irq_mask
[2]);
498 mtdcr(DCRN_UIC_CR(UIC2
), 0);
503 /* enable cascading interrupt */
504 ppc_cached_irq_mask
[0] |= 1 << (31 - UIC0_UIC1NC
);
506 mtdcr(DCRN_UIC_ER(UIC1
), ppc_cached_irq_mask
[1]);
507 mtdcr(DCRN_UIC_CR(UIC1
), 0);
509 mtdcr(DCRN_UIC_ER(UIC0
), ppc_cached_irq_mask
[0]);
510 mtdcr(DCRN_UIC_CR(UIC0
), 0);
512 if (ibm4xxPIC_InitSenses
!= NULL
)
513 ppc4xx_extpic_init();
515 /* Clear any pending interrupts */
517 mtdcr(DCRN_UIC_SR(UICB
), 0xffffffff);
518 mtdcr(DCRN_UIC_SR(UIC2
), 0xffffffff);
521 mtdcr(DCRN_UIC_SR(UIC1
), 0xffffffff);
523 mtdcr(DCRN_UIC_SR(UIC0
), 0xffffffff);
525 ppc4xx_pic
= &ppc4xx_uic
;
526 ppc_md
.get_irq
= ppc4xx_pic_get_irq
;