Przeglądaj źródła

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: Paul Mackerras <paulus@samba.org>
Paul Mackerras 19 lat temu
rodzic
commit
f9bd170a87

+ 10 - 0
arch/powerpc/Kconfig

@@ -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
 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"
 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
 	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
 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.

+ 5 - 0
arch/powerpc/platforms/embedded6xx/Kconfig

@@ -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
 
 
 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
 
 
 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
 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"

+ 4 - 15
arch/powerpc/platforms/pseries/setup.c

@@ -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)
 		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)
                  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++)
-                irq_desc[i].handler = &i8259_pic;
-	i8259_init(0);
+	i8259_init(intack, 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)

+ 1 - 0
arch/powerpc/sysdev/Makefile

@@ -1,2 +1,3 @@
 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

+ 39 - 26
arch/ppc/syslib/i8259.c → arch/powerpc/sysdev/i8259.c

@@ -1,18 +1,26 @@
+/*
+ * 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;
  * 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
-i8259_irq(struct pt_regs *regs)
+int i8259_irq(struct pt_regs *regs)
 {
 {
 	int irq;
 	int irq;
 
 
@@ -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)
 	}
 	}
 
 
 	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)
 	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 */
-		outb(cached_A1,0xA1);
-		outb(0x20,0xA0); /* Non-specific EOI */
-		outb(0x20,0x20); /* Non-specific EOI to cascade */
+		inb(0xA1); 	/* DUMMY */
+		outb(cached_A1, 0xA1);
+		outb(0x20, 0xA0);	/* Non-specific EOI */
+		outb(0x20, 0x20);	/* Non-specific EOI to cascade */
 	} else {
 	} else {
 		cached_21 |= 1 << irq_nr;
 		cached_21 |= 1 << irq_nr;
-		inb(0x21); /* DUMMY */
-		outb(cached_21,0x21);
-		outb(0x20,0x20); /* Non-specific EOI */
+		inb(0x21); 	/* DUMMY */
+		outb(cached_21, 0x21);
+		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)
 	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;
-	if ( irq_nr < 8 )
+	irq_nr -= i8259_pic_irq_offset;
+	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)
 	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;
-	if ( irq_nr < 8 )
+	irq_nr -= i8259_pic_irq_offset;
+	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 = {
  * 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
-i8259_init(long intack_addr)
+void __init i8259_init(unsigned long intack_addr, int offset)
 {
 {
 	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)
 	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;
 }
 }

+ 14 - 0
arch/ppc/Kconfig

@@ -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
 
 
 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
 
 
 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
 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
 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
 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"
 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
 	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
 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.

+ 1 - 4
arch/ppc/platforms/85xx/mpc85xx_cds_common.c

@@ -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++)
-		irq_desc[i].handler = &i8259_pic;
-
-	i8259_init(0);
+	i8259_init(0, 0);
 #endif
 #endif
 
 
 #ifdef CONFIG_CPM2
 #ifdef CONFIG_CPM2

+ 1 - 3
arch/ppc/platforms/chrp_setup.c

@@ -436,9 +436,7 @@ void __init chrp_init_IRQ(void)
 				       i8259_irq);
 				       i8259_irq);
 
 
 	}
 	}
-	for (i = 0; i < NUM_8259_INTERRUPTS; i++)
-		irq_desc[i].handler = &i8259_pic;
-	i8259_init(chrp_int_ack);
+	i8259_init(chrp_int_ack, 0);
 
 
 #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

+ 1 - 5
arch/ppc/platforms/lopec.c

@@ -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

+ 1 - 5
arch/ppc/platforms/mvme5100.c

@@ -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. */
-	for (i = 0; i < NUM_8259_INTERRUPTS; i++)
-		irq_desc[i].handler = &i8259_pic;
-
-	i8259_init(0);
+	i8259_init(0, 0);
 #else
 #else
 	openpic_init(0);
 	openpic_init(0);
 #endif
 #endif

+ 1 - 4
arch/ppc/platforms/pplus.c

@@ -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++)
-		irq_desc[i].handler = &i8259_pic;
-
-	i8259_init(0);
+	i8259_init(0, 0);
 
 
 	if (ppc_md.progress)
 	if (ppc_md.progress)
 		ppc_md.progress("init_irq: exit", 0);
 		ppc_md.progress("init_irq: exit", 0);

+ 3 - 5
arch/ppc/platforms/prep_setup.c

@@ -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)
 	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)

+ 1 - 5
arch/ppc/platforms/radstone_ppc7d.c

@@ -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;

+ 1 - 9
arch/ppc/platforms/sandpoint.c

@@ -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

+ 8 - 11
arch/ppc/syslib/Makefile

@@ -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_pci.o i8259.o
-endif
+obj-$(CONFIG_PCI_QSPAN)		+= qspan_pci.o
 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_PREP)		+= open_pic.o i8259.o todc_time.o
+obj-$(CONFIG_PPC_CHRP)		+= open_pic.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
 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
 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_SANDPOINT)		+= i8259.o pci_auto.o todc_time.o
+obj-$(CONFIG_RADSTONE_PPC7D)	+= pci_auto.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
 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

+ 5 - 0
arch/ppc64/Kconfig

@@ -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

+ 1 - 1
arch/ppc64/kernel/Makefile

@@ -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

+ 0 - 177
arch/ppc64/kernel/i8259.c

@@ -1,177 +0,0 @@
-/*
- * 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);

+ 2 - 1
include/asm-powerpc/i8259.h

@@ -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 */