diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/mem.c | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 56b2fb4fbc93..e83623ead441 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -300,6 +300,35 @@ static inline int private_mapping_ok(struct vm_area_struct *vma) | |||
300 | } | 300 | } |
301 | #endif | 301 | #endif |
302 | 302 | ||
303 | void __attribute__((weak)) | ||
304 | map_devmem(unsigned long pfn, unsigned long len, pgprot_t prot) | ||
305 | { | ||
306 | /* nothing. architectures can override. */ | ||
307 | } | ||
308 | |||
309 | void __attribute__((weak)) | ||
310 | unmap_devmem(unsigned long pfn, unsigned long len, pgprot_t prot) | ||
311 | { | ||
312 | /* nothing. architectures can override. */ | ||
313 | } | ||
314 | |||
315 | static void mmap_mem_open(struct vm_area_struct *vma) | ||
316 | { | ||
317 | map_devmem(vma->vm_pgoff, vma->vm_end - vma->vm_start, | ||
318 | vma->vm_page_prot); | ||
319 | } | ||
320 | |||
321 | static void mmap_mem_close(struct vm_area_struct *vma) | ||
322 | { | ||
323 | unmap_devmem(vma->vm_pgoff, vma->vm_end - vma->vm_start, | ||
324 | vma->vm_page_prot); | ||
325 | } | ||
326 | |||
327 | static struct vm_operations_struct mmap_mem_ops = { | ||
328 | .open = mmap_mem_open, | ||
329 | .close = mmap_mem_close | ||
330 | }; | ||
331 | |||
303 | static int mmap_mem(struct file * file, struct vm_area_struct * vma) | 332 | static int mmap_mem(struct file * file, struct vm_area_struct * vma) |
304 | { | 333 | { |
305 | size_t size = vma->vm_end - vma->vm_start; | 334 | size_t size = vma->vm_end - vma->vm_start; |
@@ -321,13 +350,17 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma) | |||
321 | size, | 350 | size, |
322 | vma->vm_page_prot); | 351 | vma->vm_page_prot); |
323 | 352 | ||
353 | vma->vm_ops = &mmap_mem_ops; | ||
354 | |||
324 | /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */ | 355 | /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */ |
325 | if (remap_pfn_range(vma, | 356 | if (remap_pfn_range(vma, |
326 | vma->vm_start, | 357 | vma->vm_start, |
327 | vma->vm_pgoff, | 358 | vma->vm_pgoff, |
328 | size, | 359 | size, |
329 | vma->vm_page_prot)) | 360 | vma->vm_page_prot)) { |
361 | unmap_devmem(vma->vm_pgoff, size, vma->vm_page_prot); | ||
330 | return -EAGAIN; | 362 | return -EAGAIN; |
363 | } | ||
331 | return 0; | 364 | return 0; |
332 | } | 365 | } |
333 | 366 | ||