Blame view

include/linux/io-mapping.h 4.32 KB
9663f2e6a   Keith Packard   resources: add io...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  /*
   * Copyright © 2008 Keith Packard <keithp@keithp.com>
   *
   * This file is free software; you can redistribute it and/or modify
   * it under the terms of version 2 of the GNU General Public License
   * as published by the Free Software Foundation.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software Foundation,
   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
   */
  
  #ifndef _LINUX_IO_MAPPING_H
  #define _LINUX_IO_MAPPING_H
  
  #include <linux/types.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
22
  #include <linux/slab.h>
187f1882b   Paul Gortmaker   BUG: headers with...
23
  #include <linux/bug.h>
2584cf835   Dan Williams   arch, drivers: do...
24
  #include <linux/io.h>
9663f2e6a   Keith Packard   resources: add io...
25
  #include <asm/page.h>
9663f2e6a   Keith Packard   resources: add io...
26
27
28
29
30
  
  /*
   * The io_mapping mechanism provides an abstraction for mapping
   * individual pages from an io device to the CPU in an efficient fashion.
   *
395cf9691   Paul Bolle   doc: fix broken r...
31
   * See Documentation/io-mapping.txt
9663f2e6a   Keith Packard   resources: add io...
32
   */
4ab0d47d0   Venkatesh Pallipadi   gpu/drm, x86, PAT...
33
34
35
36
  struct io_mapping {
  	resource_size_t base;
  	unsigned long size;
  	pgprot_t prot;
cafaf14a5   Chris Wilson   io-mapping: Alway...
37
  	void __iomem *iomem;
4ab0d47d0   Venkatesh Pallipadi   gpu/drm, x86, PAT...
38
  };
cafaf14a5   Chris Wilson   io-mapping: Alway...
39
40
41
  #ifdef CONFIG_HAVE_ATOMIC_IOMAP
  
  #include <asm/iomap.h>
e5beae169   Keith Packard   io mapping: clean...
42
43
44
45
46
47
  /*
   * For small address space machines, mapping large objects
   * into the kernel virtual space isn't practical. Where
   * available, use fixmap support to dynamically map pages
   * of the object at run time.
   */
9663f2e6a   Keith Packard   resources: add io...
48

9663f2e6a   Keith Packard   resources: add io...
49
  static inline struct io_mapping *
cafaf14a5   Chris Wilson   io-mapping: Alway...
50
51
52
  io_mapping_init_wc(struct io_mapping *iomap,
  		   resource_size_t base,
  		   unsigned long size)
9663f2e6a   Keith Packard   resources: add io...
53
  {
9e36fda0b   Venkatesh Pallipadi   x86, pat: Add PAT...
54
  	pgprot_t prot;
4ab0d47d0   Venkatesh Pallipadi   gpu/drm, x86, PAT...
55

9e36fda0b   Venkatesh Pallipadi   x86, pat: Add PAT...
56
  	if (iomap_create_wc(base, size, &prot))
cafaf14a5   Chris Wilson   io-mapping: Alway...
57
  		return NULL;
4ab0d47d0   Venkatesh Pallipadi   gpu/drm, x86, PAT...
58
59
60
  
  	iomap->base = base;
  	iomap->size = size;
9e36fda0b   Venkatesh Pallipadi   x86, pat: Add PAT...
61
  	iomap->prot = prot;
4ab0d47d0   Venkatesh Pallipadi   gpu/drm, x86, PAT...
62
  	return iomap;
9663f2e6a   Keith Packard   resources: add io...
63
64
65
  }
  
  static inline void
cafaf14a5   Chris Wilson   io-mapping: Alway...
66
  io_mapping_fini(struct io_mapping *mapping)
9663f2e6a   Keith Packard   resources: add io...
67
  {
9e36fda0b   Venkatesh Pallipadi   x86, pat: Add PAT...
68
  	iomap_free(mapping->base, mapping->size);
9663f2e6a   Keith Packard   resources: add io...
69
70
71
  }
  
  /* Atomic map/unmap */
29bc17ecb   Francisco Jerez   io-mapping: Fix t...
72
  static inline void __iomem *
