summaryrefslogtreecommitdiffstats
path: root/drivers/char/mem.c
diff options
context:
space:
mode:
authorvenkatesh.pallipadi@intel.com <venkatesh.pallipadi@intel.com>2008-03-18 17:00:21 -0700
committerIngo Molnar <mingo@elte.hu>2008-04-24 23:40:47 +0200
commite7f260a276f2c9184fe753732d834b1f6fbe9f17 (patch)
treea3189a6f29dd89f4bd91002a4cc9cb05dc9c9c63 /drivers/char/mem.c
parentf0970c13b6a5b01189aeb196ebb573cf87d95839 (diff)
downloadlinux-e7f260a276f2c9184fe753732d834b1f6fbe9f17.tar.gz
linux-e7f260a276f2c9184fe753732d834b1f6fbe9f17.tar.bz2
linux-e7f260a276f2c9184fe753732d834b1f6fbe9f17.zip
x86: PAT use reserve free memtype in mmap of /dev/mem
Use reserve_memtype and free_memtype wrappers for /dev/mem mmaps. The memtype is slightly complicated here, given that we have to support existing X mappings. We fallback on UC_MINUS for that. Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/char/mem.c')
-rw-r--r--drivers/char/mem.c35
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)
}
#endif
+void __attribute__((weak))
+map_devmem(unsigned long pfn, unsigned long len, pgprot_t prot)
+{
+ /* nothing. architectures can override. */
+}
+
+void __attribute__((weak))
+unmap_devmem(unsigned long pfn, unsigned long len, pgprot_t prot)
+{
+ /* nothing. architectures can override. */
+}
+
+static void mmap_mem_open(struct vm_area_struct *vma)
+{
+ map_devmem(vma->vm_pgoff, vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+static void mmap_mem_close(struct vm_area_struct *vma)
+{
+ unmap_devmem(vma->vm_pgoff, vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+static struct vm_operations_struct mmap_mem_ops = {
+ .open = mmap_mem_open,
+ .close = mmap_mem_close
+};
+
static int mmap_mem(struct file * file, struct vm_area_struct * vma)
{
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)
size,
vma->vm_page_prot);
+ vma->vm_ops = &mmap_mem_ops;
+
/* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
if (remap_pfn_range(vma,
vma->vm_start,
vma->vm_pgoff,
size,
- vma->vm_page_prot))
+ vma->vm_page_prot)) {
+ unmap_devmem(vma->vm_pgoff, size, vma->vm_page_prot);
return -EAGAIN;
+ }
return 0;
}