aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiviu Dudau <Liviu.Dudau@arm.com>2014-09-29 10:29:30 -0400
committerBjorn Helgaas <bhelgaas@google.com>2014-09-30 19:08:57 -0400
commit8b921acfeffdb0b45085da862fc301a2d25ed2cf (patch)
tree4772e01279a51f92b80f22b1a5f57356c08b9bdc
parentcbe4097f8ae699ebbdaf8c95ecab38d47e0bd5da (diff)
PCI: Add pci_remap_iospace() to map bus I/O resources
Add pci_remap_iospace() to map bus I/O resources into the CPU virtual address space. Architectures with special needs may provide their own version, but most should be able to use this one. This function is useful for PCI host bridge drivers that need to map the PCI I/O resources into virtual memory space. [bhelgaas: phys_addr description, drop temporary "err" variable] Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Rob Herring <robh@kernel.org> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> CC: Arnd Bergmann <arnd@arndb.de>
-rw-r--r--drivers/pci/pci.c31
-rw-r--r--include/asm-generic/pgtable.h4
-rw-r--r--include/linux/pci.h3
3 files changed, 38 insertions, 0 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index d36f35ff6c5d..6e994fc077f4 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2704,6 +2704,37 @@ int pci_request_regions_exclusive(struct pci_dev *pdev, const char *res_name)
2704} 2704}
2705EXPORT_SYMBOL(pci_request_regions_exclusive); 2705EXPORT_SYMBOL(pci_request_regions_exclusive);
2706 2706
2707/**
2708 * pci_remap_iospace - Remap the memory mapped I/O space
2709 * @res: Resource describing the I/O space
2710 * @phys_addr: physical address of range to be mapped
2711 *
2712 * Remap the memory mapped I/O space described by the @res
2713 * and the CPU physical address @phys_addr into virtual address space.
2714 * Only architectures that have memory mapped IO functions defined
2715 * (and the PCI_IOBASE value defined) should call this function.
2716 */
2717int __weak pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr)
2718{
2719#if defined(PCI_IOBASE) && defined(CONFIG_MMU)
2720 unsigned long vaddr = (unsigned long)PCI_IOBASE + res->start;
2721
2722 if (!(res->flags & IORESOURCE_IO))
2723 return -EINVAL;
2724
2725 if (res->end > IO_SPACE_LIMIT)
2726 return -EINVAL;
2727
2728 return ioremap_page_range(vaddr, vaddr + resource_size(res), phys_addr,
2729 pgprot_device(PAGE_KERNEL));
2730#else
2731 /* this architecture does not have memory mapped I/O space,
2732 so this function should never be called */
2733 WARN_ONCE(1, "This architecture does not support memory mapped I/O\n");
2734 return -ENODEV;
2735#endif
2736}
2737
2707static void __pci_set_master(struct pci_dev *dev, bool enable) 2738static void __pci_set_master(struct pci_dev *dev, bool enable)
2708{ 2739{
2709 u16 old_cmd, cmd; 2740 u16 old_cmd, cmd;
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index 53b2acc38213..977e545a64c3 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -249,6 +249,10 @@ static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b)
249#define pgprot_writecombine pgprot_noncached 249#define pgprot_writecombine pgprot_noncached
250#endif 250#endif
251 251
252#ifndef pgprot_device
253#define pgprot_device pgprot_noncached
254#endif
255
252/* 256/*
253 * When walking page tables, get the address of the next boundary, 257 * When walking page tables, get the address of the next boundary,
254 * or the end address of the range if that comes earlier. Although no 258 * or the end address of the range if that comes earlier. Although no
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 150da2d644e7..b4995fdfffb1 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1100,6 +1100,9 @@ int __must_check pci_bus_alloc_resource(struct pci_bus *bus,
1100 resource_size_t), 1100 resource_size_t),
1101 void *alignf_data); 1101 void *alignf_data);
1102 1102
1103
1104int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr);
1105
1103static inline dma_addr_t pci_bus_address(struct pci_dev *pdev, int bar) 1106static inline dma_addr_t pci_bus_address(struct pci_dev *pdev, int bar)
1104{ 1107{
1105 struct pci_bus_region region; 1108 struct pci_bus_region region;