diff options
author | Arnd Bergmann <arnd@arndb.de> | 2012-08-13 10:56:29 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2012-08-13 10:56:29 -0400 |
commit | 19ec6caca2da706f11646249ba280177fec359fa (patch) | |
tree | 6064421bc4924e7debdc8576a187cbdec4b8c352 /arch/arm/kernel/bios32.c | |
parent | 0d7614f09c1ebdbaa1599a5aba7593f147bf96ee (diff) | |
parent | dd9bf78040fa0da4cecc228e1682b9682b8cb180 (diff) |
Merge branch 'cleanup/io-pci' into next/cleanups
From Rob Herring <robherring2@gmail.com>:
This is the 2nd part of mach/io.h removals. This series removes io.h on
platforms with PCI by creating a fixed virtual I/O mapping and a common
__io() macro.
This version has changed a bit to accommodate Tegra converting its PCIe
host to a platform driver. Now the virtual space is only reserved during
early boot before .map_io() is called. The mapping is not created until
calling pci_ioremap_io which can be done at any point after vmalloc is
initialized.
I've gone back to fixed 64K windows for each PCI bus. This allows
removing all the i/o resource setup from the individually platforms and
placing it within the common ARM PCI code.
I've only tested versatilepb under qemu (with the model hacked up to
actually enable i/o space), so any testing is appreciated. iop3xx and
mv78xx0 have some risk of breaking as the PCI bus addresses are moved
to 0 from matching the cpu host bus addesss.
* cleanup/io-pci:
ARM: iop3xx: use fixed PCI i/o mapping
ARM: mv78xx0: use fixed pci i/o mapping
ARM: iop13xx: use fixed PCI i/o mapping
iop13xx: use more regular PCI I/O space handling
ARM: orion5x: use fixed PCI i/o mapping
ARM: kirkwood: use fixed PCI i/o mapping
ARM: dove: use fixed PCI i/o mapping
ARM: footbridge: use fixed PCI i/o mapping
ARM: shark: use fixed PCI i/o mapping
ARM: integrator: remove trailing whitespace on pci_v3.c
ARM: integrator: use fixed PCI i/o mapping
ARM: tegra: use fixed PCI i/o mapping
ARM: versatile: use fixed PCI i/o mapping
ARM: move PCI i/o resource setup into common code
ARM: Add fixed PCI i/o mapping
i2c: iop3xx: use standard gpiolib functions
i2c: iop3xx: clean-up trailing whitespace
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/arm/kernel/bios32.c')
-rw-r--r-- | arch/arm/kernel/bios32.c | 54 |
1 files changed, 49 insertions, 5 deletions
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index 2b2f25e7fef5..b244696de1a3 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/io.h> | 13 | #include <linux/io.h> |
14 | 14 | ||
15 | #include <asm/mach-types.h> | 15 | #include <asm/mach-types.h> |
16 | #include <asm/mach/map.h> | ||
16 | #include <asm/mach/pci.h> | 17 | #include <asm/mach/pci.h> |
17 | 18 | ||
18 | static int debug_pci; | 19 | static int debug_pci; |
@@ -423,6 +424,38 @@ static int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |||
423 | return irq; | 424 | return irq; |
424 | } | 425 | } |
425 | 426 | ||
427 | static int __init pcibios_init_resources(int busnr, struct pci_sys_data *sys) | ||
428 | { | ||
429 | int ret; | ||
430 | struct pci_host_bridge_window *window; | ||
431 | |||
432 | if (list_empty(&sys->resources)) { | ||
433 | pci_add_resource_offset(&sys->resources, | ||
434 | &iomem_resource, sys->mem_offset); | ||
435 | } | ||
436 | |||
437 | list_for_each_entry(window, &sys->resources, list) { | ||
438 | if (resource_type(window->res) == IORESOURCE_IO) | ||
439 | return 0; | ||
440 | } | ||
441 | |||
442 | sys->io_res.start = (busnr * SZ_64K) ? : pcibios_min_io; | ||
443 | sys->io_res.end = (busnr + 1) * SZ_64K - 1; | ||
444 | sys->io_res.flags = IORESOURCE_IO; | ||
445 | sys->io_res.name = sys->io_res_name; | ||
446 | sprintf(sys->io_res_name, "PCI%d I/O", busnr); | ||
447 | |||
448 | ret = request_resource(&ioport_resource, &sys->io_res); | ||
449 | if (ret) { | ||
450 | pr_err("PCI: unable to allocate I/O port region (%d)\n", ret); | ||
451 | return ret; | ||
452 | } | ||
453 | pci_add_resource_offset(&sys->resources, &sys->io_res, | ||
454 | sys->io_offset); | ||
455 | |||
456 | return 0; | ||
457 | } | ||
458 | |||
426 | static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head) | 459 | static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head) |
427 | { | 460 | { |
428 | struct pci_sys_data *sys = NULL; | 461 | struct pci_sys_data *sys = NULL; |
@@ -445,11 +478,10 @@ static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head) | |||
445 | ret = hw->setup(nr, sys); | 478 | ret = hw->setup(nr, sys); |
446 | 479 | ||
447 | if (ret > 0) { | 480 | if (ret > 0) { |
448 | if (list_empty(&sys->resources)) { | 481 | ret = pcibios_init_resources(nr, sys); |
449 | pci_add_resource_offset(&sys->resources, | 482 | if (ret) { |
450 | &ioport_resource, sys->io_offset); | 483 | kfree(sys); |
451 | pci_add_resource_offset(&sys->resources, | 484 | break; |
452 | &iomem_resource, sys->mem_offset); | ||
453 | } | 485 | } |
454 | 486 | ||
455 | if (hw->scan) | 487 | if (hw->scan) |
@@ -627,3 +659,15 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
627 | 659 | ||
628 | return 0; | 660 | return 0; |
629 | } | 661 | } |
662 | |||
663 | void __init pci_map_io_early(unsigned long pfn) | ||
664 | { | ||
665 | struct map_desc pci_io_desc = { | ||
666 | .virtual = PCI_IO_VIRT_BASE, | ||
667 | .type = MT_DEVICE, | ||
668 | .length = SZ_64K, | ||
669 | }; | ||
670 | |||
671 | pci_io_desc.pfn = pfn; | ||
672 | iotable_init(&pci_io_desc, 1); | ||
673 | } | ||