[POWERPC] Pass the pci_controller into pci_exclude_device
authorKumar Gala <galak@kernel.crashing.org>
Fri, 22 Jun 2007 05:23:57 +0000 (00:23 -0500)
committerKumar Gala <galak@kernel.crashing.org>
Fri, 29 Jun 2007 06:57:22 +0000 (01:57 -0500)
There are times that we need to know which controller we are on to decide
how to exclude devices properly.  We now pass the pci_controller that we
are going to use down to the pci_exclude_device function. This will
greatly simplify being able to exclude the PHBs in multiple controller
setups.

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
17 files changed:
arch/powerpc/platforms/52xx/mpc52xx_pci.c
arch/powerpc/platforms/82xx/mpc82xx_ads.c
arch/powerpc/platforms/83xx/mpc83xx.h
arch/powerpc/platforms/83xx/pci.c
arch/powerpc/platforms/85xx/mpc85xx_ads.c
arch/powerpc/platforms/85xx/mpc85xx_cds.c
arch/powerpc/platforms/86xx/mpc86xx.h
arch/powerpc/platforms/86xx/pci.c
arch/powerpc/platforms/embedded6xx/holly.c
arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
arch/powerpc/sysdev/Makefile
arch/powerpc/sysdev/fsl_pcie.c
arch/powerpc/sysdev/indirect_pci.c
arch/powerpc/sysdev/tsi108_pci.c
arch/ppc/syslib/Makefile
arch/ppc/syslib/indirect_pci.c [new file with mode: 0644]
include/asm-powerpc/machdep.h

index 57ca2feb0799492458292e5e0c9660e40198627c..69a04217c79dc66038b83088046e645d384202c2 100644 (file)
@@ -112,7 +112,7 @@ mpc52xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
        u32 value;
 
        if (ppc_md.pci_exclude_device)
