diff options
author | Paul Mundt <lethal@linux-sh.org> | 2009-04-20 16:38:00 +0900 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-04-20 16:38:00 +0900 |
commit | 0bb34a6bf1f71d5ad2abfda582a2c2794957bc7b (patch) | |
tree | 2ac5a8400ac65001b78f173b51bd41b0f38d9376 /arch/sh | |
parent | 394b6d2fe624246e258a218dac68d44fe9a8411f (diff) |
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')
-rw-r--r-- | arch/sh/drivers/pci/pci-lib.c | 51 | ||||
-rw-r--r-- | arch/sh/drivers/pci/pci-new.c | 35 | ||||
-rw-r--r-- | arch/sh/drivers/pci/pci.c | 35 | ||||
-rw-r--r-- | arch/sh/include/asm/pci.h | 22 | ||||
-rw-r--r-- | arch/sh/kernel/io.c | 4 |
5 files changed, 53 insertions, 94 deletions
diff --git a/arch/sh/drivers/pci/pci-lib.c b/arch/sh/drivers/pci/pci-lib.c index 8ab1a2d1b48..654ffcc67d0 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); diff --git a/arch/sh/drivers/pci/pci-new.c b/arch/sh/drivers/pci/pci-new.c index 4e9251f3d09..c92e65045c6 100644 --- a/arch/sh/drivers/pci/pci-new.c +++ b/arch/sh/drivers/pci/pci-new.c @@ -187,39 +187,4 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq) pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); } -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; - - /* - * 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_IO) - return ioport_map(start, len); - if (flags & IORESOURCE_MEM) - return ioremap(start, len); - - return NULL; -} -EXPORT_SYMBOL(pci_iomap); - -void pci_iounmap(struct pci_dev *dev, void __iomem *addr) -{ - iounmap(addr); -} -EXPORT_SYMBOL(pci_iounmap); - EXPORT_SYMBOL(board_pci_channels); diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index f670988e033..d39f24091ad 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -144,39 +144,4 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq) pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); } -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; - - /* - * 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_IO) - return ioport_map(start, len); - if (flags & IORESOURCE_MEM) - return ioremap(start, len); - - return NULL; -} -EXPORT_SYMBOL(pci_iomap); - -void pci_iounmap(struct pci_dev *dev, void __iomem *addr) -{ - iounmap(addr); -} -EXPORT_SYMBOL(pci_iounmap); - EXPORT_SYMBOL(board_pci_channels); diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index e8265fd0bb6..53242828977 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -26,6 +26,8 @@ struct pci_channel { int enabled; unsigned long reg_base; unsigned long io_base; + + unsigned long io_map_base; }; /* @@ -110,31 +112,11 @@ static inline int __is_pci_memory(unsigned long phys_addr, unsigned long size) } return 0; } - -static inline void __iomem *__get_pci_io_base(unsigned long port, - unsigned long size) -{ - struct pci_channel *p; - struct resource *res; - - for (p = board_pci_channels; p->init; p++) { - res = p->io_resource; - if (p->enabled && (port >= res->start) && - (port + size) <= (res->end + 1)) - return (void __iomem *)(p->io_base + port); - } - return NULL; -} #else static inline int __is_pci_memory(unsigned long phys_addr, unsigned long size) { return 0; } -static inline void __iomem *__get_pci_io_base(unsigned long port, - unsigned long size) -{ - return NULL; -} #endif /* Board-specific fixup routines. */ diff --git a/arch/sh/kernel/io.c b/arch/sh/kernel/io.c index 59fb020718a..4f85fffaa55 100644 --- a/arch/sh/kernel/io.c +++ b/arch/sh/kernel/io.c @@ -70,10 +70,6 @@ void __iomem *ioport_map(unsigned long port, unsigned int nr) if (ret) return ret; - ret = __get_pci_io_base(port, nr); - if (ret) - return ret; - return __ioport_map(port, nr); } EXPORT_SYMBOL(ioport_map); |