[PATCH 3/6] powerpc/fsl-pci: Determine primary bus by looking for ISA node

Jia Hongtao B38951 at freescale.com
Tue Jul 24 20:20:07 EST 2012


PCI host bridge is primary bus if it contains an ISA node. But not all boards
fit this rule. Device tree should be updated for all these boards.

Signed-off-by: Jia Hongtao <B38951 at freescale.com>
Signed-off-by: Li Yang <leoli at freescale.com>
---
 arch/powerpc/include/asm/pci-bridge.h |    1 +
 arch/powerpc/sysdev/fsl_pci.c         |   31 ++++++++++++++++++++++++-------
 arch/powerpc/sysdev/fsl_pci.h         |   12 +++++++++++-
 3 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index ac39e6a..b48fa7f 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -20,6 +20,7 @@ struct device_node;
 struct pci_controller {
 	struct pci_bus *bus;
 	char is_dynamic;
+	int is_primary;
 #ifdef CONFIG_PPC64
 	int node;
 #endif
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 99a3e78..2a369be 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -453,6 +453,7 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
 
 	hose->first_busno = bus_range ? bus_range[0] : 0x0;
 	hose->last_busno = bus_range ? bus_range[1] : 0xff;
+	hose->is_primary = is_primary;
 
 	setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
 		PPC_INDIRECT_TYPE_BIG_ENDIAN);
@@ -932,18 +933,34 @@ void pci_check_swiotlb(void)
 }
 #endif
 
-int primary_phb_addr;
+/*
+ * Recursively scan all the children nodes of parent and find out if there
+ * is "isa" node. Return 1 if parent has isa node otherwise return 0.
+ */
+int has_isa_node(struct device_node *parent)
+{
+	static int result;
+	struct device_node *cur_child;
+
+	cur_child = NULL;
+	result = 0;
+	while (!result && (cur_child = of_get_next_child(parent, cur_child))) {
+		/* Get "isa" node and return 1 */
+		if (of_node_cmp(cur_child->type, "isa") == 0)
+			return result = 1;
+		has_isa_node(cur_child);
+	}
+
+	return result;
+}
+
 static int __devinit fsl_pci_probe(struct platform_device *pdev)
 {
-	struct pci_controller *hose;
 	bool is_primary;
+	is_primary = has_isa_node(pdev->dev.of_node);
 
-	if (of_match_node(pci_ids, pdev->dev.of_node)) {
-		struct resource rsrc;
-		of_address_to_resource(pdev->dev.of_node, 0, &rsrc);
-		is_primary = ((rsrc.start & 0xfffff) == primary_phb_addr);
+	if (of_match_node(pci_ids, pdev->dev.of_node))
 		fsl_add_bridge(pdev->dev.of_node, is_primary);
-	}
 
 	return 0;
 }
diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h
index c2c1de5..abbc09d 100644
--- a/arch/powerpc/sysdev/fsl_pci.h
+++ b/arch/powerpc/sysdev/fsl_pci.h
@@ -88,7 +88,17 @@ struct ccsr_pci {
 	__be32	pex_err_cap_r3;		/* 0x.e34 - PCIE error capture register 0 */
 };
 
-extern int primary_phb_addr;
+
+#ifdef CONFIG_SUSPEND
+struct fsl_pci_private_data {
+	int inbound_num;
+	struct pci_outbound_window_regs __iomem *pci_pow;
+	struct pci_inbound_window_regs __iomem *pci_piw;
+	void *saved_regs;
+};
+#endif
+
+extern int is_has_isa_node(struct device_node *parent);
 extern int fsl_add_bridge(struct device_node *dev, int is_primary);
 extern void fsl_pcibios_fixup_bus(struct pci_bus *bus);
 extern int mpc83xx_add_bridge(struct device_node *dev);
-- 
1.7.5.1




More information about the Linuxppc-dev mailing list