diff options
| -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 | ||
