aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRandy Vinson <rvinson@mvista.com>2007-06-06 19:26:15 -0400
committerKumar Gala <galak@kernel.crashing.org>2007-07-23 23:34:40 -0400
commit3620fc1da28ad32d10d7c83eab33f48ec5b1da54 (patch)
treeea8fd966c21a23db7e5d2400f89587d7ff137bf3 /arch
parenteb12af43333dd9d54158f35147a79628c41152db (diff)
[POWERPC] 85xxCDS: Allow 8259 cascade to share an MPIC interrupt line.
The Freescale MPC8555CDS and MPC8548CDS reference hardware has a legacy 8259 interrupt controller pair contained within a VIA VT82C686B Southbridge on the main carrier board. The processor complex plugs into the carrier card using a PCI slot which limits the available interrupts to the INTA-INTD PCI interrupts. The output of the 8259 cascade pair is routed through a gate array and connected to the PCI INTA interrupt line. The normal interrupt chaining hook (set_irq_chained_handler) does not allow sharing of the chained interrupt which prevents the use of PCI INTA by PCI devices. This patch allows the 8259 cascade pair to share their interrupt line with PCI devices. NOTE: The addition of the .end routine for the MPIC is not strictly necessary for this patch. It's there so this code will run from within the threaded interrupt context used by the Real Time patch. Signed-off-by: Randy Vinson <rvinson@mvista.com> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/platforms/85xx/Kconfig1
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_cds.c37
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
18config MPC85xx_CDS 18config 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);
119DECLARE_PCI_FIXUP_EARLY(0xff3f, 0x5719, skip_fake_bridge); 120DECLARE_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 123static void mpc85xx_8259_cascade_handler(unsigned int irq,
123static 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
136static irqreturn_t mpc85xx_8259_cascade_action(int irq, void *dev_id)
137{
138 return IRQ_HANDLED;
139}
140
141static 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