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>
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index a3451d5..9f279e0 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -275,11 +275,13 @@
 config PPC_PSERIES
 	depends on PPC_MULTIPLATFORM && PPC64
 	bool "  IBM pSeries & new (POWER5-based) iSeries"
+	select PPC_I8259
 	default y
 
 config PPC_CHRP
 	bool "  Common Hardware Reference Platform (CHRP) based machines"
 	depends on PPC_MULTIPLATFORM && PPC32
+	select PPC_I8259
 	select PPC_INDIRECT_PCI
 	default y
 
@@ -298,6 +300,7 @@
 config PPC_PREP
 	bool "  PowerPC Reference Platform (PReP) based machines"
 	depends on PPC_MULTIPLATFORM && PPC32
+	select PPC_I8259
 	select PPC_INDIRECT_PCI
 	default y
 
@@ -628,6 +631,7 @@
 config ISA
 	bool "Support for ISA-bus hardware"
 	depends on PPC_PREP || PPC_CHRP
+	select PPC_I8259
 	help
 	  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
@@ -640,6 +644,11 @@
 	depends on PPC64 || POWER4 || 6xx && !CPM2
 	default y
 
+config PPC_I8259
+	bool
+	default y if 85xx
+	default n
+
 config PPC_INDIRECT_PCI
 	bool
 	depends on PCI
@@ -679,6 +688,7 @@
 config PCI_QSPAN
 	bool "QSpan PCI"
 	depends on !4xx && !CPM2 && 8xx
+	select PPC_I8259
 	help
 	  Say Y here if you have a system based on a Motorola 8xx-series
 	  embedded processor with a QSPAN PCI interface, otherwise say N.
diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig
index 784b41e..81250090 100644
--- a/arch/powerpc/platforms/embedded6xx/Kconfig
+++ b/arch/powerpc/platforms/embedded6xx/Kconfig
@@ -48,6 +48,7 @@
 
 config LOPEC
 	bool "Motorola-LoPEC"
+	select PPC_I8259
 
 config MVME5100
 	bool "Motorola-MVME5100"
@@ -55,6 +56,7 @@
 
 config PPLUS
 	bool "Motorola-PowerPlus"
+	select PPC_I8259
 	select PPC_INDIRECT_PCI
 
 config PRPMC750
@@ -67,12 +69,14 @@
 
 config SANDPOINT
 	bool "Motorola-Sandpoint"
+	select PPC_I8259
 	help
 	  Select SANDPOINT if configuring for a Motorola Sandpoint X3
 	  (any flavor).
 
 config RADSTONE_PPC7D
 	bool "Radstone Technology PPC7D board"
+	select PPC_I8259
 
 config PAL4
 	bool "SBS-Palomar4"
@@ -307,6 +311,7 @@
 config MVME5100_IPMC761_PRESENT
 	bool "MVME5100 configured with an IPMC761"
 	depends on MVME5100
+	select PPC_I8259
 
 config SPRUCE_BAUD_33M
 	bool "Spruce baud clock support"
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 92d1800..0fa5bea 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -87,7 +87,6 @@
 static void pseries_shared_idle(void);
 static void pseries_dedicated_idle(void);
 
-static volatile void __iomem * chrp_int_ack_special;
 struct mpic *pSeries_mpic;
 
 void pSeries_show_cpuinfo(struct seq_file *m)
@@ -119,19 +118,11 @@
 		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)
 {
         unsigned int *addrp;
 	struct device_node *np;
-        int i;
+	unsigned long intack = 0;
 
 	/* All ISUs are setup, complete initialization */
 	mpic_init(pSeries_mpic);
@@ -142,16 +133,14 @@
                  get_property(np, "8259-interrupt-acknowledge", NULL)))
                 printk(KERN_ERR "Cannot find pci to get ack address\n");
         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);
 
 	/* 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 */
-	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)
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index e66fef6..f3c9e61 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_MPIC)		+= mpic.o
 obj-$(CONFIG_PPC_INDIRECT_PCI)	+= indirect_pci.o
