]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
ARM: pci: create pci_common_init_dev()
authorVidya Sagar <vidyas@nvidia.com>
Mon, 11 Aug 2014 06:12:59 +0000 (11:42 +0530)
committerLaxman Dewangan <ldewangan@nvidia.com>
Wed, 13 Aug 2014 13:53:42 +0000 (06:53 -0700)
When working with device tree support for PCI on ARM you run
into a problem when mapping IRQs from the device tree irqmaps:
doing this the code in drivers/of/of_pci_irq.c will try to
find the OF node on the root bridge and this fails, because
bus->dev.of_node is NULL, and that in turn boils down to
the fact that pci_set_bus_of_node() has called
pcibios_get_phb_of_node() from drivers/pci/of.c to obtain
the OF node of the bridge or its parent and none is set
and thus NULL is returned.
Fix this by adding an additional parent argument API for
registering PCI bridges on the ARM architecture called
pci_common_init_dev(), and pass along this parent to
pci_scan_root_bus() called from pcibios_init_hw() in
bios32.c and voila: the IRQ mappings start working:
the OF node can be retrieved from the parent.
Create the old pci_common_init() as a wrapper around
the new call.

vidyas: make similar change for ARM64
based on upstream commit 14d86e725ed034917bc721cf5deea019857b6cf0

Bug 1496843

Change-Id: Ic3bb98f059e9d42396956cf166ccc06b84b70c92
Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
Reviewed-on: http://git-master/r/454896
GVS: Gerrit_Virtual_Submit
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
arch/arm64/include/asm/mach/pci.h
arch/arm64/kernel/bios32.c

index 6e1f679c3056d6a8f5e9efb9c1f42f44f9231650..27347e9dc3787f5d65b1fed56b71201055c5c397 100644 (file)
@@ -16,6 +16,7 @@
 struct pci_sys_data;
 struct pci_ops;
 struct pci_bus;
+struct device;
 
 struct hw_pci {
 #ifdef CONFIG_PCI_DOMAINS
@@ -72,7 +73,16 @@ struct pci_sys_data {
 /*
  * Call this with your hw_pci struct to initialise the PCI system.
  */
-void pci_common_init(struct hw_pci *);
+void pci_common_init_dev(struct device *, struct hw_pci *);
+
+/*
+ * Compatibility wrapper for older platforms that do not care about
+ * passing the parent device.
+ */
+static inline void pci_common_init(struct hw_pci *hw)
+{
+       pci_common_init_dev(NULL, hw);
+}
 
 /*
  * Setup early fixed I/O mapping.
index 30377772999f91f5312a1d2cd9b3b54715ce154a..1381b8d9017cf3763595b8d853b0c9878891dae3 100644 (file)
@@ -466,7 +466,8 @@ static int __init pcibios_init_resources(int busnr, struct pci_sys_data *sys)
        return 0;
 }
 
-static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
+static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
+                           struct list_head *head)
 {
        struct pci_sys_data *sys = NULL;
        int ret;
@@ -503,7 +504,7 @@ static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
                        if (hw->scan)
                                sys->bus = hw->scan(nr, sys);
                        else
-                               sys->bus = pci_scan_root_bus(NULL, sys->busnr,
+                               sys->bus = pci_scan_root_bus(parent, sys->busnr,
                                                hw->ops, sys, &sys->resources);
 
                        if (!sys->bus)
@@ -520,7 +521,7 @@ static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
        }
 }
 
-void __init pci_common_init(struct hw_pci *hw)
+void pci_common_init_dev(struct device *parent, struct hw_pci *hw)
 {
        struct pci_sys_data *sys;
        LIST_HEAD(head);
@@ -528,7 +529,7 @@ void __init pci_common_init(struct hw_pci *hw)
        pci_add_flags(PCI_REASSIGN_ALL_RSRC);
        if (hw->preinit)
                hw->preinit();
-       pcibios_init_hw(hw, &head);
+       pcibios_init_hw(parent, hw, &head);
        if (hw->postinit)
                hw->postinit();