-               if (ppc_md.pci_exclude_device(bus->number, devfn))
+               if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
                        return PCIBIOS_DEVICE_NOT_FOUND;
 
        out_be32(hose->cfg_addr,
@@ -169,7 +169,7 @@ mpc52xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
        u32 value, mask;
 
        if (ppc_md.pci_exclude_device)
-               if (ppc_md.pci_exclude_device(bus->number, devfn))
+               if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
                        return PCIBIOS_DEVICE_NOT_FOUND;
 
        out_be32(hose->cfg_addr,
index 04bf57079c1e1b2604bd7825d9fb83f949aef60e..715107b6d784f710115f34b611e130619c26b8a0 100644 (file)
@@ -507,7 +507,8 @@ void m82xx_pci_init_irq(void)
        return;
 }
 
-static int m82xx_pci_exclude_device(u_char bus, u_char devfn)
+static int m82xx_pci_exclude_device(struct pci_controller *hose,
+                                   u_char bus, u_char devfn)
 {
        if (bus == 0 && PCI_SLOT(devfn) == 0)
                return PCIBIOS_DEVICE_NOT_FOUND;
index 9bd85f5e9a56e2d96bd728c1d011c7ae26aac5b3..f5c5034a8461a5aeff41f6782a5df1f1439e9200 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <linux/init.h>
 #include <linux/device.h>
+#include <asm/pci-bridge.h>
 
 /* System Clock Control Register */
 #define MPC83XX_SCCR_OFFS          0xA08
@@ -28,7 +29,8 @@
  */
 
 extern int mpc83xx_add_bridge(struct device_node *dev);
-extern int mpc83xx_exclude_device(u_char bus, u_char devfn);
+extern int mpc83xx_exclude_device(struct pci_controller *hose,
+                                 u_char bus, u_char devfn);
 extern void mpc83xx_restart(char *cmd);
 extern long mpc83xx_time_init(void);
 
index 34716024ed1a0e199235379b025b503439376c93..f92e71f2ed6b87231e6bf39d3e24c2dbb116cca0 100644 (file)
@@ -35,7 +35,7 @@
 
 int mpc83xx_pci2_busno;
 
-int mpc83xx_exclude_device(u_char bus, u_char devfn)
+int mpc83xx_exclude_device(struct pci_controller *hose, u_char bus, u_char devfn)
 {
        if (bus == 0 && PCI_SLOT(devfn) == 0)
                return PCIBIOS_DEVICE_NOT_FOUND;
index 4100e17f4cb278bd13110ee662ace7bee4b49eaf..1262d1b8a4427fa6b5e6985007ba93b172d64ad3 100644 (file)
@@ -39,7 +39,8 @@
 #endif
 
 #ifdef CONFIG_PCI
-static int mpc85xx_exclude_device(u_char bus, u_char devfn)
+static int mpc85xx_exclude_device(struct pci_controller *hose,
+                                  u_char bus, u_char devfn)
 {
        if (bus == 0 && PCI_SLOT(devfn) == 0)
                return PCIBIOS_DEVICE_NOT_FOUND;
index fa6b6be6cadad87fc66b0f35763d78fa1fc953f5..fcea5ab5eb77db647266e22476b69edb77ff133c 100644 (file)
@@ -57,7 +57,8 @@ static volatile u8 *cadmus;
 
 extern int mpc85xx_pci2_busno;
 
-static int mpc85xx_exclude_device(u_char bus, u_char devfn)
+static int mpc85xx_exclude_device(struct pci_controller *hose,
+                                 u_char bus, u_char devfn)
 {
        if (bus == 0 && PCI_SLOT(devfn) == 0)
                return PCIBIOS_DEVICE_NOT_FOUND;
index dc2f6fdc8de4a0135a9bb5b3ceac8827e010c8a2..4c2789de045e22c5423e842e63d54f348c905a4a 100644 (file)
@@ -17,7 +17,8 @@
 
 extern int mpc86xx_add_bridge(struct device_node *dev);
 
-extern int mpc86xx_exclude_device(u_char bus, u_char devfn);
+extern int mpc86xx_exclude_device(struct pci_controller *hose,
+                                 u_char bus, u_char devfn);
 
 extern void setup_indirect_pcie(struct pci_controller *hose,
                                       u32 cfg_addr, u32 cfg_data);
index 1e47c145d54dbd35e5c78b68516b09345c461bdd..7659259cc974a075edce31a5a1cb6c0824154c9c 100644 (file)
@@ -140,7 +140,7 @@ mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size)
        early_write_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, temps);
 }
 
-int mpc86xx_exclude_device(u_char bus, u_char devfn)
+int mpc86xx_exclude_device(struct pci_controller *hose, u_char bus, u_char devfn)
 {
        if (bus == 0 && PCI_SLOT(devfn) == 0)
                return PCIBIOS_DEVICE_NOT_FOUND;
index 3a0b4a01401c2e67db40e180470478b0884a6b8d..6292e36dc57744605b6bd2e762a03ba0bab3344b 100644 (file)
@@ -45,7 +45,7 @@
 
 #define HOLLY_PCI_CFG_PHYS 0x7c000000
 
-int holly_exclude_device(u_char bus, u_char devfn)
+int holly_exclude_device(struct pci_controller *hose, u_char bus, u_char devfn)
 {
        if (bus == 0 && PCI_SLOT(devfn) == 0)
                return PCIBIOS_DEVICE_NOT_FOUND;
index 69eab173ae09ee4c30005abc3db70e52ad41ca20..1e3cc69487b58719665cc459ed582d6b60d39275 100644 (file)
@@ -56,7 +56,8 @@
 
 extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
 
-int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn)
+int mpc7448_hpc2_exclude_device(struct pci_controller *hose,
+                               u_char bus, u_char devfn)
 {
        if (bus == 0 && PCI_SLOT(devfn) == 0)
                return PCIBIOS_DEVICE_NOT_FOUND;
index 31da3b3dc993141fe2d8249f9c7d39eac2a3d4eb..337b56a732474450f5a6635a8429c8473bb471d8 100644 (file)
@@ -5,7 +5,6 @@ endif
 mpic-msi-obj-$(CONFIG_PCI_MSI) += mpic_msi.o mpic_u3msi.o
 obj-$(CONFIG_MPIC)             += mpic.o $(mpic-msi-obj-y)
 
-obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o
 obj-$(CONFIG_PPC_MPC106)       += grackle.o
 obj-$(CONFIG_PPC_DCR)          += dcr.o
 obj-$(CONFIG_PPC_DCR_NATIVE)   += dcr-low.o
@@ -25,6 +24,7 @@ obj-$(CONFIG_PM)              += timer.o
 endif
 
 ifeq ($(CONFIG_PPC_MERGE),y)
+obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o
 obj-$(CONFIG_PPC_I8259)                += i8259.o
 obj-$(CONFIG_PPC_83xx)         += ipic.o
 obj-$(CONFIG_4xx)              += uic.o
index 041c07e8b665aad108b8d5b76ff891157c4a875b..6bbd7f84b4e2df2309747f4667a79dbf0f721c95 100644 (file)
@@ -39,7 +39,7 @@ indirect_read_config_pcie(struct pci_bus *bus, unsigned int devfn, int offset,
        u32 temp;
 
        if (ppc_md.pci_exclude_device)
-               if (ppc_md.pci_exclude_device(bus->number, devfn))
+               if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
                        return PCIBIOS_DEVICE_NOT_FOUND;
 
        /* Possible artifact of CDCpp50937 needs further investigation */
@@ -90,7 +90,7 @@ indirect_write_config_pcie(struct pci_bus *bus, unsigned int devfn, int offset,
        u32 temp;
 
        if (ppc_md.pci_exclude_device)
-               if (ppc_md.pci_exclude_device(bus->number, devfn))
+               if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
                        return PCIBIOS_DEVICE_NOT_FOUND;
 
        /* Possible artifact of CDCpp50937 needs further investigation */
index e71488469704bbea18077cbf903871b72d34afeb..3dedf8f5bfb41dde9ea2d8d417184e7543dc47c8 100644 (file)
@@ -35,14 +35,14 @@ indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
        u8 cfg_type = 0;
 
        if (ppc_md.pci_exclude_device)
-               if (ppc_md.pci_exclude_device(bus->number, devfn))
+               if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
                        return PCIBIOS_DEVICE_NOT_FOUND;
        
        if (hose->set_cfg_type)
                if (bus->number != hose->first_busno)
                        cfg_type = 1;
 
-       PCI_CFG_OUT(hose->cfg_addr,                                      
+       PCI_CFG_OUT(hose->cfg_addr,
                 (0x80000000 | ((bus->number - hose->bus_offset) << 16)
                  | (devfn << 8) | ((offset & 0xfc) | cfg_type)));
 
@@ -74,14 +74,14 @@ indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
        u8 cfg_type = 0;
 
        if (ppc_md.pci_exclude_device)
-               if (ppc_md.pci_exclude_device(bus->number, devfn))
+               if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
                        return PCIBIOS_DEVICE_NOT_FOUND;
 
        if (hose->set_cfg_type)
                if (bus->number != hose->first_busno)
                        cfg_type = 1;
 
-       PCI_CFG_OUT(hose->cfg_addr,                                      
+       PCI_CFG_OUT(hose->cfg_addr,
                 (0x80000000 | ((bus->number - hose->bus_offset) << 16)
                  | (devfn << 8) | ((offset & 0xfc) | cfg_type)));
 
index 33177b60c7ed84bd838c6adf6cfe0026453c2986..298e2dd34e8957715b92f62f61632e9c765de9a0 100644 (file)
@@ -64,9 +64,10 @@ tsi108_direct_write_config(struct pci_bus *bus, unsigned int devfunc,
                           int offset, int len, u32 val)
 {
        volatile unsigned char *cfg_addr;
+       struct pci_controller *hose = bus->sysdata;
 
        if (ppc_md.pci_exclude_device)
-               if (ppc_md.pci_exclude_device(bus->number, devfunc))
+               if (ppc_md.pci_exclude_device(hose, bus->number, devfunc))
                        return PCIBIOS_DEVICE_NOT_FOUND;
 
        cfg_addr = (unsigned char *)(tsi_mk_config_addr(bus->number,
@@ -149,10 +150,11 @@ tsi108_direct_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
                          int len, u32 * val)
 {
        volatile unsigned char *cfg_addr;
+       struct pci_controller *hose = bus->sysdata;
        u32 temp;
 
        if (ppc_md.pci_exclude_device)
-               if (ppc_md.pci_exclude_device(bus->number, devfn))
+               if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
                        return PCIBIOS_DEVICE_NOT_FOUND;
 
        cfg_addr = (unsigned char *)(tsi_mk_config_addr(bus->number,
index 95694159b22602310fa088e39c8bb4d628792674..543795be58c8a769ef0b447f4e13a98da27cd394 100644 (file)
@@ -7,6 +7,7 @@ CFLAGS_btext.o          += -fPIC
 
 wdt-mpc8xx-$(CONFIG_8xx_WDT)   += m8xx_wdt.o
 
+obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o
 obj-$(CONFIG_PPCBUG_NVRAM)     += prep_nvram.o
 obj-$(CONFIG_PPC_OCP)          += ocp.o
 obj-$(CONFIG_IBM_OCP)          += ibm_ocp.o
diff --git a/arch/ppc/syslib/indirect_pci.c b/arch/ppc/syslib/indirect_pci.c
new file mode 100644 (file)
index 0000000..83b323a
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Support for indirect PCI bridges.
+ *
+ * Copyright (C) 1998 Gabriel Paubert.
+ *
+ * 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/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/machdep.h>
+
+#ifdef CONFIG_PPC_INDIRECT_PCI_BE
+#define PCI_CFG_OUT out_be32
+#else
+#define PCI_CFG_OUT out_le32
+#endif
+
+static int
+indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
+                    int len, u32 *val)
+{
+       struct pci_controller *hose = bus->sysdata;
+       volatile void __iomem *cfg_data;
+       u8 cfg_type = 0;
+
+       if (ppc_md.pci_exclude_device)
+               if (ppc_md.pci_exclude_device(bus->number, devfn))
+                       return PCIBIOS_DEVICE_NOT_FOUND;
+
+       if (hose->set_cfg_type)
+               if (bus->number != hose->first_busno)
+                       cfg_type = 1;
+
+       PCI_CFG_OUT(hose->cfg_addr,
+                (0x80000000 | ((bus->number - hose->bus_offset) << 16)
+                 | (devfn << 8) | ((offset & 0xfc) | cfg_type)));
+
+       /*
+        * Note: the caller has already checked that offset is
+        * suitably aligned and that len is 1, 2 or 4.
+        */
+       cfg_data = hose->cfg_data + (offset & 3);
+       switch (len) {
+       case 1:
+               *val = in_8(cfg_data);
+               break;
+       case 2:
+               *val = in_le16(cfg_data);
+               break;
+       default:
+               *val = in_le32(cfg_data);
+               break;
+       }
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
+                     int len, u32 val)
+{
+       struct pci_controller *hose = bus->sysdata;
+       volatile void __iomem *cfg_data;
+       u8 cfg_type = 0;
+
+       if (ppc_md.pci_exclude_device)
+               if (ppc_md.pci_exclude_device(bus->number, devfn))
+                       return PCIBIOS_DEVICE_NOT_FOUND;
+
+       if (hose->set_cfg_type)
+               if (bus->number != hose->first_busno)
+                       cfg_type = 1;
+
+       PCI_CFG_OUT(hose->cfg_addr,
+                (0x80000000 | ((bus->number - hose->bus_offset) << 16)
+                 | (devfn << 8) | ((offset & 0xfc) | cfg_type)));
+
+       /*
+        * Note: the caller has already checked that offset is
+        * suitably aligned and that len is 1, 2 or 4.
+        */
+       cfg_data = hose->cfg_data + (offset & 3);
+       switch (len) {
+       case 1:
+               out_8(cfg_data, val);
+               break;
+       case 2:
+               out_le16(cfg_data, val);
+               break;
+       default:
+               out_le32(cfg_data, val);
+               break;
+       }
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops indirect_pci_ops =
+{
+       indirect_read_config,
+       indirect_write_config
+};
+
+void __init
+setup_indirect_pci_nomap(struct pci_controller* hose, void __iomem * cfg_addr,
+       void __iomem * cfg_data)
+{
+       hose->cfg_addr = cfg_addr;
+       hose->cfg_data = cfg_data;
+       hose->ops = &indirect_pci_ops;
+}
+
+void __init
+setup_indirect_pci(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data)
+{
+       unsigned long base = cfg_addr & PAGE_MASK;
+       void __iomem *mbase, *addr, *data;
+
+       mbase = ioremap(base, PAGE_SIZE);
+       addr = mbase + (cfg_addr & ~PAGE_MASK);
+       if ((cfg_data & PAGE_MASK) != base)
+               mbase = ioremap(cfg_data & PAGE_MASK, PAGE_SIZE);
+       data = mbase + (cfg_data & ~PAGE_MASK);
+       setup_indirect_pci_nomap(hose, addr, data);
+}
index 6cf1a831f550835692c2d06f63e10b540524adba..71c6e7eb2a266798d56e3c6676d528fa1fa8be3f 100644 (file)
@@ -218,7 +218,7 @@ struct machdep_calls {
        int  (*pcibios_enable_device_hook)(struct pci_dev *, int initial);
 
        /* Called in indirect_* to avoid touching devices */
-       int (*pci_exclude_device)(unsigned char, unsigned char);
+       int (*pci_exclude_device)(struct pci_controller *, unsigned char, unsigned char);
 
        /* Called at then very end of pcibios_init() */
        void (*pcibios_after_init)(void);