powerpc: Merge i8259.c into arch/powerpc/sysdev
authorPaul Mackerras <paulus@samba.org>
Wed, 26 Oct 2005 06:47:42 +0000 (16:47 +1000)
committerPaul Mackerras <paulus@samba.org>
Wed, 26 Oct 2005 06:47:42 +0000 (16:47 +1000)
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>
20 files changed:
arch/powerpc/Kconfig
arch/powerpc/platforms/embedded6xx/Kconfig
arch/powerpc/platforms/pseries/setup.c
arch/powerpc/sysdev/Makefile
arch/powerpc/sysdev/i8259.c [new file with mode: 0644]
arch/ppc/Kconfig
arch/ppc/platforms/85xx/mpc85xx_cds_common.c
arch/ppc/platforms/chrp_setup.c
arch/ppc/platforms/lopec.c
arch/ppc/platforms/mvme5100.c
arch/ppc/platforms/pplus.c
arch/ppc/platforms/prep_setup.c
arch/ppc/platforms/radstone_ppc7d.c
arch/ppc/platforms/sandpoint.c
arch/ppc/syslib/Makefile
arch/ppc/syslib/i8259.c [deleted file]
arch/ppc64/Kconfig
arch/ppc64/kernel/Makefile
arch/ppc64/kernel/i8259.c [deleted file]
include/asm-powerpc/i8259.h

index a3451d5bb7883f806f86b1c5689d33435c223f98..9f279e0d84f26ca96063f43e2cf48de0d860c14d 100644 (file)
@@ -275,11 +275,13 @@ endchoice
 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_PMAC64
 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 @@ menu "Bus options"
 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 @@ config GENERIC_ISA_DMA
        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 MPC83xx_PCI2
 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.
index 784b41e194652c49319f52c4d6bac217add752d2..81250090f98d39a067f6fe3f0485adfdc70901ae 100644 (file)
@@ -48,6 +48,7 @@ config EV64260
 
 config LOPEC
        bool "Motorola-LoPEC"
+       select PPC_I8259
 
 config MVME5100
        bool "Motorola-MVME5100"
@@ -55,6 +56,7 @@ config MVME5100
 
 config PPLUS
        bool "Motorola-PowerPlus"
+       select PPC_I8259
        select PPC_INDIRECT_PCI
 
 config PRPMC750
@@ -67,12 +69,14 @@ config PRPMC800
 
 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 HARRIER_STORE_GATHERING
 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"
index 92d18003f152ee391138ef0c3ea082b6e21223bb..0fa5beae6d1bbfe33721ed36d87b78ff9beba593 100644 (file)
@@ -87,7 +87,6 @@ extern int pSeries_machine_check_exception(struct pt_regs *regs);
 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 @@ static void __init fwnmi_init(void)
                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 @@ static void __init pSeries_init_mpic(void)
                  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)
