diff options
Diffstat (limited to 'arch/ppc/syslib/ppc4xx_pic.c')
-rw-r--r-- | arch/ppc/syslib/ppc4xx_pic.c | 37 |
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) \ |
43 | static void ppc4xx_uic##n##_enable(unsigned int irq) \ | 44 | static 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); | ||
97 | UIC_HANDLERS(0); | ||
98 | UIC_HANDLERS(1); | ||
99 | UIC_HANDLERS(2); | ||
100 | UIC_HANDLERS(3); | ||
101 | |||
102 | static 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 | |||
115 | static 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 | }; |