diff options
author | Paul Mundt <lethal@linux-sh.org> | 2009-04-20 07:38:00 (GMT) |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-04-20 07:38:00 (GMT) |
commit | 0bb34a6bf1f71d5ad2abfda582a2c2794957bc7b (patch) | |
tree | 2ac5a8400ac65001b78f173b51bd41b0f38d9376 /arch/sh/drivers/pci/pci-lib.c | |
parent | 394b6d2fe624246e258a218dac68d44fe9a8411f (diff) | |
download | linux-0bb34a6bf1f71d5ad2abfda582a2c2794957bc7b.tar.xz |
sh: pci: Consolidate pci_iomap() and use the generic I/O base.
This consolidates the pci_iomap() definitions and reworks how the I/O
port base is handled. PCI channels can register their own I/O map base,
or if none is provided, the system-wide generic I/O base is used instead.
Functionally nothing changes, while this allows us to kill off lots of
I/O address special casing and lookups.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/drivers/pci/pci-lib.c')
-rw-r--r-- | arch/sh/drivers/pci/pci-lib.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/arch/sh/drivers/pci/pci-lib.c b/arch/sh/drivers/pci/pci-lib.c index 8ab1a2d..654ffcc 100644 --- a/arch/sh/drivers/pci/pci-lib.c +++ b/arch/sh/drivers/pci/pci-lib.c @@ -60,6 +60,57 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, vma->vm_page_prot); } +static void __iomem *ioport_map_pci(struct pci_dev *dev, + unsigned long port, unsigned int nr) +{ + struct pci_channel *chan = dev->sysdata; + + if (!chan->io_map_base) + chan->io_map_base = generic_io_base; + + return (void __iomem *)(chan->io_map_base + port); +} + +void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) +{ + resource_size_t start = pci_resource_start(dev, bar); + resource_size_t len = pci_resource_len(dev, bar); + unsigned long flags = pci_resource_flags(dev, bar); + + if (unlikely(!len || !start)) + return NULL; + if (maxlen && len > maxlen) + len = maxlen; + + if (flags & IORESOURCE_IO) + return ioport_map_pci(dev, start, len); + + /* + * Presently the IORESOURCE_MEM case is a bit special, most + * SH7751 style PCI controllers have PCI memory at a fixed + * location in the address space where no remapping is desired. + * With the IORESOURCE_MEM case more care has to be taken + * to inhibit page table mapping for legacy cores, but this is + * punted off to __ioremap(). + * -- PFM. + */ + if (flags & IORESOURCE_MEM) { + if (flags & IORESOURCE_CACHEABLE) + return ioremap(start, len); + + return ioremap_nocache(start, len); + } + + return NULL; +} +EXPORT_SYMBOL(pci_iomap); + +void pci_iounmap(struct pci_dev *dev, void __iomem *addr) +{ + iounmap(addr); +} +EXPORT_SYMBOL(pci_iounmap); + #ifdef CONFIG_HOTPLUG EXPORT_SYMBOL(pcibios_resource_to_bus); EXPORT_SYMBOL(pcibios_bus_to_resource); |