fca3ec01e   Chris Wilson   drm,io-mapping: S...
73
  io_mapping_map_atomic_wc(struct io_mapping *mapping,
3e4d3af50   Peter Zijlstra   mm: stack based k...
74
  			 unsigned long offset)
9663f2e6a   Keith Packard   resources: add io...
75
  {
4ab0d47d0   Venkatesh Pallipadi   gpu/drm, x86, PAT...
76
77
78
79
80
81
  	resource_size_t phys_addr;
  	unsigned long pfn;
  
  	BUG_ON(offset >= mapping->size);
  	phys_addr = mapping->base + offset;
  	pfn = (unsigned long) (phys_addr >> PAGE_SHIFT);
3e4d3af50   Peter Zijlstra   mm: stack based k...
82
  	return iomap_atomic_prot_pfn(pfn, mapping->prot);
9663f2e6a   Keith Packard   resources: add io...
83
84
85
  }
  
  static inline void
3e4d3af50   Peter Zijlstra   mm: stack based k...
86
  io_mapping_unmap_atomic(void __iomem *vaddr)
9663f2e6a   Keith Packard   resources: add io...
87
  {
3e4d3af50   Peter Zijlstra   mm: stack based k...
88
  	iounmap_atomic(vaddr);
9663f2e6a   Keith Packard   resources: add io...
89
  }
29bc17ecb   Francisco Jerez   io-mapping: Fix t...
90
  static inline void __iomem *
d8dab00de   Chris Wilson   io-mapping: Speci...
91
92
93
  io_mapping_map_wc(struct io_mapping *mapping,
  		  unsigned long offset,
  		  unsigned long size)
9663f2e6a   Keith Packard   resources: add io...
94
  {
5ce04e3de   Pallipadi, Venkatesh   fix warning in io...
95
  	resource_size_t phys_addr;
4ab0d47d0   Venkatesh Pallipadi   gpu/drm, x86, PAT...
96
  	BUG_ON(offset >= mapping->size);
5ce04e3de   Pallipadi, Venkatesh   fix warning in io...
97
  	phys_addr = mapping->base + offset;
d8dab00de   Chris Wilson   io-mapping: Speci...
98
  	return ioremap_wc(phys_addr, size);
9663f2e6a   Keith Packard   resources: add io...
99
100
101
  }
  
  static inline void
29bc17ecb   Francisco Jerez   io-mapping: Fix t...
102
  io_mapping_unmap(void __iomem *vaddr)
9663f2e6a   Keith Packard   resources: add io...
103
  {
e5beae169   Keith Packard   io mapping: clean...
104
  	iounmap(vaddr);
9663f2e6a   Keith Packard   resources: add io...
105
  }
e5beae169   Keith Packard   io mapping: clean...
106
  #else
9663f2e6a   Keith Packard   resources: add io...
107

24dd85ff7   Daniel Vetter   io-mapping: ensur...
108
  #include <linux/uaccess.h>
bcaaa0c43   Chris Wilson   io-mapping.h: s/P...
109
  #include <asm/pgtable.h>
4ab0d47d0   Venkatesh Pallipadi   gpu/drm, x86, PAT...
110

e5beae169   Keith Packard   io mapping: clean...
111
  /* Create the io_mapping object*/
9663f2e6a   Keith Packard   resources: add io...
112
  static inline struct io_mapping *
cafaf14a5   Chris Wilson   io-mapping: Alway...
113
114
115
116
117
118
119
  io_mapping_init_wc(struct io_mapping *iomap,
  		   resource_size_t base,
  		   unsigned long size)
  {
  	iomap->base = base;
  	iomap->size = size;
  	iomap->iomem = ioremap_wc(base, size);
351243897   Daniel Vetter   io-mapping: Fixup...
120
121
122
  #if defined(pgprot_noncached_wc) /* archs can't agree on a name ... */
  	iomap->prot = pgprot_noncached_wc(PAGE_KERNEL);
  #elif defined(pgprot_writecombine)
bcaaa0c43   Chris Wilson   io-mapping.h: s/P...
123
  	iomap->prot = pgprot_writecombine(PAGE_KERNEL);
351243897   Daniel Vetter   io-mapping: Fixup...
124
125
126
  #else
  	iomap->prot = pgprot_noncached(PAGE_KERNEL);
  #endif
cafaf14a5   Chris Wilson   io-mapping: Alway...
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
  
  	return iomap;
  }
  
  static inline void
  io_mapping_fini(struct io_mapping *mapping)
  {
  	iounmap(mapping->iomem);
  }
  
  /* Non-atomic map/unmap */
  static inline void __iomem *
  io_mapping_map_wc(struct io_mapping *mapping,
  		  unsigned long offset,
  		  unsigned long size)
