diff options
-rw-r--r-- | target/linux/generic/patches-3.8/031-PCI-Remove-__weak-annotation-from-pcibios_get_phb_of.patch | 40 | ||||
-rw-r--r-- | target/linux/generic/patches-3.8/031-pci-of-remove-weak-annotation-of-pcibios_get_phb_of_.patch | 150 | ||||
-rw-r--r-- | target/linux/generic/patches-3.8/032-MIPS-PCI-Implement-pcibios_get_phb_of_node.patch (renamed from target/linux/generic/patches-3.8/032-MIPS-implement-pcibios_get_phb_of_node.patch) | 7 |
3 files changed, 44 insertions, 153 deletions
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 <bhelgaas@google.com> +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 <juhosg@openwrt.org> +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> +--- + 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 <juhosg@openwrt.org> -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 <juhosg@openwrt.org> ---- -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 <linux/of_pci.h> - #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-implement-pcibios_get_phb_of_node.patch b/target/linux/generic/patches-3.8/032-MIPS-PCI-Implement-pcibios_get_phb_of_node.patch index 772816558..cd43c27f4 100644 --- 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-PCI-Implement-pcibios_get_phb_of_node.patch @@ -1,7 +1,7 @@ -From fe17cba0e4efb6cf6d1e4e79fa4c6e062fe32b39 Mon Sep 17 00:00:00 2001 +From 9a97cd43f4ef62520a852b5a2348233b0f37455b Mon Sep 17 00:00:00 2001 From: Gabor Juhos <juhosg@openwrt.org> -Date: Wed, 3 Apr 2013 19:28:50 +0200 -Subject: [PATCH 2/2] MIPS: implement pcibios_get_phb_of_node +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. @@ -17,6 +17,7 @@ Also remove the local assignment of bus->dev.of_node, it is not needed after the patch. Signed-off-by: Gabor Juhos <juhosg@openwrt.org> +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> --- arch/mips/pci/pci.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) |