index e66fef652fac3225873a425afb5d9e6dcc578e3e..f3c9e61c39106bcda4626d2131825bf8c9eaa893 100644 (file)
@@ -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/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
new file mode 100644 (file)
index 0000000..90bce6e
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * 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 void __iomem *pci_intack; /* RO, gives us the irq vector */
+
+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);
+
+static int i8259_pic_irq_offset;
+
+/*
+ * Acknowledge the IRQ using either the PCI host bridge's interrupt
+ * acknowledge feature or poll.  How i8259_init() is called determines
+ * 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 irq;
+
+       spin_lock(&i8259_lock);
+
+       /* Either int-ack or poll for the IRQ */
+       if (pci_intack)
+               irq = readb(pci_intack);
+       else {
+               /* Perform an interrupt acknowledge cycle on controller 1. */
+               outb(0x0C, 0x20);               /* prepare for poll */
+               irq = inb(0x20) & 7;
+               if (irq == 2 ) {
+                       /*
+                        * Interrupt is cascaded so perform interrupt
+                        * acknowledge on controller 2.
+                        */
+                       outb(0x0C, 0xA0);       /* prepare for poll */
+                       irq = (inb(0xA0) & 7) + 8;
+               }
+       }
+
+       if (irq == 7) {
+               /*
+                * This may be a spurious interrupt.
+                *
+                * Read the interrupt status register (ISR). If the most
+                * significant bit is not set then there is no valid
+                * interrupt.
+                */
+               if (!pci_intack)
+                       outb(0x0B, 0x20);       /* ISR register */
+               if(~inb(0x20) & 0x80)
+                       irq = -1;
+       }
+
+       spin_unlock(&i8259_lock);
+       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)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&i8259_lock, flags);
+       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);
+       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);
+       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 (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))
+           && 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,
+};
+
+static struct resource pic1_iores = {
+       .name = "8259 (master)",
+       .start = 0x20,
+       .end = 0x21,
+       .flags = IORESOURCE_BUSY,
+};
+
+static struct resource pic2_iores = {
+       .name = "8259 (slave)",
+       .start = 0xa0,
+       .end = 0xa1,
+       .flags = IORESOURCE_BUSY,
+};
+
+static struct resource pic_edgectrl_iores = {
+       .name = "8259 edge control",
+       .start = 0x4d0,
+       .end = 0x4d1,
+       .flags = IORESOURCE_BUSY,
+};
+
+static struct irqaction i8259_irqaction = {
+       .handler = no_action,
+       .flags = SA_INTERRUPT,
+       .mask = CPU_MASK_NONE,
+       .name = "82c59 secondary cascade",
+};
+
+/*
+ * i8259_init()
+ * intack_addr - PCI interrupt acknowledge (real) address which will return
+ *               the active irq from the 8259
+ */
+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 */
+       outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */
+       outb(0x01, 0x21); /* Select 8086 mode */
+
+       /* 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 */
+
+       /* always read ISR */
+       outb(0x0B, 0x20);
+       outb(0x0B, 0xA0);
+
+       /* Mask all interrupts */
+       outb(cached_A1, 0xA1);
+       outb(cached_21, 0x21);
+
+       spin_unlock_irqrestore(&i8259_lock, flags);
+
+       /* reserve our resources */
+       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;
+}
index e3efaf47d08363ea0c71f53d9ea74b6daa6b7352..114b90fdea240cab6d7cf7eeeb1b8adea51a7823 100644 (file)
@@ -589,6 +589,7 @@ config EV64260
 
 config LOPEC
        bool "Motorola-LoPEC"
+       select PPC_I8259
 
 config MVME5100
        bool "Motorola-MVME5100"
@@ -596,6 +597,7 @@ config MVME5100
 
 config PPLUS
        bool "Motorola-PowerPlus"
+       select PPC_I8259
        select PPC_INDIRECT_PCI
 
 config PRPMC750
@@ -608,12 +610,14 @@ config PRPMC800
 
 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 CPM2
 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_PMAC64
 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 HARRIER_STORE_GATHERING
 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 @@ menu "Bus options"
 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 @@ config GENERIC_ISA_DMA
        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 MPC83xx_PCI2
 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.
index 9f9039498ae523f3c65f72ff0c53b9c6ba2908e1..eda659916f24254d9e7100f7374bc77d49d957b1 100644 (file)
@@ -173,10 +173,7 @@ mpc85xx_cds_init_IRQ(void)
 #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
index 56c53bb3dfd41da19ed1eec5023647ba31dad900..dad81ffd401318bd2edf81725336a9a18a706b99 100644 (file)
@@ -436,9 +436,7 @@ void __init chrp_init_IRQ(void)
                                       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
index 800c56a07a97a9fcbb66a515511f882589f1efbd..06d247c23b828800df83d816486dec0c757561cf 100644 (file)
@@ -267,15 +267,11 @@ lopec_init_IRQ(void)
        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
index ce2ce88c80337d0416a9e8d4576e996ed263d26f..108eb182dddcc01c68128e83c02a961e4578fcc4 100644 (file)
@@ -223,11 +223,7 @@ mvme5100_init_IRQ(void)
        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
index 59eb330b20905cbfc69a723b208a9d0854db8f3b..22bd40cfb0928f7b2d37a88f4b7299cd4ed3a803 100644 (file)
@@ -665,10 +665,7 @@ static void __init pplus_init_IRQ(void)
                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);
index 9e5637e5f5a9aab23ebd10ac19eba632c792ab9c..067d7d53b81e76fc7fe097cc56f99307770e5025 100644 (file)
@@ -954,11 +954,9 @@ prep_init_IRQ(void)
                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 @@ prep_init_IRQ(void)
        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)
index 5058568c13ec56f11a736316327a56336037a464..6f97911c330d4e5d02ff71f12ab2fd1262528b7f 100644 (file)
@@ -514,13 +514,9 @@ static void __init ppc7d_init_irq(void)
        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;
