diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2013-04-11 17:32:28 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2013-06-03 02:02:47 -0400 |
commit | 14d86e725ed034917bc721cf5deea019857b6cf0 (patch) | |
tree | 09ca04236ddfad4c11d04691491e58b1e7597db8 /arch/arm/kernel/bios32.c | |
parent | 301d2d87cb4f826a38548f692e1b3c8c23590a9f (diff) |
ARM: pci: create pci_common_init_dev()
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.
Cc: Mike Rapoport <mike@compulab.co.il>
Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Benjamin Herrenschmitt <benh@kernel.crashing.org>
Reviewed-by: Andrew Murray <andrew.murray@arm.com>
Reviewed-by: Thierry Reding <thierry.reding@avionic-design.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'arch/arm/kernel/bios32.c')
-rw-r--r-- | arch/arm/kernel/bios32.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index b2ed73c45489..261fcc826169 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c | |||
@@ -445,7 +445,8 @@ static int pcibios_init_resources(int busnr, struct pci_sys_data *sys) | |||
445 | return 0; | 445 | return 0; |
446 | } | 446 | } |
447 | 447 | ||
448 | static void pcibios_init_hw(struct hw_pci *hw, struct list_head *head) | 448 | static void pcibios_init_hw(struct device *parent, struct hw_pci *hw, |
449 | struct list_head *head) | ||
449 | { | 450 | { |
450 | struct pci_sys_data *sys = NULL; | 451 | struct pci_sys_data *sys = NULL; |
451 | int ret; | 452 | int ret; |
@@ -480,7 +481,7 @@ static void pcibios_init_hw(struct hw_pci *hw, struct list_head *head) | |||
480 | if (hw->scan) | 481 | if (hw->scan) |
481 | sys->bus = hw->scan(nr, sys); | 482 | sys->bus = hw->scan(nr, sys); |
482 | else | 483 | else |
483 | sys->bus = pci_scan_root_bus(NULL, sys->busnr, | 484 | sys->bus = pci_scan_root_bus(parent, sys->busnr, |
484 | hw->ops, sys, &sys->resources); | 485 | hw->ops, sys, &sys->resources); |
485 | 486 | ||
486 | if (!sys->bus) | 487 | if (!sys->bus) |
@@ -497,7 +498,7 @@ static void pcibios_init_hw(struct hw_pci *hw, struct list_head *head) | |||
497 | } | 498 | } |
498 | } | 499 | } |
499 | 500 | ||
500 | void pci_common_init(struct hw_pci *hw) | 501 | void pci_common_init_dev(struct device *parent, struct hw_pci *hw) |
501 | { | 502 | { |
502 | struct pci_sys_data *sys; | 503 | struct pci_sys_data *sys; |
503 | LIST_HEAD(head); | 504 | LIST_HEAD(head); |
@@ -505,7 +506,7 @@ void pci_common_init(struct hw_pci *hw) | |||
505 | pci_add_flags(PCI_REASSIGN_ALL_RSRC); | 506 | pci_add_flags(PCI_REASSIGN_ALL_RSRC); |
506 | if (hw->preinit) | 507 | if (hw->preinit) |
507 | hw->preinit(); | 508 | hw->preinit(); |
508 | pcibios_init_hw(hw, &head); | 509 | pcibios_init_hw(parent, hw, &head); |
509 | if (hw->postinit) | 510 | if (hw->postinit) |
510 | hw->postinit(); | 511 | hw->postinit(); |
511 | 512 | ||