aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/bsr.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c
index 7d9fd8a8dfd0..c02db01f736e 100644
--- a/drivers/char/bsr.c
+++ b/drivers/char/bsr.c
@@ -27,6 +27,7 @@
27#include <linux/cdev.h> 27#include <linux/cdev.h>
28#include <linux/list.h> 28#include <linux/list.h>
29#include <linux/mm.h> 29#include <linux/mm.h>
30#include <asm/pgtable.h>
30#include <asm/io.h> 31#include <asm/io.h>
31 32
32/* 33/*
@@ -118,15 +119,22 @@ static int bsr_mmap(struct file *filp, struct vm_area_struct *vma)
118{ 119{
119 unsigned long size = vma->vm_end - vma->vm_start; 120 unsigned long size = vma->vm_end - vma->vm_start;
120 struct bsr_dev *dev = filp->private_data; 121 struct bsr_dev *dev = filp->private_data;
122 int ret;
121 123
122 if (size > dev->bsr_len || (size & (PAGE_SIZE-1)))
123 return -EINVAL;
124
125 vma->vm_flags |= (VM_IO | VM_DONTEXPAND);
126 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 124 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
127 125
128 if (io_remap_pfn_range(vma, vma->vm_start, dev->bsr_addr >> PAGE_SHIFT, 126 /* check for the case of a small BSR device and map one 4k page for it*/
129 size, vma->vm_page_prot)) 127 if (dev->bsr_len < PAGE_SIZE && size == PAGE_SIZE)
128 ret = remap_4k_pfn(vma, vma->vm_start, dev->bsr_addr >> 12,
129 vma->vm_page_prot);
130 else if (size <= dev->bsr_len)
131 ret = io_remap_pfn_range(vma, vma->vm_start,
132 dev->bsr_addr >> PAGE_SHIFT,
133 size, vma->vm_page_prot);
134 else
135 return -EINVAL;
136
137 if (ret)
130 return -EAGAIN; 138 return -EAGAIN;
131 139
132 return 0; 140 return 0;
@@ -206,6 +214,11 @@ static int bsr_add_node(struct device_node *bn)
206 cur->bsr_stride = bsr_stride[i]; 214 cur->bsr_stride = bsr_stride[i];
207 cur->bsr_dev = MKDEV(bsr_major, i + total_bsr_devs); 215 cur->bsr_dev = MKDEV(bsr_major, i + total_bsr_devs);
208 216
217 /* if we have a bsr_len of > 4k and less then PAGE_SIZE (64k pages) */
218 /* we can only map 4k of it, so only advertise the 4k in sysfs */
219 if (cur->bsr_len > 4096 && cur->bsr_len < PAGE_SIZE)
220 cur->bsr_len = 4096;
221
209 switch(cur->bsr_bytes) { 222 switch(cur->bsr_bytes) {
210 case 8: 223 case 8:
211 cur->bsr_type = BSR_8; 224 cur->bsr_type = BSR_8;