0001
0002
0003
0004
0005
0006 #include <asm/iomap.h>
0007 #include <asm/memtype.h>
0008 #include <linux/export.h>
0009 #include <linux/highmem.h>
0010
0011 static int is_io_mapping_possible(resource_size_t base, unsigned long size)
0012 {
0013 #if !defined(CONFIG_X86_PAE) && defined(CONFIG_PHYS_ADDR_T_64BIT)
0014
0015 if (base + size > 0x100000000ULL)
0016 return 0;
0017 #endif
0018 return 1;
0019 }
0020
0021 int iomap_create_wc(resource_size_t base, unsigned long size, pgprot_t *prot)
0022 {
0023 enum page_cache_mode pcm = _PAGE_CACHE_MODE_WC;
0024 int ret;
0025
0026 if (!is_io_mapping_possible(base, size))
0027 return -EINVAL;
0028
0029 ret = memtype_reserve_io(base, base + size, &pcm);
0030 if (ret)
0031 return ret;
0032
0033 *prot = __pgprot(__PAGE_KERNEL | cachemode2protval(pcm));
0034
0035 pgprot_val(*prot) &= __default_kernel_pte_mask;
0036
0037 return 0;
0038 }
0039 EXPORT_SYMBOL_GPL(iomap_create_wc);
0040
0041 void iomap_free(resource_size_t base, unsigned long size)
0042 {
0043 memtype_free_io(base, base + size);
0044 }
0045 EXPORT_SYMBOL_GPL(iomap_free);
0046
0047 void __iomem *__iomap_local_pfn_prot(unsigned long pfn, pgprot_t prot)
0048 {
0049
0050
0051
0052
0053
0054
0055
0056 if (!pat_enabled() && pgprot2cachemode(prot) != _PAGE_CACHE_MODE_WB)
0057 prot = __pgprot(__PAGE_KERNEL |
0058 cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS));
0059
0060
0061 pgprot_val(prot) &= __default_kernel_pte_mask;
0062
0063 return (void __force __iomem *)__kmap_local_pfn_prot(pfn, prot);
0064 }
0065 EXPORT_SYMBOL_GPL(__iomap_local_pfn_prot);