+obj-$(CONFIG_PPC_I8259)		+= i8259.o
diff --git a/arch/ppc/syslib/i8259.c b/arch/powerpc/sysdev/i8259.c
similarity index 76%
rename from arch/ppc/syslib/i8259.c
rename to arch/powerpc/sysdev/i8259.c
index 5c7908c..90bce6e 100644
--- a/arch/ppc/syslib/i8259.c
+++ b/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/ioport.h>
 #include <linux/interrupt.h>
 #include <asm/io.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_21 (cached_8259[1])
 
 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
@@ -20,8 +28,7 @@
  * 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.
  */
-int
-i8259_irq(struct pt_regs *regs)
+int i8259_irq(struct pt_regs *regs)
 {
 	int irq;
 
@@ -29,7 +36,7 @@
 
 	/* Either int-ack or poll for the IRQ */
 	if (pci_intack)
-		irq = *pci_intack;
+		irq = readb(pci_intack);
 	else {
 		/* Perform an interrupt acknowledge cycle on controller 1. */
 		outb(0x0C, 0x20);		/* prepare for poll */
@@ -59,7 +66,12 @@
 	}
 
 	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)
@@ -67,20 +79,18 @@
 	unsigned long 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) {
 		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 {
 		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);
 }
@@ -96,9 +106,8 @@
 	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 )
+	irq_nr -= i8259_pic_irq_offset;
+	if (irq_nr < 8)
 		cached_21 |= 1 << irq_nr;
 	else
 		cached_A1 |= 1 << (irq_nr-8);
@@ -111,9 +120,8 @@
 	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 )
+	irq_nr -= i8259_pic_irq_offset;
+	if (irq_nr < 8)
 		cached_21 &= ~(1 << irq_nr);
 	else
 		cached_A1 &= ~(1 << (irq_nr-8));
