aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-s5p/s5p-sysmmu.c
diff options
context:
space:
mode:
authorcodeworkx <codeworkx@cyanogenmod.com>2012-09-17 17:53:57 +0200
committercodeworkx <codeworkx@cyanogenmod.com>2012-09-18 16:31:59 +0200
commitc28265764ec6ad9995eb0c761a376ffc9f141fcd (patch)
tree3ad899757480d47deb2be6011509a4243e8e0dc2 /arch/arm/plat-s5p/s5p-sysmmu.c
parent0ddbcb39c0dc0318f68d858f25a96a074142af2f (diff)
downloadkernel_samsung_smdk4412-c28265764ec6ad9995eb0c761a376ffc9f141fcd.zip
kernel_samsung_smdk4412-c28265764ec6ad9995eb0c761a376ffc9f141fcd.tar.gz
kernel_samsung_smdk4412-c28265764ec6ad9995eb0c761a376ffc9f141fcd.tar.bz2
applied patches from i9305 jb sources, updated mali to r3p0
Change-Id: Iec4bc4e2fb59e2cf5b4d25568a644d4e3719565e
Diffstat (limited to 'arch/arm/plat-s5p/s5p-sysmmu.c')
-rw-r--r--arch/arm/plat-s5p/s5p-sysmmu.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/arch/arm/plat-s5p/s5p-sysmmu.c b/arch/arm/plat-s5p/s5p-sysmmu.c
index dae74e1..70edd49 100644
--- a/arch/arm/plat-s5p/s5p-sysmmu.c
+++ b/arch/arm/plat-s5p/s5p-sysmmu.c
@@ -85,6 +85,11 @@ static struct sysmmu_drvdata *get_sysmmu_data(struct device *owner,
return NULL;
}
+struct list_head *get_sysmmu_list(void)
+{
+ return &sysmmu_list;
+}
+
static struct sysmmu_drvdata *get_sysmmu_data_rollback(struct device *owner,
struct sysmmu_drvdata *start)
{
@@ -148,6 +153,12 @@ static void __sysmmu_tlb_invalidate(void __iomem *sfrbase)
__raw_writel(0x1, sfrbase + S5P_MMU_FLUSH);
}
+static void __sysmmu_tlb_invalidate_entry(void __iomem *sfrbase,
+ unsigned long iova)
+{
+ __raw_writel((iova & PAGE_MASK) | 1, sfrbase + S5P_MMU_FLUSH_ENTRY);
+}
+
static void __sysmmu_set_ptbase(void __iomem *sfrbase,
unsigned long pgd)
{
@@ -322,6 +333,8 @@ void s5p_sysmmu_set_tablebase_pgd(struct device *owner, unsigned long pgd)
{
struct sysmmu_drvdata *mmudata = NULL;
+ s5p_sysmmu_tlb_invalidate(owner);
+
while ((mmudata = get_sysmmu_data(owner, mmudata))) {
unsigned long flags;
@@ -467,6 +480,35 @@ void s5p_sysmmu_tlb_invalidate(struct device *owner)
}
}
+void s5p_sysmmu_tlb_invalidate_entry(struct device *owner, unsigned long iova,
+ unsigned int count,
+ unsigned long page_size)
+{
+ struct sysmmu_drvdata *mmudata = NULL;
+
+ while ((mmudata = get_sysmmu_data(owner, mmudata))) {
+ unsigned long flags;
+
+ read_lock_irqsave(&mmudata->lock, flags);
+
+ if (is_sysmmu_active(mmudata)) {
+ while (count > 0) {
+ sysmmu_block(mmudata->sfrbase);
+ __sysmmu_tlb_invalidate_entry(mmudata->sfrbase,
+ iova);
+ sysmmu_unblock(mmudata->sfrbase);
+ count--;
+ iova += page_size;
+ }
+ } else {
+ dev_dbg(mmudata->dev,
+ "Disabled: Skipping invalidating TLB.\n");
+ }
+
+ read_unlock_irqrestore(&mmudata->lock, flags);
+ }
+}
+
static int s5p_sysmmu_probe(struct platform_device *pdev)
{
struct resource *res, *ioarea;