diff options
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r-- | arch/powerpc/platforms/85xx/Kconfig | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/mpc85xx_cds.c | 37 |
2 files changed, 32 insertions, 6 deletions
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index 99bb74da0760..f58184086c8c 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig | |||
@@ -18,6 +18,7 @@ config MPC8560_ADS | |||
18 | config MPC85xx_CDS | 18 | config MPC85xx_CDS |
19 | bool "Freescale MPC85xx CDS" | 19 | bool "Freescale MPC85xx CDS" |
20 | select DEFAULT_UIMAGE | 20 | select DEFAULT_UIMAGE |
21 | select PPC_I8259 | ||
21 | help | 22 | help |
22 | This option enables support for the MPC85xx CDS board | 23 | This option enables support for the MPC85xx CDS board |
23 | 24 | ||
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c index 71200bdce05a..81b70628df75 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/seq_file.h> | 24 | #include <linux/seq_file.h> |
25 | #include <linux/initrd.h> | 25 | #include <linux/initrd.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/interrupt.h> | ||
27 | #include <linux/fsl_devices.h> | 28 | #include <linux/fsl_devices.h> |
28 | 29 | ||
29 | #include <asm/system.h> | 30 | #include <asm/system.h> |
@@ -119,16 +120,30 @@ DECLARE_PCI_FIXUP_EARLY(0x3fff, 0x1957, skip_fake_bridge); | |||
119 | DECLARE_PCI_FIXUP_EARLY(0xff3f, 0x5719, skip_fake_bridge); | 120 | DECLARE_PCI_FIXUP_EARLY(0xff3f, 0x5719, skip_fake_bridge); |
120 | 121 | ||
121 | #ifdef CONFIG_PPC_I8259 | 122 | #ifdef CONFIG_PPC_I8259 |
122 | #warning The i8259 PIC support is currently broken | 123 | static void mpc85xx_8259_cascade_handler(unsigned int irq, |
123 | static void mpc85xx_8259_cascade(unsigned int irq, struct irq_desc *desc) | 124 | struct irq_desc *desc) |
124 | { | 125 | { |
125 | unsigned int cascade_irq = i8259_irq(); | 126 | unsigned int cascade_irq = i8259_irq(); |
126 | 127 | ||
127 | if (cascade_irq != NO_IRQ) | 128 | if (cascade_irq != NO_IRQ) |
129 | /* handle an interrupt from the 8259 */ | ||
128 | generic_handle_irq(cascade_irq); | 130 | generic_handle_irq(cascade_irq); |
129 | 131 | ||
130 | desc->chip->eoi(irq); | 132 | /* check for any interrupts from the shared IRQ line */ |
133 | handle_fasteoi_irq(irq, desc); | ||
131 | } | 134 | } |
135 | |||
136 | static irqreturn_t mpc85xx_8259_cascade_action(int irq, void *dev_id) | ||
137 | { | ||
138 | return IRQ_HANDLED; | ||
139 | } | ||
140 | |||
141 | static struct irqaction mpc85xxcds_8259_irqaction = { | ||
142 | .handler = mpc85xx_8259_cascade_action, | ||
143 | .flags = IRQF_SHARED, | ||
144 | .mask = CPU_MASK_NONE, | ||
145 | .name = "8259 cascade", | ||
146 | }; | ||
132 | #endif /* PPC_I8259 */ | 147 | #endif /* PPC_I8259 */ |
133 | #endif /* CONFIG_PCI */ | 148 | #endif /* CONFIG_PCI */ |
134 | 149 | ||
@@ -137,7 +152,7 @@ static void __init mpc85xx_cds_pic_init(void) | |||
137 | struct mpic *mpic; | 152 | struct mpic *mpic; |
138 | struct resource r; | 153 | struct resource r; |
139 | struct device_node *np = NULL; | 154 | struct device_node *np = NULL; |
140 | #ifdef CONFIG_PPC_I8259 | 155 | #if defined(CONFIG_PPC_I8259) && defined(CONFIG_PCI) |
141 | struct device_node *cascade_node = NULL; | 156 | struct device_node *cascade_node = NULL; |
142 | int cascade_irq; | 157 | int cascade_irq; |
143 | #endif | 158 | #endif |
@@ -165,7 +180,7 @@ static void __init mpc85xx_cds_pic_init(void) | |||
165 | 180 | ||
166 | mpic_init(mpic); | 181 | mpic_init(mpic); |
167 | 182 | ||
168 | #ifdef CONFIG_PPC_I8259 | 183 | #if defined(CONFIG_PPC_I8259) && defined(CONFIG_PCI) |
169 | /* Initialize the i8259 controller */ | 184 | /* Initialize the i8259 controller */ |
170 | for_each_node_by_type(np, "interrupt-controller") | 185 | for_each_node_by_type(np, "interrupt-controller") |
171 | if (of_device_is_compatible(np, "chrp,iic")) { | 186 | if (of_device_is_compatible(np, "chrp,iic")) { |
@@ -187,7 +202,17 @@ static void __init mpc85xx_cds_pic_init(void) | |||
187 | i8259_init(cascade_node, 0); | 202 | i8259_init(cascade_node, 0); |
188 | of_node_put(cascade_node); | 203 | of_node_put(cascade_node); |
189 | 204 | ||
190 | set_irq_chained_handler(cascade_irq, mpc85xx_8259_cascade); | 205 | /* |
206 | * Hook the interrupt to make sure desc->action is never NULL. | ||
207 | * This is required to ensure that the interrupt does not get | ||
208 | * disabled when the last user of the shared IRQ line frees their | ||
209 | * interrupt. | ||
210 | */ | ||
211 | if (setup_irq(cascade_irq, &mpc85xxcds_8259_irqaction)) | ||
212 | printk(KERN_ERR "Failed to setup cascade interrupt\n"); | ||
213 | else | ||
214 | /* Success. Connect our low-level cascade handler. */ | ||
215 | set_irq_handler(cascade_irq, mpc85xx_8259_cascade_handler); | ||
191 | #endif /* CONFIG_PPC_I8259 */ | 216 | #endif /* CONFIG_PPC_I8259 */ |
192 | } | 217 | } |
193 | 218 | ||