@@ -169,12 +177,14 @@
  * 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(unsigned long intack_addr, int offset)
 {
 	unsigned long flags;
+	int i;
 
 	spin_lock_irqsave(&i8259_lock, flags);
+	i8259_pic_irq_offset = offset;
+
 	/* init master interrupt controller */
 	outb(0x11, 0x20); /* Start init sequence */
 	outb(0x00, 0x21); /* Vector base */
@@ -198,11 +208,14 @@
 	spin_unlock_irqrestore(&i8259_lock, flags);
 
 	/* 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, &pic2_iores);
 	request_resource(&ioport_resource, &pic_edgectrl_iores);
 
 	if (intack_addr != 0)
 		pci_intack = ioremap(intack_addr, 1);
+
+	for (i = 0; i < NUM_ISA_INTERRUPTS; ++i)
+		irq_desc[offset + i].handler = &i8259_pic;
 }
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index e3efaf4..114b90f 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -589,6 +589,7 @@
 
 config LOPEC
 	bool "Motorola-LoPEC"
+	select PPC_I8259
 
 config MVME5100
 	bool "Motorola-MVME5100"
@@ -596,6 +597,7 @@
 
 config PPLUS
 	bool "Motorola-PowerPlus"
+	select PPC_I8259
 	select PPC_INDIRECT_PCI
 
 config PRPMC750
@@ -608,12 +610,14 @@
 
 config SANDPOINT
 	bool "Motorola-Sandpoint"
+	select PPC_I8259
 	help
 	  Select SANDPOINT if configuring for a Motorola Sandpoint X3
 	  (any flavor).
 
 config RADSTONE_PPC7D
 	bool "Radstone Technology PPC7D board"
+	select PPC_I8259
 
 config PAL4
 	bool "SBS-Palomar4"
@@ -755,6 +759,7 @@
 config PPC_CHRP
 	bool "  Common Hardware Reference Platform (CHRP) based machines"
 	depends on PPC_MULTIPLATFORM
+	select PPC_I8259
 	select PPC_INDIRECT_PCI
 	default y
 
@@ -772,6 +777,7 @@
 config PPC_PREP
 	bool "  PowerPC Reference Platform (PReP) based machines"
 	depends on PPC_MULTIPLATFORM
+	select PPC_I8259
 	select PPC_INDIRECT_PCI
 	default y
 
@@ -881,6 +887,7 @@
 config MVME5100_IPMC761_PRESENT
 	bool "MVME5100 configured with an IPMC761"
 	depends on MVME5100
+	select PPC_I8259
 
 config SPRUCE_BAUD_33M
 	bool "Spruce baud clock support"
@@ -1138,6 +1145,7 @@
 config ISA
 	bool "Support for ISA-bus hardware"
 	depends on PPC_PREP || PPC_CHRP
+	select PPC_I8259
 	help
 	  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
@@ -1150,6 +1158,11 @@
 	depends on POWER3 || POWER4 || 6xx && !CPM2
 	default y
 
+config PPC_I8259
+	bool
+	default y if 85xx
+	default n
+
 config PPC_INDIRECT_PCI
 	bool
 	depends on PCI
@@ -1192,6 +1205,7 @@
 config PCI_QSPAN
 	bool "QSpan PCI"
 	depends on !4xx && !CPM2 && 8xx
+	select PPC_I8259
 	help
 	  Say Y here if you have a system based on a Motorola 8xx-series
 	  embedded processor with a QSPAN PCI interface, otherwise say N.
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
index 9f90394..eda6599 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
+++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
@@ -173,10 +173,7 @@
 #ifdef CONFIG_PCI
 	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
 
 #ifdef CONFIG_CPM2
diff --git a/arch/ppc/platforms/chrp_setup.c b/arch/ppc/platforms/chrp_setup.c
index 56c53bb..dad81ff 100644
--- a/arch/ppc/platforms/chrp_setup.c
+++ b/arch/ppc/platforms/chrp_setup.c
@@ -436,9 +436,7 @@
 				       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)
 	/* see if there is a keyboard in the device tree
diff --git a/arch/ppc/platforms/lopec.c b/arch/ppc/platforms/lopec.c
index 800c56a..06d247c 100644
--- a/arch/ppc/platforms/lopec.c
+++ b/arch/ppc/platforms/lopec.c
@@ -267,15 +267,11 @@
 	openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
 			&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 ->
 	 * 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction.
 	 */
-	i8259_init(0xfef00000);
+	i8259_init(0xfef00000, 0);
 }
 
 static int __init
diff --git a/arch/ppc/platforms/mvme5100.c b/arch/ppc/platforms/mvme5100.c
index ce2ce88..108eb18 100644
--- a/arch/ppc/platforms/mvme5100.c
+++ b/arch/ppc/platforms/mvme5100.c
@@ -223,11 +223,7 @@
 	openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
 			&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
 	openpic_init(0);
 #endif
diff --git a/arch/ppc/platforms/pplus.c b/arch/ppc/platforms/pplus.c
index 59eb330..22bd40c 100644
--- a/arch/ppc/platforms/pplus.c
+++ b/arch/ppc/platforms/pplus.c
@@ -665,10 +665,7 @@
 		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)
 		ppc_md.progress("init_irq: exit", 0);
diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c
index 9e5637e..067d7d5 100644
--- a/arch/ppc/platforms/prep_setup.c
+++ b/arch/ppc/platforms/prep_setup.c
@@ -954,11 +954,9 @@
 		openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
 				       i8259_irq);
 	}
-	for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ )
-		irq_desc[i].handler = &i8259_pic;
 
 	if (have_residual_data) {
-		i8259_init(residual_isapic_addr());
+		i8259_init(residual_isapic_addr(), 0);
 		return;
 	}
 
@@ -969,11 +967,11 @@
 	if (((pci_viddid & 0xffff) == PCI_VENDOR_ID_MOTOROLA)
 			&& ((pci_did == PCI_DEVICE_ID_MOTOROLA_RAVEN)
 				|| (pci_did == PCI_DEVICE_ID_MOTOROLA_HAWK)))
