Commit 6c4f928b authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ppc32: Add openpic_hookup_cascade()

From: Tom Rini <trini@kernel.crashing.org>

This patch adds openpic_hookup_cascade(offset, name, handler) which allows for
an arbitrary interrupt controller to be hooked up as a cascade to the openpic.
 This also allows for platforms to just not have a cascaded controller.
parent 9be15f90
...@@ -407,6 +407,9 @@ void __init chrp_init_IRQ(void) ...@@ -407,6 +407,9 @@ void __init chrp_init_IRQ(void)
OpenPIC_NumInitSenses = NR_IRQS - NUM_8259_INTERRUPTS; OpenPIC_NumInitSenses = NR_IRQS - NUM_8259_INTERRUPTS;
openpic_init(NUM_8259_INTERRUPTS); openpic_init(NUM_8259_INTERRUPTS);
/* We have a cascade on OpenPIC IRQ 0, Linux IRQ 16 */
openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
i8259_irq);
for (i = 0; i < NUM_8259_INTERRUPTS; i++) for (i = 0; i < NUM_8259_INTERRUPTS; i++)
irq_desc[i].handler = &i8259_pic; irq_desc[i].handler = &i8259_pic;
......
...@@ -208,6 +208,9 @@ lopec_init_IRQ(void) ...@@ -208,6 +208,9 @@ lopec_init_IRQ(void)
openpic_set_sources(19, 1, OpenPIC_Addr + 0x110C0); openpic_set_sources(19, 1, OpenPIC_Addr + 0x110C0);
openpic_init(NUM_8259_INTERRUPTS); openpic_init(NUM_8259_INTERRUPTS);
/* We have a cascade on OpenPIC IRQ 0, Linux IRQ 16 */
openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
&i8259_irq);
/* Map i8259 interrupts */ /* Map i8259 interrupts */
for(i = 0; i < NUM_8259_INTERRUPTS; i++) for(i = 0; i < NUM_8259_INTERRUPTS; i++)
......
...@@ -30,9 +30,6 @@ ...@@ -30,9 +30,6 @@
#include <linux/console.h> #include <linux/console.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/irq.h> #include <linux/irq.h>
#if 0
#include <linux/ide.h>
#endif
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/root_dev.h> #include <linux/root_dev.h>
#include <linux/serial.h> #include <linux/serial.h>
...@@ -385,6 +382,8 @@ mcpn765_init_IRQ(void) ...@@ -385,6 +382,8 @@ mcpn765_init_IRQ(void)
ppc_md.progress("init_irq: enter", 0); ppc_md.progress("init_irq: enter", 0);
openpic_init(NUM_8259_INTERRUPTS); openpic_init(NUM_8259_INTERRUPTS);
openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
i8259_irq);
for(i=0; i < NUM_8259_INTERRUPTS; i++) for(i=0; i < NUM_8259_INTERRUPTS; i++)
irq_desc[i].handler = &i8259_pic; irq_desc[i].handler = &i8259_pic;
......
...@@ -138,6 +138,7 @@ mvme5100_init_IRQ(void) ...@@ -138,6 +138,7 @@ mvme5100_init_IRQ(void)
#ifdef CONFIG_MVME5100_IPMC761_PRESENT #ifdef CONFIG_MVME5100_IPMC761_PRESENT
openpic_init(1, NUM_8259_INTERRUPTS, NULL, -1); openpic_init(1, NUM_8259_INTERRUPTS, NULL, -1);
openpic_hookup_cascade(NUM_8259_INTERRUPTS,"82c59 cascade",&i8259_irq);
for(i=0; i < NUM_8259_INTERRUPTS; i++) for(i=0; i < NUM_8259_INTERRUPTS; i++)
irq_desc[i].handler = &i8259_pic; irq_desc[i].handler = &i8259_pic;
......
...@@ -672,6 +672,8 @@ static void __init pplus_init_IRQ(void) ...@@ -672,6 +672,8 @@ static void __init pplus_init_IRQ(void)
openpic_set_sources(0, 16, OpenPIC_Addr + 0x10000); openpic_set_sources(0, 16, OpenPIC_Addr + 0x10000);
openpic_init(NUM_8259_INTERRUPTS); openpic_init(NUM_8259_INTERRUPTS);
openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
i8259_irq);
ppc_md.get_irq = openpic_get_irq; ppc_md.get_irq = openpic_get_irq;
} }
......
...@@ -856,8 +856,12 @@ prep_init_IRQ(void) ...@@ -856,8 +856,12 @@ prep_init_IRQ(void)
int i; int i;
unsigned int pci_viddid, pci_did; unsigned int pci_viddid, pci_did;
if (OpenPIC_Addr != NULL) if (OpenPIC_Addr != NULL) {
openpic_init(NUM_8259_INTERRUPTS); openpic_init(NUM_8259_INTERRUPTS);
/* We have a cascade on OpenPIC IRQ 0, Linux IRQ 16 */
openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
i8259_irq);
}
for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ ) for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ )
irq_desc[i].handler = &i8259_pic; irq_desc[i].handler = &i8259_pic;
/* If we have a Raven PCI bridge or a Hawk PCI bridge / Memory /* If we have a Raven PCI bridge or a Hawk PCI bridge / Memory
......
...@@ -444,6 +444,8 @@ sandpoint_init_IRQ(void) ...@@ -444,6 +444,8 @@ sandpoint_init_IRQ(void)
openpic_set_sources(0, 16, OpenPIC_Addr + 0x10200); openpic_set_sources(0, 16, OpenPIC_Addr + 0x10200);
openpic_init(NUM_8259_INTERRUPTS); openpic_init(NUM_8259_INTERRUPTS);
openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
i8259_irq);
/* /*
* openpic_init() has set up irq_desc[16-31] to be openpic * openpic_init() has set up irq_desc[16-31] to be openpic
......
...@@ -39,7 +39,7 @@ obj-$(CONFIG_ADIR) += i8259.o indirect_pci.o pci_auto.o \ ...@@ -39,7 +39,7 @@ obj-$(CONFIG_ADIR) += i8259.o indirect_pci.o pci_auto.o \
obj-$(CONFIG_EBONY) += indirect_pci.o pci_auto.o todc_time.o obj-$(CONFIG_EBONY) += indirect_pci.o pci_auto.o todc_time.o
obj-$(CONFIG_EV64260) += gt64260_common.o gt64260_pic.o \ obj-$(CONFIG_EV64260) += gt64260_common.o gt64260_pic.o \
indirect_pci.o todc_time.o pci_auto.o indirect_pci.o todc_time.o pci_auto.o
obj-$(CONFIG_GEMINI) += open_pic.o i8259.o indirect_pci.o obj-$(CONFIG_GEMINI) += open_pic.o indirect_pci.o
obj-$(CONFIG_K2) += i8259.o indirect_pci.o todc_time.o \ obj-$(CONFIG_K2) += i8259.o indirect_pci.o todc_time.o \
pci_auto.o pci_auto.o
obj-$(CONFIG_LOPEC) += pci_auto.o open_pic.o i8259.o todc_time.o obj-$(CONFIG_LOPEC) += pci_auto.o open_pic.o i8259.o todc_time.o
......
...@@ -48,6 +48,8 @@ static u_int NumProcessors; ...@@ -48,6 +48,8 @@ static u_int NumProcessors;
static u_int NumSources; static u_int NumSources;
static int open_pic_irq_offset; static int open_pic_irq_offset;
static volatile OpenPIC_Source *ISR[NR_IRQS]; static volatile OpenPIC_Source *ISR[NR_IRQS];
static int openpic_cascade_irq = -1;
static int (*openpic_cascade_fn)(struct pt_regs *);
/* Global Operations */ /* Global Operations */
static void openpic_disable_8259_pass_through(void); static void openpic_disable_8259_pass_through(void);
...@@ -416,13 +418,6 @@ void __init openpic_init(int offset) ...@@ -416,13 +418,6 @@ void __init openpic_init(int offset)
/* Initialize the spurious interrupt */ /* Initialize the spurious interrupt */
if (ppc_md.progress) ppc_md.progress("openpic: spurious",0x3bd); if (ppc_md.progress) ppc_md.progress("openpic: spurious",0x3bd);
openpic_set_spurious(OPENPIC_VEC_SPURIOUS+offset); openpic_set_spurious(OPENPIC_VEC_SPURIOUS+offset);
/* Initialize the cascade */
if (offset) {
if (request_irq(offset, no_action, SA_INTERRUPT,
"82c59 cascade", NULL))
printk("Unable to get OpenPIC IRQ 0 for cascade\n");
}
openpic_disable_8259_pass_through(); openpic_disable_8259_pass_through();
#ifdef CONFIG_EPIC_SERIAL_MODE #ifdef CONFIG_EPIC_SERIAL_MODE
openpic_eicr_set_clk(7); /* Slowest value until we know better */ openpic_eicr_set_clk(7); /* Slowest value until we know better */
...@@ -682,6 +677,19 @@ openpic_init_nmi_irq(u_int irq) ...@@ -682,6 +677,19 @@ openpic_init_nmi_irq(u_int irq)
* *
*/ */
/*
* Hookup a cascade to the OpenPIC.
*/
void __init
openpic_hookup_cascade(u_int irq, char *name,
int (*cascade_fn)(struct pt_regs *))
{
openpic_cascade_irq = irq;
openpic_cascade_fn = cascade_fn;
if (request_irq(irq, no_action, SA_INTERRUPT, name, NULL))
printk("Unable to get OpenPIC IRQ %d for cascade\n",
irq - open_pic_irq_offset);
}
/* /*
* Enable/disable an external interrupt source * Enable/disable an external interrupt source
...@@ -841,14 +849,19 @@ openpic_get_irq(struct pt_regs *regs) ...@@ -841,14 +849,19 @@ openpic_get_irq(struct pt_regs *regs)
int irq = openpic_irq(); int irq = openpic_irq();
/* /*
* This needs to be cleaned up. We don't necessarily have * Check for the cascade interrupt and call the cascaded
* an i8259 cascaded or even a cascade. * interrupt controller function (usually i8259_irq) if so.
* This should move to irq.c eventually. -- paulus
*/ */
if (open_pic_irq_offset && irq == open_pic_irq_offset) { if (irq == openpic_cascade_irq && openpic_cascade_fn != NULL) {
/* Get the IRQ from the cascade. */ int cirq = openpic_cascade_fn(regs);
irq = i8259_irq(regs);
openpic_eoi(); /* Allow for the cascade being shared with other devices */
} else if (irq == OPENPIC_VEC_SPURIOUS + open_pic_irq_offset) if (cirq != -1) {
irq = cirq;
openpic_eoi();
}
} else if (irq == OPENPIC_VEC_SPURIOUS + open_pic_irq_offset)
irq = -1; irq = -1;
return irq; return irq;
} }
......
...@@ -41,6 +41,8 @@ extern void* OpenPIC_Addr; ...@@ -41,6 +41,8 @@ extern void* OpenPIC_Addr;
extern void openpic_set_sources(int first_irq, int num_irqs, void *isr); extern void openpic_set_sources(int first_irq, int num_irqs, void *isr);
extern void openpic_init(int linux_irq_offset); extern void openpic_init(int linux_irq_offset);
extern void openpic_init_nmi_irq(u_int irq); extern void openpic_init_nmi_irq(u_int irq);
extern void openpic_hookup_cascade(u_int irq, char *name,
int (*cascade_fn)(struct pt_regs *));
extern u_int openpic_irq(void); extern u_int openpic_irq(void);
extern void openpic_eoi(void); extern void openpic_eoi(void);
extern void openpic_request_IPIs(void); extern void openpic_request_IPIs(void);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment