aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/Kconfig4
-rw-r--r--include/linux/io-mapping.h43
2 files changed, 29 insertions, 18 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 6f20718d3156..e60c59b81bdd 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1894,6 +1894,10 @@ config SYSVIPC_COMPAT
1894endmenu 1894endmenu
1895 1895
1896 1896
1897config HAVE_ATOMIC_IOMAP
1898 def_bool y
1899 depends on X86_32
1900
1897source "net/Kconfig" 1901source "net/Kconfig"
1898 1902
1899source "drivers/Kconfig" 1903source "drivers/Kconfig"
diff --git a/include/linux/io-mapping.h b/include/linux/io-mapping.h
index 1b566993db6e..82df31726a54 100644
--- a/include/linux/io-mapping.h
+++ b/include/linux/io-mapping.h
@@ -33,86 +33,93 @@
33/* this struct isn't actually defined anywhere */ 33/* this struct isn't actually defined anywhere */
34struct io_mapping; 34struct io_mapping;
35 35
36#ifdef CONFIG_X86_64 36#ifdef CONFIG_HAVE_ATOMIC_IOMAP
37
38/*
39 * For small address space machines, mapping large objects
40 * into the kernel virtual space isn't practical. Where
41 * available, use fixmap support to dynamically map pages
42 * of the object at run time.
43 */
37 44
38/* Create the io_mapping object*/
39static inline struct io_mapping * 45static inline struct io_mapping *
40io_mapping_create_wc(unsigned long base, unsigned long size) 46io_mapping_create_wc(unsigned long base, unsigned long size)
41{ 47{
42 return (struct io_mapping *) ioremap_wc(base, size); 48 return (struct io_mapping *) base;
43} 49}
44 50
45static inline void 51static inline void
46io_mapping_free(struct io_mapping *mapping) 52io_mapping_free(struct io_mapping *mapping)
47{ 53{
48 iounmap(mapping);
49} 54}
50 55
51/* Atomic map/unmap */ 56/* Atomic map/unmap */
52static inline void * 57static inline void *
53io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset) 58io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset)
54{ 59{
55 return ((char *) mapping) + offset; 60 offset += (unsigned long) mapping;
61 return iomap_atomic_prot_pfn(offset >> PAGE_SHIFT, KM_USER0,
62 __pgprot(__PAGE_KERNEL_WC));
56} 63}
57 64
58static inline void 65static inline void
59io_mapping_unmap_atomic(void *vaddr) 66io_mapping_unmap_atomic(void *vaddr)
60{ 67{
68 iounmap_atomic(vaddr, KM_USER0);
61} 69}
62 70
63/* Non-atomic map/unmap */
64static inline void * 71static inline void *
65io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset) 72io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset)
66{ 73{
67 return ((char *) mapping) + offset; 74 offset += (unsigned long) mapping;
75 return ioremap_wc(offset, PAGE_SIZE);
68} 76}
69 77
70static inline void 78static inline void
71io_mapping_unmap(void *vaddr) 79io_mapping_unmap(void *vaddr)
72{ 80{
81 iounmap(vaddr);
73} 82}
74 83
75#endif /* CONFIG_X86_64 */ 84#else
76 85
77#ifdef CONFIG_X86_32 86/* Create the io_mapping object*/
78static inline struct io_mapping * 87static inline struct io_mapping *
79io_mapping_create_wc(unsigned long base, unsigned long size) 88io_mapping_create_wc(unsigned long base, unsigned long size)
80{ 89{
81 return (struct io_mapping *) base; 90 return (struct io_mapping *) ioremap_wc(base, size);
82} 91}
83 92
84static inline void 93static inline void
85io_mapping_free(struct io_mapping *mapping) 94io_mapping_free(struct io_mapping *mapping)
86{ 95{
96 iounmap(mapping);
87} 97}
88 98
89/* Atomic map/unmap */ 99/* Atomic map/unmap */
90static inline void * 100static inline void *
91io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset) 101io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset)
92{ 102{
93 offset += (unsigned long) mapping; 103 return ((char *) mapping) + offset;
94 return iomap_atomic_prot_pfn(offset >> PAGE_SHIFT, KM_USER0,
95 __pgprot(__PAGE_KERNEL_WC));
96} 104}
97 105
98static inline void 106static inline void
99io_mapping_unmap_atomic(void *vaddr) 107io_mapping_unmap_atomic(void *vaddr)
100{ 108{
101 iounmap_atomic(vaddr, KM_USER0);
102} 109}
103 110
111/* Non-atomic map/unmap */
104static inline void * 112static inline void *
105io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset) 113io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset)
106{ 114{
107 offset += (unsigned long) mapping; 115 return ((char *) mapping) + offset;
108 return ioremap_wc(offset, PAGE_SIZE);
109} 116}
110 117
111static inline void 118static inline void
112io_mapping_unmap(void *vaddr) 119io_mapping_unmap(void *vaddr)
113{ 120{
114 iounmap(vaddr);
115} 121}
116#endif /* CONFIG_X86_32 */ 122
123#endif /* HAVE_ATOMIC_IOMAP */
117 124
118#endif /* _LINUX_IO_MAPPING_H */ 125#endif /* _LINUX_IO_MAPPING_H */