diff options
author | Rob Herring <rob.herring@calxeda.com> | 2012-07-09 21:59:03 -0500 |
---|---|---|
committer | Rob Herring <rob.herring@calxeda.com> | 2012-07-26 09:09:17 -0500 |
commit | 3c5d1699887bfcd17e6d9842ba7e2b3234e665db (patch) | |
tree | 67704d14f9877622c305fee05ced1af7cee0654a /arch/arm/kernel/bios32.c | |
parent | c2794437091a4fda72c4a4f3567dd728dcc0c3c9 (diff) | |
download | kernel_goldelico_gta04-3c5d1699887bfcd17e6d9842ba7e2b3234e665db.zip kernel_goldelico_gta04-3c5d1699887bfcd17e6d9842ba7e2b3234e665db.tar.gz kernel_goldelico_gta04-3c5d1699887bfcd17e6d9842ba7e2b3234e665db.tar.bz2 |
ARM: move PCI i/o resource setup into common code
With consolidation of the PCI i/o mappings, the i/o space is being
set to start at a PCI bus addr of 0x0 and fixed to 64K per bus. In
this case the core ARM PCI setup code can setup the i/o resource.
Currently, the resource is only setup if the platform did not setup
an i/o resource.
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/arm/kernel/bios32.c')
-rw-r--r-- | arch/arm/kernel/bios32.c | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index c3165f0..036f7ea 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -424,6 +424,38 @@ static int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) return irq; } +static int __init pcibios_init_resources(int busnr, struct pci_sys_data *sys) +{ + int ret; + struct pci_host_bridge_window *window; + + if (list_empty(&sys->resources)) { + pci_add_resource_offset(&sys->resources, + &iomem_resource, sys->mem_offset); + } + + list_for_each_entry(window, &sys->resources, list) { + if (resource_type(window->res) == IORESOURCE_IO) + return 0; + } + + sys->io_res.start = (busnr * SZ_64K) ? : pcibios_min_io; + sys->io_res.end = (busnr + 1) * SZ_64K - 1; + sys->io_res.flags = IORESOURCE_IO; + sys->io_res.name = sys->io_res_name; + sprintf(sys->io_res_name, "PCI%d I/O", busnr); + + ret = request_resource(&ioport_resource, &sys->io_res); + if (ret) { + pr_err("PCI: unable to allocate I/O port region (%d)\n", ret); + return ret; + } + pci_add_resource_offset(&sys->resources, &sys->io_res, + sys->io_offset); + + return 0; +} + static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head) { struct pci_sys_data *sys = NULL; @@ -446,11 +478,10 @@ static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head) ret = hw->setup(nr, sys); if (ret > 0) { - if (list_empty(&sys->resources)) { - pci_add_resource_offset(&sys->resources, - &ioport_resource, sys->io_offset); - pci_add_resource_offset(&sys->resources, - &iomem_resource, sys->mem_offset); + ret = pcibios_init_resources(nr, sys); + if (ret) { + kfree(sys); + break; } if (hw->scan) |