Commit 73926916 authored by Tom Rini's avatar Tom Rini

PPC32: Modify openpic_get_irq() to call i8259_irq() for cascaded IRQs. This

requires that i8259_init() be called with the real address where PCI
interrupt-acknowledge transactions will be generated.
parent 4dc15fed
...@@ -171,6 +171,10 @@ static struct resource pic_edgectrl_iores = { ...@@ -171,6 +171,10 @@ static struct resource pic_edgectrl_iores = {
"8259 edge control", 0x4d0, 0x4d1, IORESOURCE_BUSY "8259 edge control", 0x4d0, 0x4d1, IORESOURCE_BUSY
}; };
/* i8259_init()
* intack_addr - PCI interrupt acknowledge (real) address which will return
* the active irq from the 8259
*/
void __init i8259_init(long intack_addr) void __init i8259_init(long intack_addr)
{ {
unsigned long flags; unsigned long flags;
...@@ -205,6 +209,9 @@ void __init i8259_init(long intack_addr) ...@@ -205,6 +209,9 @@ void __init i8259_init(long intack_addr)
request_resource(&ioport_resource, &pic2_iores); request_resource(&ioport_resource, &pic2_iores);
request_resource(&ioport_resource, &pic_edgectrl_iores); request_resource(&ioport_resource, &pic_edgectrl_iores);
if (intack_addr) /* XXX remove me after board maintainers fix their i8259_init calls */
pci_intack = ioremap(intack_addr, 1); if (intack_addr == 0)
panic("You must supply a PCI interrupt acknowledge address to i8259_init()\n");
pci_intack = ioremap(intack_addr, 1);
} }
...@@ -46,7 +46,6 @@ extern int use_of_interrupt_tree; ...@@ -46,7 +46,6 @@ extern int use_of_interrupt_tree;
static u_int NumProcessors; 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 unsigned char *chrp_int_ack_special;
static volatile OpenPIC_Source *ISR[NR_IRQS]; static volatile OpenPIC_Source *ISR[NR_IRQS];
/* Global Operations */ /* Global Operations */
...@@ -303,8 +302,7 @@ void openpic_set_sources(int first_irq, int num_irqs, void *first_ISR) ...@@ -303,8 +302,7 @@ void openpic_set_sources(int first_irq, int num_irqs, void *first_ISR)
ISR[i] = src; ISR[i] = src;
} }
void __init openpic_init(int main_pic, int offset, unsigned char *chrp_ack, void __init openpic_init(int main_pic, int offset, int programmer_switch_irq)
int programmer_switch_irq)
{ {
u_int t, i; u_int t, i;
u_int timerfreq; u_int timerfreq;
...@@ -357,7 +355,6 @@ void __init openpic_init(int main_pic, int offset, unsigned char *chrp_ack, ...@@ -357,7 +355,6 @@ void __init openpic_init(int main_pic, int offset, unsigned char *chrp_ack,
return; return;
open_pic_irq_offset = offset; open_pic_irq_offset = offset;
chrp_int_ack_special = chrp_ack;
/* Initialize timer interrupts */ /* Initialize timer interrupts */
if ( ppc_md.progress ) ppc_md.progress("openpic timer",0x3ba); if ( ppc_md.progress ) ppc_md.progress("openpic timer",0x3ba);
...@@ -814,19 +811,13 @@ openpic_get_irq(struct pt_regs *regs) ...@@ -814,19 +811,13 @@ openpic_get_irq(struct pt_regs *regs)
/* Management of the cascade should be moved out of here */ /* Management of the cascade should be moved out of here */
/* Yep - because openpic !=> i8259, for one thing. -VAL */ /* Yep - because openpic !=> i8259, for one thing. -VAL */
if (open_pic_irq_offset && irq == open_pic_irq_offset) if (open_pic_irq_offset && irq == open_pic_irq_offset)
{ {
/*
* This magic address generates a PCI IACK cycle.
*/
if ( chrp_int_ack_special )
irq = *chrp_int_ack_special;
#ifndef CONFIG_GEMINI #ifndef CONFIG_GEMINI
else irq = i8259_irq(regs); /* get IRQ from cascade */
irq = i8259_poll();
#endif #endif
openpic_eoi(); openpic_eoi();
} }
if (irq == OPENPIC_VEC_SPURIOUS + open_pic_irq_offset) if (irq == OPENPIC_VEC_SPURIOUS + open_pic_irq_offset)
irq = -1; irq = -1;
return irq; return irq;
......
...@@ -386,7 +386,7 @@ void __init chrp_init_IRQ(void) ...@@ -386,7 +386,7 @@ void __init chrp_init_IRQ(void)
{ {
struct device_node *np; struct device_node *np;
int i; int i;
unsigned char* chrp_int_ack_special = 0; unsigned long chrp_int_ack;
unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS]; unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS];
int nmi_irq = -1; int nmi_irq = -1;
#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON) #if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON)
...@@ -396,14 +396,14 @@ void __init chrp_init_IRQ(void) ...@@ -396,14 +396,14 @@ void __init chrp_init_IRQ(void)
for (np = find_devices("pci"); np != NULL; np = np->next) { for (np = find_devices("pci"); np != NULL; np = np->next) {
unsigned int *addrp = (unsigned int *) unsigned int *addrp = (unsigned int *)
get_property(np, "8259-interrupt-acknowledge", NULL); get_property(np, "8259-interrupt-acknowledge", NULL);
if (addrp == NULL) if (addrp == NULL)
continue; continue;
chrp_int_ack_special = (unsigned char *) chrp_int_ack = addrp[prom_n_addr_cells(np)-1];
ioremap(addrp[prom_n_addr_cells(np)-1], 1);
break; break;
} }
if (np == NULL) if (np == NULL)
printk("Cannot find pci to get ack address\n"); printk(KERN_ERR "Cannot find PCI interrupt acknowledge address\n");
chrp_find_openpic(); chrp_find_openpic();
...@@ -411,11 +411,11 @@ void __init chrp_init_IRQ(void) ...@@ -411,11 +411,11 @@ void __init chrp_init_IRQ(void)
OpenPIC_InitSenses = init_senses; OpenPIC_InitSenses = init_senses;
OpenPIC_NumInitSenses = NR_IRQS - NUM_8259_INTERRUPTS; OpenPIC_NumInitSenses = NR_IRQS - NUM_8259_INTERRUPTS;
openpic_init(1, NUM_8259_INTERRUPTS, chrp_int_ack_special, nmi_irq); openpic_init(1, NUM_8259_INTERRUPTS, nmi_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;
i8259_init(0); i8259_init(chrp_int_ack);
#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON) #if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON)
/* see if there is a keyboard in the device tree /* see if there is a keyboard in the device tree
......
...@@ -217,13 +217,17 @@ lopec_init_IRQ(void) ...@@ -217,13 +217,17 @@ lopec_init_IRQ(void)
/* Skip reserved space and map Message Unit Interrupt (I2O) */ /* Skip reserved space and map Message Unit Interrupt (I2O) */
openpic_set_sources(19, 1, OpenPIC_Addr + 0x110C0); openpic_set_sources(19, 1, OpenPIC_Addr + 0x110C0);
openpic_init(1, NUM_8259_INTERRUPTS, NULL, -1); openpic_init(1, NUM_8259_INTERRUPTS, -1);
/* Map i8259 interrupts */ /* Map i8259 interrupts */
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;
i8259_init(0); /*
* The EPIC allows for a read in the range of 0xFEF00000 ->
* 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction.
*/
i8259_init(0xfef00000);
} }
void __init void __init
......
...@@ -373,7 +373,7 @@ pmac_pic_init(void) ...@@ -373,7 +373,7 @@ pmac_pic_init(void)
ppc_md.get_irq = openpic_get_irq; ppc_md.get_irq = openpic_get_irq;
OpenPIC_Addr = ioremap(irqctrler->addrs[0].address, OpenPIC_Addr = ioremap(irqctrler->addrs[0].address,
irqctrler->addrs[0].size); irqctrler->addrs[0].size);
openpic_init(1, 0, 0, nmi_irq); openpic_init(1, 0, nmi_irq);
#ifdef CONFIG_XMON #ifdef CONFIG_XMON
if (nmi_irq >= 0) if (nmi_irq >= 0)
request_irq(nmi_irq, xmon_irq, 0, request_irq(nmi_irq, xmon_irq, 0,
......
...@@ -691,7 +691,7 @@ prep_init_IRQ(void) ...@@ -691,7 +691,7 @@ prep_init_IRQ(void)
int i; int i;
if (OpenPIC_Addr != NULL) if (OpenPIC_Addr != NULL)
openpic_init(1, NUM_8259_INTERRUPTS, 0, -1); openpic_init(1, NUM_8259_INTERRUPTS, -1);
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;
i8259_init(0xbffffff0); /* PCI interrupt ack address for MPC105 and 106 */ i8259_init(0xbffffff0); /* PCI interrupt ack address for MPC105 and 106 */
......
...@@ -55,7 +55,7 @@ extern void* OpenPIC_Addr; ...@@ -55,7 +55,7 @@ extern void* OpenPIC_Addr;
/* Exported functions */ /* Exported functions */
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, int, unsigned char *, int); extern void openpic_init(int, int, int);
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