9663f2e6a   Keith Packard   resources: add io...
142
  {
cafaf14a5   Chris Wilson   io-mapping: Alway...
143
  	return mapping->iomem + offset;
9663f2e6a   Keith Packard   resources: add io...
144
145
146
  }
  
  static inline void
cafaf14a5   Chris Wilson   io-mapping: Alway...
147
  io_mapping_unmap(void __iomem *vaddr)
9663f2e6a   Keith Packard   resources: add io...
148
149
150
151
  {
  }
  
  /* Atomic map/unmap */
29bc17ecb   Francisco Jerez   io-mapping: Fix t...
152
  static inline void __iomem *
fca3ec01e   Chris Wilson   drm,io-mapping: S...
153
  io_mapping_map_atomic_wc(struct io_mapping *mapping,
3e4d3af50   Peter Zijlstra   mm: stack based k...
154
  			 unsigned long offset)
9663f2e6a   Keith Packard   resources: add io...
155
  {
2cb7c9cb4   David Hildenbrand   sched/preempt, mm...
156
  	preempt_disable();
24dd85ff7   Daniel Vetter   io-mapping: ensur...
157
  	pagefault_disable();
cafaf14a5   Chris Wilson   io-mapping: Alway...
158
  	return io_mapping_map_wc(mapping, offset, PAGE_SIZE);
9663f2e6a   Keith Packard   resources: add io...
159
160
161
  }
  
  static inline void
3e4d3af50   Peter Zijlstra   mm: stack based k...
162
  io_mapping_unmap_atomic(void __iomem *vaddr)
9663f2e6a   Keith Packard   resources: add io...
163
  {
cafaf14a5   Chris Wilson   io-mapping: Alway...
164
  	io_mapping_unmap(vaddr);
24dd85ff7   Daniel Vetter   io-mapping: ensur...
165
  	pagefault_enable();
2cb7c9cb4   David Hildenbrand   sched/preempt, mm...
166
  	preempt_enable();
9663f2e6a   Keith Packard   resources: add io...
167
  }
cafaf14a5   Chris Wilson   io-mapping: Alway...
168
169
170
171
172
  #endif /* HAVE_ATOMIC_IOMAP */
  
  static inline struct io_mapping *
  io_mapping_create_wc(resource_size_t base,
  		     unsigned long size)
9663f2e6a   Keith Packard   resources: add io...
173
  {
cafaf14a5   Chris Wilson   io-mapping: Alway...
174
175
176
177
178
179
180
181
182
183
184
185
  	struct io_mapping *iomap;
  
  	iomap = kmalloc(sizeof(*iomap), GFP_KERNEL);
  	if (!iomap)
  		return NULL;
  
  	if (!io_mapping_init_wc(iomap, base, size)) {
  		kfree(iomap);
  		return NULL;
  	}
  
  	return iomap;
9663f2e6a   Keith Packard   resources: add io...
186
187
188
  }
  
  static inline void
cafaf14a5   Chris Wilson   io-mapping: Alway...
189
  io_mapping_free(struct io_mapping *iomap)
9663f2e6a   Keith Packard   resources: add io...
190
  {
cafaf14a5   Chris Wilson   io-mapping: Alway...
191
192
  	io_mapping_fini(iomap);
  	kfree(iomap);
9663f2e6a   Keith Packard   resources: add io...
193
  }
e5beae169   Keith Packard   io mapping: clean...
194

9663f2e6a   Keith Packard   resources: add io...
195
  #endif /* _LINUX_IO_MAPPING_H */