Commit f9bd170a authored by Paul Mackerras's avatar Paul Mackerras

powerpc: Merge i8259.c into arch/powerpc/sysdev

This changes the parameters for i8259_init so that it takes two
parameters: a physical address for generating an interrupt
acknowledge cycle, and an interrupt number offset.  i8259_init
now sets the irq_desc[] for its interrupts; all the callers
were doing this, and that code is gone now.  This also defines
a CONFIG_PPC_I8259 symbol to select i8259.o for inclusion, and
makes the platforms that need it select that symbol.
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent 25635c71
...@@ -275,11 +275,13 @@ endchoice ...@@ -275,11 +275,13 @@ endchoice
config PPC_PSERIES config PPC_PSERIES
depends on PPC_MULTIPLATFORM && PPC64 depends on PPC_MULTIPLATFORM && PPC64
bool " IBM pSeries & new (POWER5-based) iSeries" bool " IBM pSeries & new (POWER5-based) iSeries"
select PPC_I8259
default y default y
config PPC_CHRP config PPC_CHRP
bool " Common Hardware Reference Platform (CHRP) based machines" bool " Common Hardware Reference Platform (CHRP) based machines"
depends on PPC_MULTIPLATFORM && PPC32 depends on PPC_MULTIPLATFORM && PPC32
select PPC_I8259
select PPC_INDIRECT_PCI select PPC_INDIRECT_PCI
default y default y
...@@ -298,6 +300,7 @@ config PPC_PMAC64 ...@@ -298,6 +300,7 @@ config PPC_PMAC64
config PPC_PREP config PPC_PREP
bool " PowerPC Reference Platform (PReP) based machines" bool " PowerPC Reference Platform (PReP) based machines"
depends on PPC_MULTIPLATFORM && PPC32 depends on PPC_MULTIPLATFORM && PPC32
select PPC_I8259
select PPC_INDIRECT_PCI select PPC_INDIRECT_PCI
default y default y
...@@ -628,6 +631,7 @@ menu "Bus options" ...@@ -628,6 +631,7 @@ menu "Bus options"
config ISA config ISA
bool "Support for ISA-bus hardware" bool "Support for ISA-bus hardware"
depends on PPC_PREP || PPC_CHRP depends on PPC_PREP || PPC_CHRP
select PPC_I8259
help help
Find out whether you have ISA slots on your motherboard. ISA is the Find out whether you have ISA slots on your motherboard. ISA is the
name of a bus system, i.e. the way the CPU talks to the other stuff name of a bus system, i.e. the way the CPU talks to the other stuff
...@@ -640,6 +644,11 @@ config GENERIC_ISA_DMA ...@@ -640,6 +644,11 @@ config GENERIC_ISA_DMA
depends on PPC64 || POWER4 || 6xx && !CPM2 depends on PPC64 || POWER4 || 6xx && !CPM2
default y default y
config PPC_I8259
bool
default y if 85xx
default n
config PPC_INDIRECT_PCI config PPC_INDIRECT_PCI
bool bool
depends on PCI depends on PCI
...@@ -679,6 +688,7 @@ config MPC83xx_PCI2 ...@@ -679,6 +688,7 @@ config MPC83xx_PCI2
config PCI_QSPAN config PCI_QSPAN
bool "QSpan PCI" bool "QSpan PCI"
depends on !4xx && !CPM2 && 8xx depends on !4xx && !CPM2 && 8xx
select PPC_I8259
help help
Say Y here if you have a system based on a Motorola 8xx-series Say Y here if you have a system based on a Motorola 8xx-series
embedded processor with a QSPAN PCI interface, otherwise say N. embedded processor with a QSPAN PCI interface, otherwise say N.
......
...@@ -48,6 +48,7 @@ config EV64260 ...@@ -48,6 +48,7 @@ config EV64260
config LOPEC config LOPEC
bool "Motorola-LoPEC" bool "Motorola-LoPEC"
select PPC_I8259
config MVME5100 config MVME5100
bool "Motorola-MVME5100" bool "Motorola-MVME5100"
...@@ -55,6 +56,7 @@ config MVME5100 ...@@ -55,6 +56,7 @@ config MVME5100
config PPLUS config PPLUS
bool "Motorola-PowerPlus" bool "Motorola-PowerPlus"
select PPC_I8259
select PPC_INDIRECT_PCI select PPC_INDIRECT_PCI
config PRPMC750 config PRPMC750
...@@ -67,12 +69,14 @@ config PRPMC800 ...@@ -67,12 +69,14 @@ config PRPMC800
config SANDPOINT config SANDPOINT
bool "Motorola-Sandpoint" bool "Motorola-Sandpoint"
select PPC_I8259
help help
Select SANDPOINT if configuring for a Motorola Sandpoint X3 Select SANDPOINT if configuring for a Motorola Sandpoint X3
(any flavor). (any flavor).
config RADSTONE_PPC7D config RADSTONE_PPC7D
bool "Radstone Technology PPC7D board" bool "Radstone Technology PPC7D board"
select PPC_I8259
config PAL4 config PAL4
bool "SBS-Palomar4" bool "SBS-Palomar4"
...@@ -307,6 +311,7 @@ config HARRIER_STORE_GATHERING ...@@ -307,6 +311,7 @@ config HARRIER_STORE_GATHERING
config MVME5100_IPMC761_PRESENT config MVME5100_IPMC761_PRESENT
bool "MVME5100 configured with an IPMC761" bool "MVME5100 configured with an IPMC761"
depends on MVME5100 depends on MVME5100
select PPC_I8259
config SPRUCE_BAUD_33M config SPRUCE_BAUD_33M
bool "Spruce baud clock support" bool "Spruce baud clock support"
......
...@@ -87,7 +87,6 @@ extern int pSeries_machine_check_exception(struct pt_regs *regs); ...@@ -87,7 +87,6 @@ extern int pSeries_machine_check_exception(struct pt_regs *regs);
static void pseries_shared_idle(void); static void pseries_shared_idle(void);
static void pseries_dedicated_idle(void); static void pseries_dedicated_idle(void);
static volatile void __iomem * chrp_int_ack_special;
struct mpic *pSeries_mpic; struct mpic *pSeries_mpic;
void pSeries_show_cpuinfo(struct seq_file *m) void pSeries_show_cpuinfo(struct seq_file *m)
...@@ -119,19 +118,11 @@ static void __init fwnmi_init(void) ...@@ -119,19 +118,11 @@ static void __init fwnmi_init(void)
fwnmi_active = 1; fwnmi_active = 1;
} }
static int pSeries_irq_cascade(struct pt_regs *regs, void *data)
{
if (chrp_int_ack_special)
return readb(chrp_int_ack_special);
else
return i8259_irq(regs);
}
static void __init pSeries_init_mpic(void) static void __init pSeries_init_mpic(void)
{ {
unsigned int *addrp; unsigned int *addrp;
struct device_node *np; struct device_node *np;
int i; unsigned long intack = 0;
/* All ISUs are setup, complete initialization */ /* All ISUs are setup, complete initialization */
mpic_init(pSeries_mpic); mpic_init(pSeries_mpic);
...@@ -142,16 +133,14 @@ static void __init pSeries_init_mpic(void) ...@@ -142,16 +133,14 @@ static void __init pSeries_init_mpic(void)
get_property(np, "8259-interrupt-acknowledge", NULL))) get_property(np, "8259-interrupt-acknowledge", NULL)))
printk(KERN_ERR "Cannot find pci to get ack address\n"); printk(KERN_ERR "Cannot find pci to get ack address\n");
else else
chrp_int_ack_special = ioremap(addrp[prom_n_addr_cells(np)-1], 1); intack = addrp[prom_n_addr_cells(np)-1];
of_node_put(np); of_node_put(np);
/* Setup the legacy interrupts & controller */ /* Setup the legacy interrupts & controller */
for (i = 0; i < NUM_ISA_INTERRUPTS; i++) i8259_init(intack, 0);
irq_desc[i].handler = &i8259_pic;
i8259_init(0);
/* Hook cascade to mpic */ /* Hook cascade to mpic */
mpic_setup_cascade(NUM_ISA_INTERRUPTS, pSeries_irq_cascade, NULL); mpic_setup_cascade(NUM_ISA_INTERRUPTS, i8259_irq_cascade, NULL);
} }
static void __init pSeries_setup_mpic(void) static void __init pSeries_setup_mpic(void)
......
obj-$(CONFIG_MPIC) += mpic.o obj-$(CONFIG_MPIC) += mpic.o
obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o
obj-$(CONFIG_PPC_I8259) += i8259.o
/*
* i8259 interrupt controller driver.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/init.h> #include <linux/init.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/i8259.h> #include <asm/i8259.h>
static volatile unsigned char *pci_intack; /* RO, gives us the irq vector */ static volatile void __iomem *pci_intack; /* RO, gives us the irq vector */
unsigned char cached_8259[2] = { 0xff, 0xff }; static unsigned char cached_8259[2] = { 0xff, 0xff };
#define cached_A1 (cached_8259[0]) #define cached_A1 (cached_8259[0])
#define cached_21 (cached_8259[1]) #define cached_21 (cached_8259[1])
static DEFINE_SPINLOCK(i8259_lock); static DEFINE_SPINLOCK(i8259_lock);
int i8259_pic_irq_offset; static int i8259_pic_irq_offset;
/* /*
* Acknowledge the IRQ using either the PCI host bridge's interrupt * Acknowledge the IRQ using either the PCI host bridge's interrupt
...@@ -20,8 +28,7 @@ int i8259_pic_irq_offset; ...@@ -20,8 +28,7 @@ int i8259_pic_irq_offset;
* which is called. It should be noted that polling is broken on some * which is called. It should be noted that polling is broken on some
* IBM and Motorola PReP boxes so we must use the int-ack feature on them. * IBM and Motorola PReP boxes so we must use the int-ack feature on them.
*/ */
int int i8259_irq(struct pt_regs *regs)
i8259_irq(struct pt_regs *regs)
{ {
int irq; int irq;
...@@ -29,7 +36,7 @@ i8259_irq(struct pt_regs *regs) ...@@ -29,7 +36,7 @@ i8259_irq(struct pt_regs *regs)
/* Either int-ack or poll for the IRQ */ /* Either int-ack or poll for the IRQ */
if (pci_intack) if (pci_intack)
irq = *pci_intack; irq = readb(pci_intack);
else { else {
/* Perform an interrupt acknowledge cycle on controller 1. */ /* Perform an interrupt acknowledge cycle on controller 1. */
outb(0x0C, 0x20); /* prepare for poll */ outb(0x0C, 0x20); /* prepare for poll */
...@@ -59,7 +66,12 @@ i8259_irq(struct pt_regs *regs) ...@@ -59,7 +66,12 @@ i8259_irq(struct pt_regs *regs)
} }
spin_unlock(&i8259_lock); spin_unlock(&i8259_lock);
return irq; return irq + i8259_pic_irq_offset;
}
int i8259_irq_cascade(struct pt_regs *regs, void *unused)
{
return i8259_irq(regs);
} }
static void i8259_mask_and_ack_irq(unsigned int irq_nr) static void i8259_mask_and_ack_irq(unsigned int irq_nr)
...@@ -67,20 +79,18 @@ static void i8259_mask_and_ack_irq(unsigned int irq_nr) ...@@ -67,20 +79,18 @@ static void i8259_mask_and_ack_irq(unsigned int irq_nr)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&i8259_lock, flags); spin_lock_irqsave(&i8259_lock, flags);
if ( irq_nr >= i8259_pic_irq_offset ) irq_nr -= i8259_pic_irq_offset;
irq_nr -= i8259_pic_irq_offset;
if (irq_nr > 7) { if (irq_nr > 7) {
cached_A1 |= 1 << (irq_nr-8); cached_A1 |= 1 << (irq_nr-8);
inb(0xA1); /* DUMMY */ inb(0xA1); /* DUMMY */
outb(cached_A1,0xA1); outb(cached_A1, 0xA1);
outb(0x20,0xA0); /* Non-specific EOI */ outb(0x20, 0xA0); /* Non-specific EOI */
outb(0x20,0x20); /* Non-specific EOI to cascade */ outb(0x20, 0x20); /* Non-specific EOI to cascade */
} else { } else {
cached_21 |= 1 << irq_nr; cached_21 |= 1 << irq_nr;
inb(0x21); /* DUMMY */ inb(0x21); /* DUMMY */
outb(cached_21,0x21); outb(cached_21, 0x21);
outb(0x20,0x20); /* Non-specific EOI */ outb(0x20, 0x20); /* Non-specific EOI */
} }
spin_unlock_irqrestore(&i8259_lock, flags); spin_unlock_irqrestore(&i8259_lock, flags);
} }
...@@ -96,9 +106,8 @@ static void i8259_mask_irq(unsigned int irq_nr) ...@@ -96,9 +106,8 @@ static void i8259_mask_irq(unsigned int irq_nr)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&i8259_lock, flags); spin_lock_irqsave(&i8259_lock, flags);
if ( irq_nr >= i8259_pic_irq_offset ) irq_nr -= i8259_pic_irq_offset;
irq_nr -= i8259_pic_irq_offset; if (irq_nr < 8)
if ( irq_nr < 8 )
cached_21 |= 1 << irq_nr; cached_21 |= 1 << irq_nr;
else else
cached_A1 |= 1 << (irq_nr-8); cached_A1 |= 1 << (irq_nr-8);
...@@ -111,9 +120,8 @@ static void i8259_unmask_irq(unsigned int irq_nr) ...@@ -111,9 +120,8 @@ static void i8259_unmask_irq(unsigned int irq_nr)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&i8259_lock, flags); spin_lock_irqsave(&i8259_lock, flags);
if ( irq_nr >= i8259_pic_irq_offset ) irq_nr -= i8259_pic_irq_offset;
irq_nr -= i8259_pic_irq_offset; if (irq_nr < 8)
if ( irq_nr < 8 )
cached_21 &= ~(1 << irq_nr); cached_21 &= ~(1 << irq_nr);
else else
cached_A1 &= ~(1 << (irq_nr-8)); cached_A1 &= ~(1 << (irq_nr-8));
...@@ -169,12 +177,14 @@ static struct irqaction i8259_irqaction = { ...@@ -169,12 +177,14 @@ static struct irqaction i8259_irqaction = {
* intack_addr - PCI interrupt acknowledge (real) address which will return * intack_addr - PCI interrupt acknowledge (real) address which will return
* the active irq from the 8259 * the active irq from the 8259
*/ */
void __init void __init i8259_init(unsigned long intack_addr, int offset)
i8259_init(long intack_addr)
{ {
unsigned long flags; unsigned long flags;
int i;
spin_lock_irqsave(&i8259_lock, flags); spin_lock_irqsave(&i8259_lock, flags);
i8259_pic_irq_offset = offset;
/* init master interrupt controller */ /* init master interrupt controller */
outb(0x11, 0x20); /* Start init sequence */ outb(0x11, 0x20); /* Start init sequence */
outb(0x00, 0x21); /* Vector base */ outb(0x00, 0x21); /* Vector base */
...@@ -198,11 +208,14 @@ i8259_init(long intack_addr) ...@@ -198,11 +208,14 @@ i8259_init(long intack_addr)
spin_unlock_irqrestore(&i8259_lock, flags); spin_unlock_irqrestore(&i8259_lock, flags);
/* reserve our resources */ /* reserve our resources */
setup_irq( i8259_pic_irq_offset + 2, &i8259_irqaction); setup_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);
for (i = 0; i < NUM_ISA_INTERRUPTS; ++i)
irq_desc[offset + i].handler = &i8259_pic;
} }
...@@ -589,6 +589,7 @@ config EV64260 ...@@ -589,6 +589,7 @@ config EV64260
config LOPEC config LOPEC
bool "Motorola-LoPEC" bool "Motorola-LoPEC"
select PPC_I8259
config MVME5100 config MVME5100
bool "Motorola-MVME5100" bool "Motorola-MVME5100"
...@@ -596,6 +597,7 @@ config MVME5100 ...@@ -596,6 +597,7 @@ config MVME5100
config PPLUS config PPLUS
bool "Motorola-PowerPlus" bool "Motorola-PowerPlus"
select PPC_I8259
select PPC_INDIRECT_PCI select PPC_INDIRECT_PCI
config PRPMC750 config PRPMC750
...@@ -608,12 +610,14 @@ config PRPMC800 ...@@ -608,12 +610,14 @@ config PRPMC800
config SANDPOINT config SANDPOINT
bool "Motorola-Sandpoint" bool "Motorola-Sandpoint"
select PPC_I8259
help help
Select SANDPOINT if configuring for a Motorola Sandpoint X3 Select SANDPOINT if configuring for a Motorola Sandpoint X3
(any flavor). (any flavor).
config RADSTONE_PPC7D config RADSTONE_PPC7D
bool "Radstone Technology PPC7D board" bool "Radstone Technology PPC7D board"
select PPC_I8259
config PAL4 config PAL4
bool "SBS-Palomar4" bool "SBS-Palomar4"
...@@ -755,6 +759,7 @@ config CPM2 ...@@ -755,6 +759,7 @@ config CPM2
config PPC_CHRP config PPC_CHRP
bool " Common Hardware Reference Platform (CHRP) based machines" bool " Common Hardware Reference Platform (CHRP) based machines"
depends on PPC_MULTIPLATFORM depends on PPC_MULTIPLATFORM
select PPC_I8259
select PPC_INDIRECT_PCI select PPC_INDIRECT_PCI
default y default y
...@@ -772,6 +777,7 @@ config PPC_PMAC64 ...@@ -772,6 +777,7 @@ config PPC_PMAC64
config PPC_PREP config PPC_PREP
bool " PowerPC Reference Platform (PReP) based machines" bool " PowerPC Reference Platform (PReP) based machines"
depends on PPC_MULTIPLATFORM depends on PPC_MULTIPLATFORM
select PPC_I8259
select PPC_INDIRECT_PCI select PPC_INDIRECT_PCI
default y default y
...@@ -881,6 +887,7 @@ config HARRIER_STORE_GATHERING ...@@ -881,6 +887,7 @@ config HARRIER_STORE_GATHERING
config MVME5100_IPMC761_PRESENT config MVME5100_IPMC761_PRESENT
bool "MVME5100 configured with an IPMC761" bool "MVME5100 configured with an IPMC761"
depends on MVME5100 depends on MVME5100
select PPC_I8259
config SPRUCE_BAUD_33M config SPRUCE_BAUD_33M
bool "Spruce baud clock support" bool "Spruce baud clock support"
...@@ -1138,6 +1145,7 @@ menu "Bus options" ...@@ -1138,6 +1145,7 @@ menu "Bus options"
config ISA config ISA
bool "Support for ISA-bus hardware" bool "Support for ISA-bus hardware"
depends on PPC_PREP || PPC_CHRP depends on PPC_PREP || PPC_CHRP
select PPC_I8259
help help
Find out whether you have ISA slots on your motherboard. ISA is the Find out whether you have ISA slots on your motherboard. ISA is the
name of a bus system, i.e. the way the CPU talks to the other stuff name of a bus system, i.e. the way the CPU talks to the other stuff
...@@ -1150,6 +1158,11 @@ config GENERIC_ISA_DMA ...@@ -1150,6 +1158,11 @@ config GENERIC_ISA_DMA
depends on POWER3 || POWER4 || 6xx && !CPM2 depends on POWER3 || POWER4 || 6xx && !CPM2
default y default y
config PPC_I8259
bool
default y if 85xx
default n
config PPC_INDIRECT_PCI config PPC_INDIRECT_PCI
bool bool
depends on PCI depends on PCI
...@@ -1192,6 +1205,7 @@ config MPC83xx_PCI2 ...@@ -1192,6 +1205,7 @@ config MPC83xx_PCI2
config PCI_QSPAN config PCI_QSPAN
bool "QSpan PCI" bool "QSpan PCI"
depends on !4xx && !CPM2 && 8xx depends on !4xx && !CPM2 && 8xx
select PPC_I8259
help help
Say Y here if you have a system based on a Motorola 8xx-series Say Y here if you have a system based on a Motorola 8xx-series
embedded processor with a QSPAN PCI interface, otherwise say N. embedded processor with a QSPAN PCI interface, otherwise say N.
......
...@@ -173,10 +173,7 @@ mpc85xx_cds_init_IRQ(void) ...@@ -173,10 +173,7 @@ mpc85xx_cds_init_IRQ(void)
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
openpic_hookup_cascade(PIRQ0A, "82c59 cascade", i8259_irq); openpic_hookup_cascade(PIRQ0A, "82c59 cascade", i8259_irq);
for (i = 0; i < NUM_8259_INTERRUPTS; i++) i8259_init(0, 0);
irq_desc[i].handler = &i8259_pic;
i8259_init(0);
#endif #endif
#ifdef CONFIG_CPM2 #ifdef CONFIG_CPM2
......
...@@ -436,9 +436,7 @@ void __init chrp_init_IRQ(void) ...@@ -436,9 +436,7 @@ void __init chrp_init_IRQ(void)
i8259_irq); i8259_irq);
} }
for (i = 0; i < NUM_8259_INTERRUPTS; i++) i8259_init(chrp_int_ack, 0);
irq_desc[i].handler = &i8259_pic;
i8259_init(chrp_int_ack);
#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) #if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
/* see if there is a keyboard in the device tree /* see if there is a keyboard in the device tree
......
...@@ -267,15 +267,11 @@ lopec_init_IRQ(void) ...@@ -267,15 +267,11 @@ lopec_init_IRQ(void)
openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade", openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
&i8259_irq); &i8259_irq);
/* Map i8259 interrupts */
for(i = 0; i < NUM_8259_INTERRUPTS; i++)
irq_desc[i].handler = &i8259_pic;
/* /*
* The EPIC allows for a read in the range of 0xFEF00000 -> * The EPIC allows for a read in the range of 0xFEF00000 ->
* 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction. * 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction.
*/ */
i8259_init(0xfef00000); i8259_init(0xfef00000, 0);
} }
static int __init static int __init
......
...@@ -223,11 +223,7 @@ mvme5100_init_IRQ(void) ...@@ -223,11 +223,7 @@ mvme5100_init_IRQ(void)
openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade", openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
&i8259_irq); &i8259_irq);
/* Map i8259 interrupts. */ i8259_init(0, 0);
for (i = 0; i < NUM_8259_INTERRUPTS; i++)
irq_desc[i].handler = &i8259_pic;
i8259_init(0);
#else #else
openpic_init(0); openpic_init(0);
#endif #endif
......
...@@ -665,10 +665,7 @@ static void __init pplus_init_IRQ(void) ...@@ -665,10 +665,7 @@ static void __init pplus_init_IRQ(void)
ppc_md.get_irq = openpic_get_irq; ppc_md.get_irq = openpic_get_irq;
} }
for (i = 0; i < NUM_8259_INTERRUPTS; i++) i8259_init(0, 0);
irq_desc[i].handler = &i8259_pic;
i8259_init(0);
if (ppc_md.progress) if (ppc_md.progress)
ppc_md.progress("init_irq: exit", 0); ppc_md.progress("init_irq: exit", 0);
......
...@@ -954,11 +954,9 @@ prep_init_IRQ(void) ...@@ -954,11 +954,9 @@ prep_init_IRQ(void)
openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade", openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
i8259_irq); i8259_irq);
} }
for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ )
irq_desc[i].handler = &i8259_pic;
if (have_residual_data) { if (have_residual_data) {
i8259_init(residual_isapic_addr()); i8259_init(residual_isapic_addr(), 0);
return; return;
} }
...@@ -969,11 +967,11 @@ prep_init_IRQ(void) ...@@ -969,11 +967,11 @@ prep_init_IRQ(void)
if (((pci_viddid & 0xffff) == PCI_VENDOR_ID_MOTOROLA) if (((pci_viddid & 0xffff) == PCI_VENDOR_ID_MOTOROLA)
&& ((pci_did == PCI_DEVICE_ID_MOTOROLA_RAVEN) && ((pci_did == PCI_DEVICE_ID_MOTOROLA_RAVEN)
|| (pci_did == PCI_DEVICE_ID_MOTOROLA_HAWK))) || (pci_did == PCI_DEVICE_ID_MOTOROLA_HAWK)))
i8259_init(0); i8259_init(0, 0);
else else
/* PCI interrupt ack address given in section 6.1.8 of the /* PCI interrupt ack address given in section 6.1.8 of the
* PReP specification. */ * PReP specification. */
i8259_init(MPC10X_MAPA_PCI_INTACK_ADDR); i8259_init(MPC10X_MAPA_PCI_INTACK_ADDR, 0);
} }
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
......
...@@ -514,13 +514,9 @@ static void __init ppc7d_init_irq(void) ...@@ -514,13 +514,9 @@ static void __init ppc7d_init_irq(void)
int irq; int irq;
pr_debug("%s\n", __FUNCTION__); pr_debug("%s\n", __FUNCTION__);
i8259_init(0); i8259_init(0, 0);
mv64360_init_irq(); mv64360_init_irq();
/* IRQ 0..15 are handled by the cascaded 8259's of the Ali1535 */
for (irq = 0; irq < 16; irq++) {
irq_desc[irq].handler = &i8259_pic;
}
/* IRQs 5,6,9,10,11,14,15 are level sensitive */ /* IRQs 5,6,9,10,11,14,15 are level sensitive */
irq_desc[5].status |= IRQ_LEVEL; irq_desc[5].status |= IRQ_LEVEL;
irq_desc[6].status |= IRQ_LEVEL; irq_desc[6].status |= IRQ_LEVEL;
......
...@@ -493,19 +493,11 @@ sandpoint_init_IRQ(void) ...@@ -493,19 +493,11 @@ sandpoint_init_IRQ(void)
openpic_hookup_cascade(sandpoint_is_x2 ? 17 : NUM_8259_INTERRUPTS, "82c59 cascade", openpic_hookup_cascade(sandpoint_is_x2 ? 17 : NUM_8259_INTERRUPTS, "82c59 cascade",
i8259_irq); i8259_irq);
/*
* openpic_init() has set up irq_desc[16-31] to be openpic
* interrupts. We need to set irq_desc[0-15] to be i8259
* interrupts.
*/
for(i=0; i < NUM_8259_INTERRUPTS; i++)
irq_desc[i].handler = &i8259_pic;
/* /*
* The EPIC allows for a read in the range of 0xFEF00000 -> * The EPIC allows for a read in the range of 0xFEF00000 ->
* 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction. * 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction.
*/ */
i8259_init(0xfef00000); i8259_init(0xfef00000, 0);
} }
static unsigned long __init static unsigned long __init
......
...@@ -36,14 +36,12 @@ endif ...@@ -36,14 +36,12 @@ endif
endif endif
obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \ obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \
ppc_sys.o mpc8xx_devices.o mpc8xx_sys.o ppc_sys.o mpc8xx_devices.o mpc8xx_sys.o
ifeq ($(CONFIG_8xx),y) obj-$(CONFIG_PCI_QSPAN) += qspan_pci.o
obj-$(CONFIG_PCI) += qspan_pci.o i8259.o
endif
obj-$(CONFIG_PPC_OF) += prom_init.o prom.o obj-$(CONFIG_PPC_OF) += prom_init.o prom.o
obj-$(CONFIG_PPC_PMAC) += open_pic.o obj-$(CONFIG_PPC_PMAC) += open_pic.o
obj-$(CONFIG_POWER4) += open_pic2.o obj-$(CONFIG_POWER4) += open_pic2.o
obj-$(CONFIG_PPC_CHRP) += open_pic.o i8259.o obj-$(CONFIG_PPC_CHRP) += open_pic.o
obj-$(CONFIG_PPC_PREP) += open_pic.o i8259.o todc_time.o obj-$(CONFIG_PPC_PREP) += open_pic.o todc_time.o
obj-$(CONFIG_BAMBOO) += pci_auto.o todc_time.o obj-$(CONFIG_BAMBOO) += pci_auto.o todc_time.o
obj-$(CONFIG_CPCI690) += todc_time.o pci_auto.o obj-$(CONFIG_CPCI690) += todc_time.o pci_auto.o
obj-$(CONFIG_EBONY) += pci_auto.o todc_time.o obj-$(CONFIG_EBONY) += pci_auto.o todc_time.o
...@@ -51,7 +49,7 @@ obj-$(CONFIG_EV64260) += todc_time.o pci_auto.o ...@@ -51,7 +49,7 @@ obj-$(CONFIG_EV64260) += todc_time.o pci_auto.o
obj-$(CONFIG_CHESTNUT) += mv64360_pic.o pci_auto.o obj-$(CONFIG_CHESTNUT) += mv64360_pic.o pci_auto.o
obj-$(CONFIG_GEMINI) += open_pic.o obj-$(CONFIG_GEMINI) += open_pic.o
obj-$(CONFIG_GT64260) += gt64260_pic.o obj-$(CONFIG_GT64260) += gt64260_pic.o
obj-$(CONFIG_LOPEC) += i8259.o pci_auto.o todc_time.o obj-$(CONFIG_LOPEC) += pci_auto.o todc_time.o
obj-$(CONFIG_HDPU) += pci_auto.o obj-$(CONFIG_HDPU) += pci_auto.o
obj-$(CONFIG_LUAN) += pci_auto.o todc_time.o obj-$(CONFIG_LUAN) += pci_auto.o todc_time.o
obj-$(CONFIG_KATANA) += pci_auto.o obj-$(CONFIG_KATANA) += pci_auto.o
...@@ -59,18 +57,17 @@ obj-$(CONFIG_MV64360) += mv64360_pic.o ...@@ -59,18 +57,17 @@ obj-$(CONFIG_MV64360) += mv64360_pic.o
obj-$(CONFIG_MV64X60) += mv64x60.o mv64x60_win.o obj-$(CONFIG_MV64X60) += mv64x60.o mv64x60_win.o
obj-$(CONFIG_MVME5100) += open_pic.o todc_time.o \ obj-$(CONFIG_MVME5100) += open_pic.o todc_time.o \
pci_auto.o hawk_common.o pci_auto.o hawk_common.o
obj-$(CONFIG_MVME5100_IPMC761_PRESENT) += i8259.o
obj-$(CONFIG_OCOTEA) += pci_auto.o todc_time.o obj-$(CONFIG_OCOTEA) += pci_auto.o todc_time.o
obj-$(CONFIG_PAL4) += cpc700_pic.o obj-$(CONFIG_PAL4) += cpc700_pic.o
obj-$(CONFIG_POWERPMC250) += pci_auto.o obj-$(CONFIG_POWERPMC250) += pci_auto.o
obj-$(CONFIG_PPLUS) += hawk_common.o open_pic.o i8259.o \ obj-$(CONFIG_PPLUS) += hawk_common.o open_pic.o \
todc_time.o pci_auto.o todc_time.o pci_auto.o
obj-$(CONFIG_PRPMC750) += open_pic.o pci_auto.o \ obj-$(CONFIG_PRPMC750) += open_pic.o pci_auto.o \
hawk_common.o hawk_common.o
obj-$(CONFIG_HARRIER) += harrier.o obj-$(CONFIG_HARRIER) += harrier.o
obj-$(CONFIG_PRPMC800) += open_pic.o pci_auto.o obj-$(CONFIG_PRPMC800) += open_pic.o pci_auto.o
obj-$(CONFIG_RADSTONE_PPC7D) += i8259.o pci_auto.o obj-$(CONFIG_RADSTONE_PPC7D) += pci_auto.o
obj-$(CONFIG_SANDPOINT) += i8259.o pci_auto.o todc_time.o obj-$(CONFIG_SANDPOINT) += pci_auto.o todc_time.o
obj-$(CONFIG_SBC82xx) += todc_time.o obj-$(CONFIG_SBC82xx) += todc_time.o
obj-$(CONFIG_SPRUCE) += cpc700_pic.o pci_auto.o \ obj-$(CONFIG_SPRUCE) += cpc700_pic.o pci_auto.o \
todc_time.o todc_time.o
...@@ -92,7 +89,7 @@ obj-$(CONFIG_MPC10X_OPENPIC) += open_pic.o ...@@ -92,7 +89,7 @@ obj-$(CONFIG_MPC10X_OPENPIC) += open_pic.o
obj-$(CONFIG_40x) += dcr.o obj-$(CONFIG_40x) += dcr.o
obj-$(CONFIG_BOOKE) += dcr.o obj-$(CONFIG_BOOKE) += dcr.o
obj-$(CONFIG_85xx) += open_pic.o ppc85xx_common.o ppc85xx_setup.o \ obj-$(CONFIG_85xx) += open_pic.o ppc85xx_common.o ppc85xx_setup.o \
ppc_sys.o i8259.o mpc85xx_sys.o \ ppc_sys.o mpc85xx_sys.o \
mpc85xx_devices.o mpc85xx_devices.o
ifeq ($(CONFIG_85xx),y) ifeq ($(CONFIG_85xx),y)
obj-$(CONFIG_PCI) += pci_auto.o obj-$(CONFIG_PCI) += pci_auto.o
......
...@@ -123,6 +123,11 @@ config MPIC ...@@ -123,6 +123,11 @@ config MPIC
bool bool
default y default y
config PPC_I8259
depends on PPC_PSERIES
bool
default y
config BPA_IIC config BPA_IIC
depends on PPC_BPA depends on PPC_BPA
bool bool
......
...@@ -24,7 +24,7 @@ pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o ...@@ -24,7 +24,7 @@ pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o
obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y)
obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o
ifneq ($(CONFIG_PPC_MERGE),y) ifneq ($(CONFIG_PPC_MERGE),y)
obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o
endif endif
......
/*
* c 2001 PPC64 Team, IBM Corp
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/stddef.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/cache.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/ppcdebug.h>
#include "i8259.h"
unsigned char cached_8259[2] = { 0xff, 0xff };
#define cached_A1 (cached_8259[0])
#define cached_21 (cached_8259[1])
static __cacheline_aligned_in_smp DEFINE_SPINLOCK(i8259_lock);
static int i8259_pic_irq_offset;
static int i8259_present;
int i8259_irq(int cpu)
{
int irq;
spin_lock/*_irqsave*/(&i8259_lock/*, flags*/);
/*
* Perform an interrupt acknowledge cycle on controller 1
*/
outb(0x0C, 0x20);
irq = inb(0x20) & 7;
if (irq == 2)
{
/*
* Interrupt is cascaded so perform interrupt
* acknowledge on controller 2
*/
outb(0x0C, 0xA0);
irq = (inb(0xA0) & 7) + 8;
}
else if (irq==7)
{
/*
* This may be a spurious interrupt
*
* Read the interrupt status register. If the most
* significant bit is not set then there is no valid
* interrupt
*/
outb(0x0b, 0x20);
if(~inb(0x20)&0x80) {
spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/);
return -1;
}
}
spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/);
return irq;
}
static void i8259_mask_and_ack_irq(unsigned int irq_nr)
{
unsigned long flags;
spin_lock_irqsave(&i8259_lock, flags);
if ( irq_nr >= i8259_pic_irq_offset )
irq_nr -= i8259_pic_irq_offset;
if (irq_nr > 7) {
cached_A1 |= 1 << (irq_nr-8);
inb(0xA1); /* DUMMY */
outb(cached_A1,0xA1);
outb(0x20,0xA0); /* Non-specific EOI */
outb(0x20,0x20); /* Non-specific EOI to cascade */
} else {
cached_21 |= 1 << irq_nr;
inb(0x21); /* DUMMY */
outb(cached_21,0x21);
outb(0x20,0x20); /* Non-specific EOI */
}
spin_unlock_irqrestore(&i8259_lock, flags);
}
static void i8259_set_irq_mask(int irq_nr)
{
outb(cached_A1,0xA1);
outb(cached_21,0x21);
}
static void i8259_mask_irq(unsigned int irq_nr)
{
unsigned long flags;
spin_lock_irqsave(&i8259_lock, flags);
if ( irq_nr >= i8259_pic_irq_offset )
irq_nr -= i8259_pic_irq_offset;
if ( irq_nr < 8 )
cached_21 |= 1 << irq_nr;
else
cached_A1 |= 1 << (irq_nr-8);
i8259_set_irq_mask(irq_nr);
spin_unlock_irqrestore(&i8259_lock, flags);
}
static void i8259_unmask_irq(unsigned int irq_nr)
{
unsigned long flags;
spin_lock_irqsave(&i8259_lock, flags);
if ( irq_nr >= i8259_pic_irq_offset )
irq_nr -= i8259_pic_irq_offset;
if ( irq_nr < 8 )
cached_21 &= ~(1 << irq_nr);
else
cached_A1 &= ~(1 << (irq_nr-8));
i8259_set_irq_mask(irq_nr);
spin_unlock_irqrestore(&i8259_lock, flags);
}
static void i8259_end_irq(unsigned int irq)
{
if (!(get_irq_desc(irq)->status & (IRQ_DISABLED|IRQ_INPROGRESS)) &&
get_irq_desc(irq)->action)
i8259_unmask_irq(irq);
}
struct hw_interrupt_type i8259_pic = {
.typename = " i8259 ",
.enable = i8259_unmask_irq,
.disable = i8259_mask_irq,
.ack = i8259_mask_and_ack_irq,
.end = i8259_end_irq,
};
void __init i8259_init(int offset)
{
unsigned long flags;
spin_lock_irqsave(&i8259_lock, flags);
i8259_pic_irq_offset = offset;
i8259_present = 1;
/* init master interrupt controller */
outb(0x11, 0x20); /* Start init sequence */
outb(0x00, 0x21); /* Vector base */
outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */
outb(0x01, 0x21); /* Select 8086 mode */
outb(0xFF, 0x21); /* Mask all */
/* init slave interrupt controller */
outb(0x11, 0xA0); /* Start init sequence */
outb(0x08, 0xA1); /* Vector base */
outb(0x02, 0xA1); /* edge triggered, Cascade (slave) on IRQ2 */
outb(0x01, 0xA1); /* Select 8086 mode */
outb(0xFF, 0xA1); /* Mask all */
outb(cached_A1, 0xA1);
outb(cached_21, 0x21);
spin_unlock_irqrestore(&i8259_lock, flags);
}
static int i8259_request_cascade(void)
{
if (!i8259_present)
return -ENODEV;
request_irq( i8259_pic_irq_offset + 2, no_action, SA_INTERRUPT,
"82c59 secondary cascade", NULL );
return 0;
}
arch_initcall(i8259_request_cascade);
...@@ -5,7 +5,8 @@ ...@@ -5,7 +5,8 @@
extern struct hw_interrupt_type i8259_pic; extern struct hw_interrupt_type i8259_pic;
extern void i8259_init(long intack_addr); extern void i8259_init(unsigned long intack_addr, int offset);
extern int i8259_irq(struct pt_regs *regs); extern int i8259_irq(struct pt_regs *regs);
extern int i8259_irq_cascade(struct pt_regs *regs, void *unused);
#endif /* _ASM_POWERPC_I8259_H */ #endif /* _ASM_POWERPC_I8259_H */
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