aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2009-04-20 16:38:00 +0900
committerPaul Mundt <lethal@linux-sh.org>2009-04-20 16:38:00 +0900
commit0bb34a6bf1f71d5ad2abfda582a2c2794957bc7b (patch)
tree2ac5a8400ac65001b78f173b51bd41b0f38d9376
parentsh: pci: Kill off unused pcibios_fixup(). (diff)
downloadlinux-dev-0bb34a6bf1f71d5ad2abfda582a2c2794957bc7b.tar.xz
linux-dev-0bb34a6bf1f71d5ad2abfda582a2c2794957bc7b.zip
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>
-rw-r--r--arch/sh/drivers/pci/pci-lib.c51
-rw-r--r--arch/sh/drivers/pci/pci-new.c35
-rw-r--r--arch/sh/drivers/pci/pci.c35
-rw-r--r--arch/sh/include/asm/pci.h22
-rw-r--r--arch/sh/kernel/io.c4
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 8ab1a2d1b483..654ffcc67d0a 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 4e9251f3d090..c92e65045c68 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 f670988e033d..d39f24091ade 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 e8265fd0bb6f..532428289772 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 59fb020718a3..4f85fffaa557 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);