Commit a6d21e85 authored by Tom Rini's avatar Tom Rini Committed by Linus Torvalds

[PATCH] ppc32: fix early request_irq

Here's a patch which backs out the fix Randy Vinson came up with, and makes
i8259_init() and openpic_hookup_cascade() use setup_irq (tested on LoPEC). 
This also converts the rest of the request_irq callers that were expecting the
old behavior (psurge SMP, chrp xmon, 85xx, some 82xx).  This is more untested,
but looks correct.  I've left 8xx alone in this as it needs other changes
before it would make sense.
Signed-off-by: default avatarTom Rini <trini@kernel.crashing.org>
Acked-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 8c8e5bf8
...@@ -150,6 +150,13 @@ static irqreturn_t cpm2_cascade(int irq, void *dev_id, struct pt_regs *regs) ...@@ -150,6 +150,13 @@ static irqreturn_t cpm2_cascade(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static struct irqaction cpm2_irqaction = {
.handler = cpm2_cascade,
.flags = SA_INTERRUPT,
.mask = CPU_MASK_NONE,
.name = "cpm2_cascade",
};
static void __init static void __init
mpc8560_ads_init_IRQ(void) mpc8560_ads_init_IRQ(void)
{ {
...@@ -173,7 +180,7 @@ mpc8560_ads_init_IRQ(void) ...@@ -173,7 +180,7 @@ mpc8560_ads_init_IRQ(void)
immap->im_intctl.ic_scprrh = 0x05309770; immap->im_intctl.ic_scprrh = 0x05309770;
immap->im_intctl.ic_scprrl = 0x05309770; immap->im_intctl.ic_scprrl = 0x05309770;
request_irq(MPC85xx_IRQ_CPM, cpm2_cascade, SA_INTERRUPT, "cpm2_cascade", NULL); setup_irq(MPC85xx_IRQ_CPM, &cpm2_irqaction);
return; return;
} }
......
...@@ -193,6 +193,13 @@ static void cpm2_cascade(int irq, void *dev_id, struct pt_regs *regs) ...@@ -193,6 +193,13 @@ static void cpm2_cascade(int irq, void *dev_id, struct pt_regs *regs)
while((irq = cpm2_get_irq(regs)) >= 0) while((irq = cpm2_get_irq(regs)) >= 0)
__do_IRQ(irq, regs); __do_IRQ(irq, regs);
} }
static struct irqaction cpm2_irqaction = {
.handler = cpm2_cascade,
.flags = SA_INTERRUPT,
.mask = CPU_MASK_NONE,
.name = "cpm2_cascade",
};
#endif /* CONFIG_CPM2 */ #endif /* CONFIG_CPM2 */
void __init void __init
...@@ -235,7 +242,7 @@ mpc85xx_cds_init_IRQ(void) ...@@ -235,7 +242,7 @@ mpc85xx_cds_init_IRQ(void)
immap->im_intctl.ic_scprrh = 0x05309770; immap->im_intctl.ic_scprrh = 0x05309770;
immap->im_intctl.ic_scprrl = 0x05309770; immap->im_intctl.ic_scprrl = 0x05309770;
request_irq(MPC85xx_IRQ_CPM, cpm2_cascade, SA_INTERRUPT, "cpm2_cascade", NULL); setup_irq(MPC85xx_IRQ_CPM, &cpm2_irqaction);
#endif #endif
return; return;
......
...@@ -371,18 +371,13 @@ static void __init chrp_find_openpic(void) ...@@ -371,18 +371,13 @@ static void __init chrp_find_openpic(void)
} }
} }
static int __init #if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
chrp_request_cascade(void) static struct irqaction xmon_irqaction = {
{ .handler = xmon_irq,
if (_machine != _MACH_chrp) .mask = CPU_MASK_NONE,
return 0; .name = "XMON break",
};
/* We have a cascade on OpenPIC IRQ 0, Linux IRQ 16 */ #endif
openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
i8259_irq);
return 0;
}
arch_initcall(chrp_request_cascade);
void __init chrp_init_IRQ(void) void __init chrp_init_IRQ(void)
{ {
...@@ -413,6 +408,9 @@ void __init chrp_init_IRQ(void) ...@@ -413,6 +408,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;
...@@ -426,7 +424,7 @@ void __init chrp_init_IRQ(void) ...@@ -426,7 +424,7 @@ void __init chrp_init_IRQ(void)
&& strcmp(kbd->parent->type, "adb") == 0) && strcmp(kbd->parent->type, "adb") == 0)
break; break;
if (kbd) if (kbd)
request_irq(HYDRA_INT_ADB_NMI, xmon_irq, 0, "XMON break", 0); setup_irq(HYDRA_INT_ADB_NMI, &xmon_irqaction);
#endif #endif
} }
......
...@@ -258,17 +258,6 @@ lopec_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data, ...@@ -258,17 +258,6 @@ lopec_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data,
} }
#endif /* BLK_DEV_IDE */ #endif /* BLK_DEV_IDE */
static int __init
lopec_request_cascade(void)
{
/* We have a cascade on OpenPIC IRQ 0, Linux IRQ 16 */
openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
&i8259_irq);
return 0;
}
arch_initcall(lopec_request_cascade);
static void __init static void __init
lopec_init_IRQ(void) lopec_init_IRQ(void)
{ {
...@@ -282,6 +271,10 @@ lopec_init_IRQ(void) ...@@ -282,6 +271,10 @@ lopec_init_IRQ(void)
mpc10x_set_openpic(); mpc10x_set_openpic();
/* 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++)
irq_desc[i].handler = &i8259_pic; irq_desc[i].handler = &i8259_pic;
......
...@@ -363,15 +363,6 @@ mcpn765_init2(void) ...@@ -363,15 +363,6 @@ mcpn765_init2(void)
return; return;
} }
static int __init
mcpn765_request_cascade(void)
{
openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
i8259_irq);
return 0;
}
arch_initcall(mcpn765_request_cascade);
/* /*
* Interrupt setup and service. * Interrupt setup and service.
* Have MPIC on HAWK and cascaded 8259s on VIA 82586 cascaded to MPIC. * Have MPIC on HAWK and cascaded 8259s on VIA 82586 cascaded to MPIC.
...@@ -385,6 +376,8 @@ mcpn765_init_IRQ(void) ...@@ -385,6 +376,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;
......
...@@ -204,17 +204,6 @@ mvme5100_init2(void) ...@@ -204,17 +204,6 @@ mvme5100_init2(void)
return; return;
} }
static int __init
mvme5100_request_cascade(void)
{
#ifdef CONFIG_MVME5100_IPMC761_PRESENT
openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
&i8259_irq);
#endif
return 0;
}
arch_initcall(mvme5100_request_cascade);
/* /*
* Interrupt setup and service. * Interrupt setup and service.
* Have MPIC on HAWK and cascaded 8259s on Winbond cascaded to MPIC. * Have MPIC on HAWK and cascaded 8259s on Winbond cascaded to MPIC.
...@@ -232,12 +221,14 @@ mvme5100_init_IRQ(void) ...@@ -232,12 +221,14 @@ mvme5100_init_IRQ(void)
openpic_set_sources(0, 16, OpenPIC_Addr + 0x10000); openpic_set_sources(0, 16, OpenPIC_Addr + 0x10000);
#ifdef CONFIG_MVME5100_IPMC761_PRESENT #ifdef CONFIG_MVME5100_IPMC761_PRESENT
openpic_init(NUM_8259_INTERRUPTS); openpic_init(NUM_8259_INTERRUPTS);
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++)
irq_desc[i].handler = &i8259_pic; irq_desc[i].handler = &i8259_pic;
i8259_init((long)NULL); i8259_init(0);
#else #else
openpic_init(0); openpic_init(0);
#endif #endif
......
...@@ -405,6 +405,13 @@ static void __init psurge_dual_sync_tb(int cpu_nr) ...@@ -405,6 +405,13 @@ static void __init psurge_dual_sync_tb(int cpu_nr)
smp_tb_synchronized = 1; smp_tb_synchronized = 1;
} }
static struct irqaction psurge_irqaction = {
.handler = psurge_primary_intr,
.flags = SA_INTERRUPT,
.mask = CPU_MASK_NONE,
.name = "primary IPI",
};
static void __init smp_psurge_setup_cpu(int cpu_nr) static void __init smp_psurge_setup_cpu(int cpu_nr)
{ {
...@@ -421,7 +428,7 @@ static void __init smp_psurge_setup_cpu(int cpu_nr) ...@@ -421,7 +428,7 @@ static void __init smp_psurge_setup_cpu(int cpu_nr)
/* reset the entry point so if we get another intr we won't /* reset the entry point so if we get another intr we won't
* try to startup again */ * try to startup again */
out_be32(psurge_start, 0x100); out_be32(psurge_start, 0x100);
if (request_irq(30, psurge_primary_intr, SA_INTERRUPT, "primary IPI", NULL)) if (setup_irq(30, &psurge_irqaction))
printk(KERN_ERR "Couldn't get primary IPI interrupt"); printk(KERN_ERR "Couldn't get primary IPI interrupt");
} }
......
...@@ -654,16 +654,6 @@ static unsigned int pplus_irq_canonicalize(u_int irq) ...@@ -654,16 +654,6 @@ static unsigned int pplus_irq_canonicalize(u_int irq)
return irq; return irq;
} }
static int __init
pplus_request_cascade(void)
{
if (OpenPIC_Addr != NULL)
openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
i8259_irq);
return 0;
}
arch_initcall(pplus_request_cascade);
static void __init pplus_init_IRQ(void) static void __init pplus_init_IRQ(void)
{ {
int i; int i;
...@@ -678,6 +668,8 @@ static void __init pplus_init_IRQ(void) ...@@ -678,6 +668,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;
} }
......
...@@ -958,20 +958,6 @@ prep_irq_canonicalize(u_int irq) ...@@ -958,20 +958,6 @@ prep_irq_canonicalize(u_int irq)
} }
} }
static int __init
prep_request_cascade(void)
{
if (_machine != _MACH_prep)
return 0;
if (OpenPIC_Addr != NULL)
/* We have a cascade on OpenPIC IRQ 0, Linux IRQ 16 */
openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
i8259_irq);
return 0;
}
arch_initcall(prep_request_cascade);
static void __init static void __init
prep_init_IRQ(void) prep_init_IRQ(void)
{ {
...@@ -980,6 +966,9 @@ prep_init_IRQ(void) ...@@ -980,6 +966,9 @@ prep_init_IRQ(void)
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;
......
...@@ -383,15 +383,6 @@ sandpoint_request_io(void) ...@@ -383,15 +383,6 @@ sandpoint_request_io(void)
arch_initcall(sandpoint_request_io); arch_initcall(sandpoint_request_io);
static int __init
sandpoint_request_cascade(void)
{
openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
i8259_irq);
return 0;
}
arch_initcall(sandpoint_request_cascade);
/* /*
* Interrupt setup and service. Interrrupts on the Sandpoint come * Interrupt setup and service. Interrrupts on the Sandpoint come
* from the four PCI slots plus the 8259 in the Winbond Super I/O (SIO). * from the four PCI slots plus the 8259 in the Winbond Super I/O (SIO).
...@@ -407,6 +398,8 @@ sandpoint_init_IRQ(void) ...@@ -407,6 +398,8 @@ sandpoint_init_IRQ(void)
OpenPIC_NumInitSenses = sizeof(sandpoint_openpic_initsenses); OpenPIC_NumInitSenses = sizeof(sandpoint_openpic_initsenses);
mpc10x_set_openpic(); mpc10x_set_openpic();
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
......
...@@ -146,6 +146,13 @@ static irqreturn_t sbc82xx_i8259_demux(int irq, void *dev_id, struct pt_regs *re ...@@ -146,6 +146,13 @@ static irqreturn_t sbc82xx_i8259_demux(int irq, void *dev_id, struct pt_regs *re
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static struct irqaction sbc82xx_i8259_irqaction = {
.handler = sbc82xx_i8259_demux,
.flags = SA_INTERRUPT,
.mask = CPU_MASK_NONE,
.name = "i8259 demux",
};
void __init sbc82xx_init_IRQ(void) void __init sbc82xx_init_IRQ(void)
{ {
volatile memctl_cpm2_t *mc = &cpm2_immr->im_memctl; volatile memctl_cpm2_t *mc = &cpm2_immr->im_memctl;
...@@ -186,8 +193,7 @@ void __init sbc82xx_init_IRQ(void) ...@@ -186,8 +193,7 @@ void __init sbc82xx_init_IRQ(void)
sbc82xx_i8259_map[1] = sbc82xx_i8259_mask; /* Set interrupt mask */ sbc82xx_i8259_map[1] = sbc82xx_i8259_mask; /* Set interrupt mask */
/* Request cascade IRQ */ /* Request cascade IRQ */
if (request_irq(SIU_INT_IRQ6, sbc82xx_i8259_demux, SA_INTERRUPT, if (setup_irq(SIU_INT_IRQ6, &sbc82xx_i8259_irqaction)) {
"i8259 demux", 0)) {
printk("Installation of i8259 IRQ demultiplexer failed.\n"); printk("Installation of i8259 IRQ demultiplexer failed.\n");
} }
} }
......
...@@ -13,7 +13,6 @@ unsigned char cached_8259[2] = { 0xff, 0xff }; ...@@ -13,7 +13,6 @@ unsigned char cached_8259[2] = { 0xff, 0xff };
static spinlock_t i8259_lock = SPIN_LOCK_UNLOCKED; static spinlock_t i8259_lock = SPIN_LOCK_UNLOCKED;
int i8259_pic_irq_offset; int i8259_pic_irq_offset;
static int i8259_present;
/* /*
* Acknowledge the IRQ using either the PCI host bridge's interrupt * Acknowledge the IRQ using either the PCI host bridge's interrupt
...@@ -152,19 +151,12 @@ static struct resource pic_edgectrl_iores = { ...@@ -152,19 +151,12 @@ static struct resource pic_edgectrl_iores = {
"8259 edge control", 0x4d0, 0x4d1, IORESOURCE_BUSY "8259 edge control", 0x4d0, 0x4d1, IORESOURCE_BUSY
}; };
static int __init static struct irqaction i8259_irqaction = {
i8259_hook_cascade(void) .handler = no_action,
{ .flags = SA_INTERRUPT,
if (!i8259_present) .mask = CPU_MASK_NONE,
return 0; .name = "82c59 secondary cascade",
};
/* reserve our resources */
request_irq( i8259_pic_irq_offset + 2, no_action, SA_INTERRUPT,
"82c59 secondary cascade", NULL );
return 0;
}
arch_initcall(i8259_hook_cascade);
/* /*
* i8259_init() * i8259_init()
...@@ -199,12 +191,12 @@ i8259_init(long intack_addr) ...@@ -199,12 +191,12 @@ i8259_init(long intack_addr)
spin_unlock_irqrestore(&i8259_lock, flags); spin_unlock_irqrestore(&i8259_lock, flags);
/* reserve our resources */
setup_irq( i8259_pic_irq_offset + 2, &i8259_irqaction);
request_resource(&ioport_resource, &pic1_iores); request_resource(&ioport_resource, &pic1_iores);
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 != 0) if (intack_addr != 0)
pci_intack = ioremap(intack_addr, 1); pci_intack = ioremap(intack_addr, 1);
i8259_present = 1;
} }
...@@ -681,13 +681,21 @@ openpic_init_nmi_irq(u_int irq) ...@@ -681,13 +681,21 @@ openpic_init_nmi_irq(u_int irq)
/* /*
* Hookup a cascade to the OpenPIC. * Hookup a cascade to the OpenPIC.
*/ */
static struct irqaction openpic_cascade_irqaction = {
.handler = no_action,
.flags = SA_INTERRUPT,
.mask = CPU_MASK_NONE,
};
void __init void __init
openpic_hookup_cascade(u_int irq, char *name, openpic_hookup_cascade(u_int irq, char *name,
int (*cascade_fn)(struct pt_regs *)) int (*cascade_fn)(struct pt_regs *))
{ {
openpic_cascade_irq = irq; openpic_cascade_irq = irq;
openpic_cascade_fn = cascade_fn; openpic_cascade_fn = cascade_fn;
if (request_irq(irq, no_action, SA_INTERRUPT, name, NULL))
if (setup_irq(irq, &openpic_cascade_irqaction))
printk("Unable to get OpenPIC IRQ %d for cascade\n", printk("Unable to get OpenPIC IRQ %d for cascade\n",
irq - open_pic_irq_offset); irq - open_pic_irq_offset);
} }
......
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