aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc/syslib/ppc4xx_pic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ppc/syslib/ppc4xx_pic.c')
-rw-r--r--arch/ppc/syslib/ppc4xx_pic.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/arch/ppc/syslib/ppc4xx_pic.c b/arch/ppc/syslib/ppc4xx_pic.c
index 0b435633a0d1..aa4165144ec2 100644
--- a/arch/ppc/syslib/ppc4xx_pic.c
+++ b/arch/ppc/syslib/ppc4xx_pic.c
@@ -38,6 +38,7 @@ extern unsigned char ppc4xx_uic_ext_irq_cfg[] __attribute__ ((weak));
38#define IRQ_MASK_UICx(irq) (1 << (31 - ((irq) & 0x1f))) 38#define IRQ_MASK_UICx(irq) (1 << (31 - ((irq) & 0x1f)))
39#define IRQ_MASK_UIC1(irq) IRQ_MASK_UICx(irq) 39#define IRQ_MASK_UIC1(irq) IRQ_MASK_UICx(irq)
40#define IRQ_MASK_UIC2(irq) IRQ_MASK_UICx(irq) 40#define IRQ_MASK_UIC2(irq) IRQ_MASK_UICx(irq)
41#define IRQ_MASK_UIC3(irq) IRQ_MASK_UICx(irq)
41 42
42#define UIC_HANDLERS(n) \ 43#define UIC_HANDLERS(n) \
43static void ppc4xx_uic##n##_enable(unsigned int irq) \ 44static void ppc4xx_uic##n##_enable(unsigned int irq) \
@@ -88,7 +89,38 @@ static void ppc4xx_uic##n##_end(unsigned int irq) \
88 .end = ppc4xx_uic##n##_end, \ 89 .end = ppc4xx_uic##n##_end, \
89} \ 90} \
90 91
91#if NR_UICS == 3 92#if NR_UICS == 4
93#define ACK_UIC0_PARENT
94#define ACK_UIC1_PARENT mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC1NC);
95#define ACK_UIC2_PARENT mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC2NC);
96#define ACK_UIC3_PARENT mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC3NC);
97UIC_HANDLERS(0);
98UIC_HANDLERS(1);
99UIC_HANDLERS(2);
100UIC_HANDLERS(3);
101
102static int ppc4xx_pic_get_irq(struct pt_regs *regs)
103{
104 u32 uic0 = mfdcr(DCRN_UIC_MSR(UIC0));
105 if (uic0 & UIC0_UIC1NC)
106 return 64 - ffs(mfdcr(DCRN_UIC_MSR(UIC1)));
107 else if (uic0 & UIC0_UIC2NC)
108 return 96 - ffs(mfdcr(DCRN_UIC_MSR(UIC2)));
109 else if (uic0 & UIC0_UIC3NC)
110 return 128 - ffs(mfdcr(DCRN_UIC_MSR(UIC3)));
111 else
112 return uic0 ? 32 - ffs(uic0) : -1;
113}
114
115static void __init ppc4xx_pic_impl_init(void)
116{
117 /* Enable cascade interrupts in UIC0 */
118 ppc_cached_irq_mask[0] |= UIC0_UIC1NC | UIC0_UIC2NC | UIC0_UIC3NC;
119 mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC1NC | UIC0_UIC2NC | UIC0_UIC3NC);
120 mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[0]);
121}
122
123#elif NR_UICS == 3
92#define ACK_UIC0_PARENT mtdcr(DCRN_UIC_SR(UICB), UICB_UIC0NC); 124#define ACK_UIC0_PARENT mtdcr(DCRN_UIC_SR(UICB), UICB_UIC0NC);
93#define ACK_UIC1_PARENT mtdcr(DCRN_UIC_SR(UICB), UICB_UIC1NC); 125#define ACK_UIC1_PARENT mtdcr(DCRN_UIC_SR(UICB), UICB_UIC1NC);
94#define ACK_UIC2_PARENT mtdcr(DCRN_UIC_SR(UICB), UICB_UIC2NC); 126#define ACK_UIC2_PARENT mtdcr(DCRN_UIC_SR(UICB), UICB_UIC2NC);
@@ -170,6 +202,9 @@ static struct ppc4xx_uic_impl {
170 { .decl = DECLARE_UIC(1), .base = UIC1 }, 202 { .decl = DECLARE_UIC(1), .base = UIC1 },
171#if NR_UICS > 2 203#if NR_UICS > 2
172 { .decl = DECLARE_UIC(2), .base = UIC2 }, 204 { .decl = DECLARE_UIC(2), .base = UIC2 },
205#if NR_UICS > 3
206 { .decl = DECLARE_UIC(3), .base = UIC3 },
207#endif
173#endif 208#endif
174#endif 209#endif
175}; 210};