-		i8259_init(0);
+		i8259_init(0, 0);
 	else
 		/* PCI interrupt ack address given in section 6.1.8 of the
 		 * 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)
diff --git a/arch/ppc/platforms/radstone_ppc7d.c b/arch/ppc/platforms/radstone_ppc7d.c
index 5058568..6f97911 100644
--- a/arch/ppc/platforms/radstone_ppc7d.c
+++ b/arch/ppc/platforms/radstone_ppc7d.c
@@ -514,13 +514,9 @@
 	int irq;
 
 	pr_debug("%s\n", __FUNCTION__);
-	i8259_init(0);
+	i8259_init(0, 0);
 	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 */
 	irq_desc[5].status |= IRQ_LEVEL;
 	irq_desc[6].status |= IRQ_LEVEL;
diff --git a/arch/ppc/platforms/sandpoint.c b/arch/ppc/platforms/sandpoint.c
index d4c9781..9eeed35 100644
--- a/arch/ppc/platforms/sandpoint.c
+++ b/arch/ppc/platforms/sandpoint.c
@@ -494,18 +494,10 @@
 			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 ->
 	 * 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction.
 	 */
-	i8259_init(0xfef00000);
+	i8259_init(0xfef00000, 0);
 }
 
 static unsigned long __init
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
index 5739a19..e6e6aa4 100644
--- a/arch/ppc/syslib/Makefile
+++ b/arch/ppc/syslib/Makefile
@@ -36,14 +36,12 @@
 endif
 obj-$(CONFIG_8xx)		+= m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \
 				   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_PMAC)		+= open_pic.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_CPCI690)		+= todc_time.o pci_auto.o
 obj-$(CONFIG_EBONY)		+= pci_auto.o todc_time.o
@@ -51,7 +49,7 @@
 obj-$(CONFIG_CHESTNUT)		+= mv64360_pic.o pci_auto.o
 obj-$(CONFIG_GEMINI)		+= open_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_LUAN)		+= pci_auto.o todc_time.o
 obj-$(CONFIG_KATANA)		+= pci_auto.o
@@ -59,18 +57,17 @@
 obj-$(CONFIG_MV64X60)		+= mv64x60.o mv64x60_win.o
 obj-$(CONFIG_MVME5100)		+= open_pic.o todc_time.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_PAL4)		+= cpc700_pic.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
 obj-$(CONFIG_PRPMC750)		+= open_pic.o pci_auto.o \
 					hawk_common.o
 obj-$(CONFIG_HARRIER)		+= harrier.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_SPRUCE)		+= cpc700_pic.o pci_auto.o \
 				   todc_time.o
@@ -92,7 +89,7 @@
 obj-$(CONFIG_40x)		+= dcr.o
 obj-$(CONFIG_BOOKE)		+= dcr.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
 ifeq ($(CONFIG_85xx),y)
 obj-$(CONFIG_PCI)		+= pci_auto.o
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
index 8cbac7f..963f519 100644
--- a/arch/ppc64/Kconfig
+++ b/arch/ppc64/Kconfig
@@ -123,6 +123,11 @@
 	bool
 	default y
 
+config PPC_I8259
+	depends on PPC_PSERIES
+	bool
+	default y
+
 config BPA_IIC
 	depends on PPC_BPA
 	bool
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
index cb6ac3d1..2c541c6 100644
--- a/arch/ppc64/kernel/Makefile
+++ b/arch/ppc64/kernel/Makefile
@@ -24,7 +24,7 @@
 
 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)
 obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o
 endif
diff --git a/arch/ppc64/kernel/i8259.c b/arch/ppc64/kernel/i8259.c
deleted file mode 100644
index 74dcfd6..0000000
--- a/arch/ppc64/kernel/i8259.c
+++ /dev/null
@@ -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);
diff --git a/include/asm-powerpc/i8259.h b/include/asm-powerpc/i8259.h
index 9521ad4..fc4bfee 100644
--- a/include/asm-powerpc/i8259.h
+++ b/include/asm-powerpc/i8259.h
@@ -5,7 +5,8 @@
 
 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_cascade(struct pt_regs *regs, void *unused);
 
 #endif /* _ASM_POWERPC_I8259_H */