summaryrefslogtreecommitdiff
path: root/drivers/mxc
diff options
context:
space:
mode:
authorSammy He <r62914@freescale.com>2012-02-14 10:09:05 +0800
committerSammy He <r62914@freescale.com>2012-02-14 10:25:08 +0800
commit12ae952212e23bb6b19fde28511b9bc9350ecb26 (patch)
tree271cbda85cb6717453b36b952bb17ff49150034c /drivers/mxc
parentbcfa7c2f12af577240f587815aa80d93ad85934e (diff)
ENGR00174323 vpu: Fix system hang issue of multi-instances processing
VPU registers have been mapped with ioremap() at probe which L_PTE_XN is 1, and the same physical address must be mapped multiple times with same type when doing mmap() to user space, so also need to set it to 1. Otherwise, there may be unexpected result in video codec. Here, Use new defined pgprot_noncachedxn for vm_page_prot in mmap(). Signed-off-by: Sammy He <r62914@freescale.com>
Diffstat (limited to 'drivers/mxc')
-rw-r--r--drivers/mxc/vpu/mxc_vpu.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/mxc/vpu/mxc_vpu.c b/drivers/mxc/vpu/mxc_vpu.c
index 0e0e03835e87..20d523aac9e1 100644
--- a/drivers/mxc/vpu/mxc_vpu.c
+++ b/drivers/mxc/vpu/mxc_vpu.c
@@ -45,6 +45,10 @@
#include <mach/mxc_vpu.h>
+/* Define one new pgprot which combined uncached and XN(never executable) */
+#define pgprot_noncachedxn(prot) \
+ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED | L_PTE_XN)
+
struct vpu_priv {
struct fasync_struct *async_queue;
struct work_struct work;
@@ -511,7 +515,13 @@ static int vpu_map_hwregs(struct file *fp, struct vm_area_struct *vm)
unsigned long pfn;
vm->vm_flags |= VM_IO | VM_RESERVED;
- vm->vm_page_prot = pgprot_noncached(vm->vm_page_prot);
+ /*
+ * Since vpu registers have been mapped with ioremap() at probe
+ * which L_PTE_XN is 1, and the same physical address must be
+ * mapped multiple times with same type, so set L_PTE_XN to 1 here.
+ * Otherwise, there may be unexpected result in video codec.
+ */
+ vm->vm_page_prot = pgprot_noncachedxn(vm->vm_page_prot);
pfn = phy_vpu_base_addr >> PAGE_SHIFT;
pr_debug("size=0x%x, page no.=0x%x\n",
(int)(vm->vm_end - vm->vm_start), (int)pfn);