aboutsummaryrefslogtreecommitdiff
path: root/arch/powerpc/sysdev/fsl_pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/sysdev/fsl_pci.c')
-rw-r--r--arch/powerpc/sysdev/fsl_pci.c58
1 files changed, 37 insertions, 21 deletions
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 61e6d77efa4..5b264eb4b1f 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -1,7 +1,7 @@
/*
- * MPC85xx/86xx PCI/PCIE support routing.
+ * MPC83xx/85xx/86xx PCI/PCIE support routing.
*
- * Copyright 2007 Freescale Semiconductor, Inc
+ * Copyright 2007,2008 Freescale Semiconductor, Inc
*
* Initial author: Xianghua Xiao <x.xiao@freescale.com>
* Recode: ZHANG WEI <wei.zhang@freescale.com>
@@ -251,20 +251,47 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641D, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8610, quirk_fsl_pcie_header);
#endif /* CONFIG_PPC_85xx || CONFIG_PPC_86xx */
-#if defined(CONFIG_PPC_83xx)
+#if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x)
int __init mpc83xx_add_bridge(struct device_node *dev)
{
int len;
struct pci_controller *hose;
- struct resource rsrc;
+ struct resource rsrc_reg;
+ struct resource rsrc_cfg;
const int *bus_range;
- int primary = 1, has_address = 0;
- phys_addr_t immr = get_immrbase();
+ int primary;
pr_debug("Adding PCI host bridge %s\n", dev->full_name);
/* Fetch host bridge registers address */
- has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
+ if (of_address_to_resource(dev, 0, &rsrc_reg)) {
+ printk(KERN_WARNING "Can't get pci register base!\n");
+ return -ENOMEM;
+ }
+
+ memset(&rsrc_cfg, 0, sizeof(rsrc_cfg));
+
+ if (of_address_to_resource(dev, 1, &rsrc_cfg)) {
+ printk(KERN_WARNING
+ "No pci config register base in dev tree, "
+ "using default\n");
+ /*
+ * MPC83xx supports up to two host controllers
+ * one at 0x8500 has config space registers at 0x8300
+ * one at 0x8600 has config space registers at 0x8380
+ */
+ if ((rsrc_reg.start & 0xfffff) == 0x8500)
+ rsrc_cfg.start = (rsrc_reg.start & 0xfff00000) + 0x8300;
+ else if ((rsrc_reg.start & 0xfffff) == 0x8600)
+ rsrc_cfg.start = (rsrc_reg.start & 0xfff00000) + 0x8380;
+ }
+ /*
+ * Controller at offset 0x8500 is primary
+ */
+ if ((rsrc_reg.start & 0xfffff) == 0x8500)
+ primary = 1;
+ else
+ primary = 0;
/* Get bus range if any */
bus_range = of_get_property(dev, "bus-range", &len);
@@ -281,22 +308,11 @@ int __init mpc83xx_add_bridge(struct device_node *dev)
hose->first_busno = bus_range ? bus_range[0] : 0;
hose->last_busno = bus_range ? bus_range[1] : 0xff;
- /* MPC83xx supports up to two host controllers one at 0x8500 from immrbar
- * the other at 0x8600, we consider the 0x8500 the primary controller
- */
- /* PCI 1 */
- if ((rsrc.start & 0xfffff) == 0x8500) {
- setup_indirect_pci(hose, immr + 0x8300, immr + 0x8304, 0);
- }
- /* PCI 2 */
- if ((rsrc.start & 0xfffff) == 0x8600) {
- setup_indirect_pci(hose, immr + 0x8380, immr + 0x8384, 0);
- primary = 0;
- }
+ setup_indirect_pci(hose, rsrc_cfg.start, rsrc_cfg.start + 4, 0);
- printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%016llx. "
+ printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. "
"Firmware bus number: %d->%d\n",
- (unsigned long long)rsrc.start, hose->first_busno,
+ (unsigned long long)rsrc_reg.start, hose->first_busno,
hose->last_busno);
pr_debug(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",