Messages in this thread Patch in this message | | | Date | Tue, 18 Sep 2007 19:08:36 -0400 | From | Jeff Garzik <> | Subject | Re: [PATCH] Clarify pci_iomap() usage for MMIO-only devices |
| |
Benjamin Herrenschmidt wrote: > On Tue, 2007-09-18 at 16:21 -0400, Jeff Garzik wrote: >> A new pci_mmio_map() helper, to be used with 100% MMIO hardware, might >> help eliminate confusion. > > Maybe not the best name in theory but at least would show that it > relates to existing ioremap would be pci_ioremap()
Easy enough... 'pcimap' branch of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/misc-2.6.git
Jeff
commit 6e09c71822f76c618353682bf295fc7588284521 Author: Jeff Garzik <jeff@garzik.org> Date: Tue Sep 18 19:06:08 2007 -0400
Add pci_ioremap() to generic iomap lib.
(arches that don't wish to use lib/iomap.c's version may fill in their own)
Signed-off-by: Jeff Garzik <jeff@garzik.org>
include/asm-generic/iomap.h | 1 + lib/iomap.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+)
6e09c71822f76c618353682bf295fc7588284521 diff --git a/include/asm-generic/iomap.h b/include/asm-generic/iomap.h index cde592f..611e6cf 100644 --- a/include/asm-generic/iomap.h +++ b/include/asm-generic/iomap.h @@ -63,6 +63,7 @@ extern void ioport_unmap(void __iomem *); /* Create a virtual mapping cookie for a PCI BAR (memory or IO) */ struct pci_dev; extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max); +extern void __iomem *pci_ioremap(struct pci_dev *dev, int bar, unsigned long max); extern void pci_iounmap(struct pci_dev *dev, void __iomem *); #endif diff --git a/lib/iomap.c b/lib/iomap.c index 864f2ec..0338da0 100644 --- a/lib/iomap.c +++ b/lib/iomap.c @@ -275,9 +275,43 @@ void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) return NULL; } +/** + * pci_ioremap - create a virtual mapping cookie for a memory-based PCI BAR + * @dev: PCI device that owns the BAR + * @bar: BAR number + * @maxlen: length of MMIO memory to map + * + * Using this function you will get a __iomem address to your device BAR. + * You can access it using read*() and write*(). + * + * @maxlen specifies the maximum length to map. If you want to get access to + * the complete BAR without checking for its length first, pass %0 here. + * */ +void __iomem *pci_ioremap(struct pci_dev *dev, int bar, unsigned long maxlen) +{ + unsigned long start = pci_resource_start(dev, bar); + unsigned long len = pci_resource_len(dev, bar); + unsigned long flags = pci_resource_flags(dev, bar); + + if (!len || !start) + return NULL; + if (maxlen && len > maxlen) + len = maxlen; + if (flags & IORESOURCE_IO) + return NULL; + if (flags & IORESOURCE_MEM) { + if (flags & IORESOURCE_CACHEABLE) + return ioremap(start, len); + return ioremap_nocache(start, len); + } + /* What? */ + return NULL; +} + void pci_iounmap(struct pci_dev *dev, void __iomem * addr) { IO_COND(addr, /* nothing */, iounmap(addr)); } EXPORT_SYMBOL(pci_iomap); +EXPORT_SYMBOL(pci_ioremap); EXPORT_SYMBOL(pci_iounmap); | |