diff options
Diffstat (limited to 'drivers/char/mem.c')
| -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 | ||
