aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/bios32.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2012-08-13 10:56:29 -0400
committerArnd Bergmann <arnd@arndb.de>2012-08-13 10:56:29 -0400
commit19ec6caca2da706f11646249ba280177fec359fa (patch)
tree6064421bc4924e7debdc8576a187cbdec4b8c352 /arch/arm/kernel/bios32.c
parent0d7614f09c1ebdbaa1599a5aba7593f147bf96ee (diff)
parentdd9bf78040fa0da4cecc228e1682b9682b8cb180 (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.c54
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
18static int debug_pci; 19static 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
427static 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
426static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head) 459static 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
663void __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}