index d4c9781989fbbd4004996bb9a6a74e2307906566..9eeed35723098d842efa856d4f2da75ebbe86d5d 100644 (file)
@@ -493,19 +493,11 @@ sandpoint_init_IRQ(void)
        openpic_hookup_cascade(sandpoint_is_x2 ? 17 : NUM_8259_INTERRUPTS, "82c59 cascade",
                        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
index 5739a19b9ed9a005f20aa7bb4872fc5353d4009e..e6e6aa4d291ebca89215164418771ea5bc5d3a4d 100644 (file)
@@ -36,14 +36,12 @@ endif
 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_EV64260)         += todc_time.o pci_auto.o
 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_MV64360)               += mv64360_pic.o
 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_MPC10X_OPENPIC)  += open_pic.o
 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/ppc/syslib/i8259.c b/arch/ppc/syslib/i8259.c
deleted file mode 100644 (file)
index 5c7908c..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-#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 */
-
-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;
-
-/*
- * Acknowledge the IRQ using either the PCI host bridge's interrupt
- * acknowledge feature or poll.  How i8259_init() is called determines
- * 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 irq;
-
-       spin_lock(&i8259_lock);
-
-       /* Either int-ack or poll for the IRQ */
-       if (pci_intack)
-               irq = *pci_intack;
-       else {
-               /* Perform an interrupt acknowledge cycle on controller 1. */
-               outb(0x0C, 0x20);               /* prepare for poll */
-               irq = inb(0x20) & 7;
-               if (irq == 2 ) {
-                       /*
-                        * Interrupt is cascaded so perform interrupt
-                        * acknowledge on controller 2.
-                        */
-                       outb(0x0C, 0xA0);       /* prepare for poll */
-                       irq = (inb(0xA0) & 7) + 8;
-               }
-       }
-
-       if (irq == 7) {
-               /*
-                * This may be a spurious interrupt.
-                *
-                * Read the interrupt status register (ISR). If the most
-                * significant bit is not set then there is no valid
-                * interrupt.
-                */
-               if (!pci_intack)
-                       outb(0x0B, 0x20);       /* ISR register */
-               if(~inb(0x20) & 0x80)
-                       irq = -1;
-       }
-
-       spin_unlock(&i8259_lock);
-       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 (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))
-           && 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,
-};
-
-static struct resource pic1_iores = {
-       .name = "8259 (master)",
-       .start = 0x20,
-       .end = 0x21,
-       .flags = IORESOURCE_BUSY,
-};
-
-static struct resource pic2_iores = {
-       .name = "8259 (slave)",
-       .start = 0xa0,
-       .end = 0xa1,
-       .flags = IORESOURCE_BUSY,
-};
-
-static struct resource pic_edgectrl_iores = {
-       .name = "8259 edge control",
-       .start = 0x4d0,
-       .end = 0x4d1,
-       .flags = IORESOURCE_BUSY,
-};
-
-static struct irqaction i8259_irqaction = {
-       .handler = no_action,
-       .flags = SA_INTERRUPT,
-       .mask = CPU_MASK_NONE,
-       .name = "82c59 secondary cascade",
-};
-
-/*
- * i8259_init()
- * intack_addr - PCI interrupt acknowledge (real) address which will return
- *               the active irq from the 8259
- */
-void __init
-i8259_init(long intack_addr)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&i8259_lock, flags);
-       /* 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 */
-
-       /* 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 */
-
-       /* always read ISR */
-       outb(0x0B, 0x20);
-       outb(0x0B, 0xA0);
-
-       /* Mask all interrupts */
-       outb(cached_A1, 0xA1);
-       outb(cached_21, 0x21);
-
-       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, &pic2_iores);
-       request_resource(&ioport_resource, &pic_edgectrl_iores);
-
-       if (intack_addr != 0)
-               pci_intack = ioremap(intack_addr, 1);
-}
index 8cbac7f32092f8646a52f337e4a5ee48d211e430..963f519b7713b330d521a8472f400f0c7ee5fa84 100644 (file)
@@ -123,6 +123,11 @@ config MPIC
        bool
        default y
 
+config PPC_I8259
+       depends on PPC_PSERIES
+       bool
+       default y
+
 config BPA_IIC
        depends on PPC_BPA
        bool
index cb6ac3d1a06f134de82b8075e78032a3b07ffd69..2c541c6652b2b3300d9cd8dc2a311ce6df2b30bb 100644 (file)
@@ -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_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 (file)
index 74dcfd6..0000000
+++ /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);
index 9521ad47740f192f83f7f5b1e77b62cc2aea9632..fc4bfee124d7016689b785becfc741f5ae55e60e 100644 (file)
@@ -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 */