From e25203eb2feeb8a123a20b8127ba9673e06c65b2 Mon Sep 17 00:00:00 2001 From: juhosg Date: Tue, 30 Apr 2013 10:44:07 +0000 Subject: linux/3.8: use backported pcibios_get_phb_of_node patches Signed-off-by: Gabor Juhos git-svn-id: svn://svn.openwrt.org/openwrt/trunk@36494 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- ...__weak-annotation-from-pcibios_get_phb_of.patch | 40 ++++++ ...ve-weak-annotation-of-pcibios_get_phb_of_.patch | 150 --------------------- ...IPS-PCI-Implement-pcibios_get_phb_of_node.patch | 48 +++++++ ...32-MIPS-implement-pcibios_get_phb_of_node.patch | 47 ------- 4 files changed, 88 insertions(+), 197 deletions(-) create mode 100644 target/linux/generic/patches-3.8/031-PCI-Remove-__weak-annotation-from-pcibios_get_phb_of.patch delete mode 100644 target/linux/generic/patches-3.8/031-pci-of-remove-weak-annotation-of-pcibios_get_phb_of_.patch create mode 100644 target/linux/generic/patches-3.8/032-MIPS-PCI-Implement-pcibios_get_phb_of_node.patch delete mode 100644 target/linux/generic/patches-3.8/032-MIPS-implement-pcibios_get_phb_of_node.patch diff --git a/target/linux/generic/patches-3.8/031-PCI-Remove-__weak-annotation-from-pcibios_get_phb_of.patch b/target/linux/generic/patches-3.8/031-PCI-Remove-__weak-annotation-from-pcibios_get_phb_of.patch new file mode 100644 index 000000000..ed9777683 --- /dev/null +++ b/target/linux/generic/patches-3.8/031-PCI-Remove-__weak-annotation-from-pcibios_get_phb_of.patch @@ -0,0 +1,40 @@ +From 10629d711ed780470937ecda50d9ffa0e925a4ee Mon Sep 17 00:00:00 2001 +From: Bjorn Helgaas +Date: Wed, 10 Apr 2013 09:56:54 -0600 +Subject: [PATCH 1/2] PCI: Remove __weak annotation from + pcibios_get_phb_of_node decl + +The __weak annotation on the pcibios_get_phb_of_node() declaration +causes *every* definition to be marked "weak." The linker then +selects one based on link order, which may be the wrong one. + +Gabor found that on MIPS, the linker selected the generic implementation +from drivers/pci even though arch/mips supplied a definition without the +__weak annotation: + +$ mipsel-openwrt-linux-readelf -s arch/mips/pci/built-in.o \ + drivers/pci/built-in.o vmlinux.o | grep pcibios_get_phb_of_node + 86: 0000046c 12 FUNC WEAK DEFAULT 2 pcibios_get_phb_of_node + 1430: 00012e2c 104 FUNC WEAK DEFAULT 2 pcibios_get_phb_of_node + 31898: 0017e4ec 104 FUNC WEAK DEFAULT 2 pcibios_get_phb_of_node + +This removes the __weak annotation from the pcibios_get_phb_of_node() +declaration so arch-specific non-weak implementations work reliably. + +Suggested-by: Gabor Juhos +Signed-off-by: Bjorn Helgaas +--- + include/linux/pci.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/linux/pci.h ++++ b/include/linux/pci.h +@@ -1803,7 +1803,7 @@ extern void pci_set_bus_of_node(struct p + extern void pci_release_bus_of_node(struct pci_bus *bus); + + /* Arch may override this (weak) */ +-extern struct device_node * __weak pcibios_get_phb_of_node(struct pci_bus *bus); ++extern struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus); + + static inline struct device_node * + pci_device_to_OF_node(const struct pci_dev *pdev) diff --git a/target/linux/generic/patches-3.8/031-pci-of-remove-weak-annotation-of-pcibios_get_phb_of_.patch b/target/linux/generic/patches-3.8/031-pci-of-remove-weak-annotation-of-pcibios_get_phb_of_.patch deleted file mode 100644 index a439d1db8..000000000 --- a/target/linux/generic/patches-3.8/031-pci-of-remove-weak-annotation-of-pcibios_get_phb_of_.patch +++ /dev/null @@ -1,150 +0,0 @@ -From 61cb343b4ac20d2d957811cd492fec770646dda8 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Wed, 3 Apr 2013 19:47:50 +0200 -Subject: [PATCH 1/2] pci/of: remove weak annotation of - pcibios_get_phb_of_node - -Due to the __weak annotation in the forward declaration -of the 'pcibios_get_phb_of_node' function GCC will emit -a weak symbol for this functions even if the actual -implementation does not use the weak attribute. - -If an architecture tries to override the function -by providing its own implementation there will be -multiple weak symbols with the same name in the -object files. When the kernel is linked from the -object files the linking order determines which -implementation will be used in the final image. - -On x86 and on powerpc the architecture specific -version gets used: - - $ readelf -s arch/x86/kernel/built-in.o drivers/pci/built-in.o \ - vmlinux.o | grep pcibios_get_phb_of_node - 3338: 00029b80 86 FUNC WEAK DEFAULT 1 pcibios_get_phb_of_node - 1701: 00012710 77 FUNC WEAK DEFAULT 1 pcibios_get_phb_of_node - 52072: 0002a170 86 FUNC WEAK DEFAULT 1 pcibios_get_phb_of_node - $ - - $ powerpc-openwrt-linux-uclibc-readelf -s arch/powerpc/kernel/built-in.o \ - drivers/pci/built-in.o vmlinux.o | grep pcibios_get_phb_of_node - 1001: 0000cbb8 12 FUNC WEAK DEFAULT 1 pcibios_get_phb_of_node - 1484: 0001471c 88 FUNC WEAK DEFAULT 1 pcibios_get_phb_of_node - 28652: 0000d6f8 12 FUNC WEAK DEFAULT 1 pcibios_get_phb_of_node - $ - -However on MIPS, the linker puts the default -implementation into the final image: - - $ mipsel-openwrt-linux-readelf -s arch/mips/pci/built-in.o \ - drivers/pci/built-in.o vmlinux.o | grep pcibios_get_phb_of_node - 86: 0000046c 12 FUNC WEAK DEFAULT 2 pcibios_get_phb_of_node - 1430: 00012e2c 104 FUNC WEAK DEFAULT 2 pcibios_get_phb_of_node - 31898: 0017e4ec 104 FUNC WEAK DEFAULT 2 pcibios_get_phb_of_node - $ - -Rename the default implementation and remove the -__weak annotation of that. This ensures that there -will be no multiple weak symbols with the same name -in the object files. In order to keep the expected -behaviour, call the architecture specific function -if the weak symbol is resolved. - -Also move the renamed function to the top instead -of adding a new forward declaration for that. - -Signed-off-by: Gabor Juhos ---- -Notes: - -Unfortunately I'm not a binutils/gcc expert, so -I don't know if this is the expected behaviour -of those or not. - -Removing the __weak annotation from the forward -declaration of 'pcibios_get_phb_of_node' in -'include/linux/pci.h' also fixes the problem. - -The microblaze architecture also provides its own -implementation. The behaviour of that is not tested -but I assume that the linker chooses the arch specific -implementation on that as well similarly to the -x86/powerpc. - -The MIPS version is implemented in the followup -patch. - -Removing the __weak annotation from the forward -declaration of 'pcibios_get_phb_of_node' in -'include/linux/pci.h' also fixes the problem. - --Gabor ---- - drivers/pci/of.c | 41 +++++++++++++++++++++++------------------ - 1 file changed, 23 insertions(+), 18 deletions(-) - ---- a/drivers/pci/of.c -+++ b/drivers/pci/of.c -@@ -15,10 +15,32 @@ - #include - #include "pci.h" - -+static struct device_node *__pcibios_get_phb_of_node(struct pci_bus *bus) -+{ -+ /* This should only be called for PHBs */ -+ if (WARN_ON(bus->self || bus->parent)) -+ return NULL; -+ -+ if (pcibios_get_phb_of_node) -+ return pcibios_get_phb_of_node(bus); -+ -+ /* Look for a node pointer in either the intermediary device we -+ * create above the root bus or it's own parent. Normally only -+ * the later is populated. -+ */ -+ if (bus->bridge->of_node) -+ return of_node_get(bus->bridge->of_node); -+ if (bus->bridge->parent && bus->bridge->parent->of_node) -+ return of_node_get(bus->bridge->parent->of_node); -+ -+ return NULL; -+} -+ - void pci_set_of_node(struct pci_dev *dev) - { - if (!dev->bus->dev.of_node) - return; -+ - dev->dev.of_node = of_pci_find_child_device(dev->bus->dev.of_node, - dev->devfn); - } -@@ -32,7 +54,7 @@ void pci_release_of_node(struct pci_dev - void pci_set_bus_of_node(struct pci_bus *bus) - { - if (bus->self == NULL) -- bus->dev.of_node = pcibios_get_phb_of_node(bus); -+ bus->dev.of_node = __pcibios_get_phb_of_node(bus); - else - bus->dev.of_node = of_node_get(bus->self->dev.of_node); - } -@@ -42,20 +64,3 @@ void pci_release_bus_of_node(struct pci_ - of_node_put(bus->dev.of_node); - bus->dev.of_node = NULL; - } -- --struct device_node * __weak pcibios_get_phb_of_node(struct pci_bus *bus) --{ -- /* This should only be called for PHBs */ -- if (WARN_ON(bus->self || bus->parent)) -- return NULL; -- -- /* Look for a node pointer in either the intermediary device we -- * create above the root bus or it's own parent. Normally only -- * the later is populated. -- */ -- if (bus->bridge->of_node) -- return of_node_get(bus->bridge->of_node); -- if (bus->bridge->parent && bus->bridge->parent->of_node) -- return of_node_get(bus->bridge->parent->of_node); -- return NULL; --} diff --git a/target/linux/generic/patches-3.8/032-MIPS-PCI-Implement-pcibios_get_phb_of_node.patch b/target/linux/generic/patches-3.8/032-MIPS-PCI-Implement-pcibios_get_phb_of_node.patch new file mode 100644 index 000000000..cd43c27f4 --- /dev/null +++ b/target/linux/generic/patches-3.8/032-MIPS-PCI-Implement-pcibios_get_phb_of_node.patch @@ -0,0 +1,48 @@ +From 9a97cd43f4ef62520a852b5a2348233b0f37455b Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Thu, 4 Apr 2013 20:01:23 +0200 +Subject: [PATCH 2/2] MIPS/PCI: Implement pcibios_get_phb_of_node + +The of_node field of the device assigned to a +PCI bus is used during scanning of the PCI bus. +However on MIPS, the of_node field is assigned +only after the bus has been scanned. + +Implement the architecture specific version of +'pcibios_get_phb_of_node'. Which ensures that the +PCI driver core will initialize the of_node field +before starting the scan. + +Also remove the local assignment of bus->dev.of_node, +it is not needed after the patch. + +Signed-off-by: Gabor Juhos +Signed-off-by: Bjorn Helgaas +--- + arch/mips/pci/pci.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/arch/mips/pci/pci.c ++++ b/arch/mips/pci/pci.c +@@ -115,7 +115,6 @@ static void pcibios_scanbus(struct pci_c + pci_bus_assign_resources(bus); + pci_enable_bridges(bus); + } +- bus->dev.of_node = hose->of_node; + } + } + +@@ -169,6 +168,13 @@ void pci_load_of_ranges(struct pci_contr + } + } + } ++ ++struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus) ++{ ++ struct pci_controller *hose = bus->sysdata; ++ ++ return of_node_get(hose->of_node); ++} + #endif + + static DEFINE_MUTEX(pci_scan_mutex); diff --git a/target/linux/generic/patches-3.8/032-MIPS-implement-pcibios_get_phb_of_node.patch b/target/linux/generic/patches-3.8/032-MIPS-implement-pcibios_get_phb_of_node.patch deleted file mode 100644 index 772816558..000000000 --- a/target/linux/generic/patches-3.8/032-MIPS-implement-pcibios_get_phb_of_node.patch +++ /dev/null @@ -1,47 +0,0 @@ -From fe17cba0e4efb6cf6d1e4e79fa4c6e062fe32b39 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Wed, 3 Apr 2013 19:28:50 +0200 -Subject: [PATCH 2/2] MIPS: implement pcibios_get_phb_of_node - -The of_node field of the device assigned to a -PCI bus is used during scanning of the PCI bus. -However on MIPS, the of_node field is assigned -only after the bus has been scanned. - -Implement the architecture specific version of -'pcibios_get_phb_of_node'. Which ensures that the -PCI driver core will initialize the of_node field -before starting the scan. - -Also remove the local assignment of bus->dev.of_node, -it is not needed after the patch. - -Signed-off-by: Gabor Juhos ---- - arch/mips/pci/pci.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - ---- a/arch/mips/pci/pci.c -+++ b/arch/mips/pci/pci.c -@@ -115,7 +115,6 @@ static void pcibios_scanbus(struct pci_c - pci_bus_assign_resources(bus); - pci_enable_bridges(bus); - } -- bus->dev.of_node = hose->of_node; - } - } - -@@ -169,6 +168,13 @@ void pci_load_of_ranges(struct pci_contr - } - } - } -+ -+struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus) -+{ -+ struct pci_controller *hose = bus->sysdata; -+ -+ return of_node_get(hose->of_node); -+} - #endif - - static DEFINE_MUTEX(pci_scan_mutex); -- cgit v1.2.3