Subject: [PATCH 1/2] mach-ux500: cache operations are atomic on PL310

From: [email-masked] (Srinidhi KASAGAR)
Date: Tue, 17 Jan 2012 16:57:43 +0530

On Tue, Jan 17, 2012 at 11:30:23 +0100, Will Deacon wrote:
> Hi Srinidhi,
> 
> On Tue, Jan 17, 2012 at 06:22:26AM +0000, Srinidhi KASAGAR wrote:
> > On Mon, Jan 16, 2012 at 15:50:08 +0100, Will Deacon wrote:
> > > The lock needs to stay. Besides, the problem isn't with inv_all, the problem
> > > is with not being able to disable the outer cache. So can't you just do
> > > something nasty like:
> > > 
> > > 	outer_cache.disable = NULL;
> > > 
> > > after your call to l2x0_init?
> > 
> > hmm..patch below
> 
> Thanks. Comments inline.
> 
> > > 
> > > Also, if you can't disable the L2 from non-secure, does that mean that you
> > > boot Linux with the L2 enabled?
> > 
> > Yes, we boot with L2 enabled.
> 
> Interesting. I'm surprised you don't have problems with stale data on the
> D-side after the decompressor. Maybe you're lucky with the mappings being no
> write allocate.

Actually the pre bootloader makes sure that L2 is clean before relinquishing
the control to kernel decompressor.

> 
> > From 46fdbda7d2d9a9f4df0933341bcc467b3bdd03d6 Mon Sep 17 00:00:00 2001
> > From: srinidhi kasagar <[email-masked]>
> > Date: Tue, 17 Jan 2012 11:29:39 +0530
> > Subject: [PATCH] mach-ux500: Do not override outer.inv_all
> > 
> > outer.inv_all is currently being used only in kexec path.
> > Invalidating outer cache without disabling it is a big
> > nono, and so, remove the machine specific outer.inv_all
> > assuming that kexec does not call inv_all in its path.
> 
> Please change this comment. Kexec doesn't do this anymore.

Done, patch below.

>>From a8cf7e2f7b58c3ef860be58fa72cd0c51e2be487 Mon Sep 17 00:00:00 2001
From: srinidhi kasagar <[email-masked]>
Date: Tue, 17 Jan 2012 11:29:39 +0530
Subject: [PATCH] mach-ux500: Do not override outer.inv_all

Invalidating outer cache without disabling it is a big
nono, and so, remove the machine specific outer.inv_all

And at the same time it does not prevent us overriding
outer.disable as we do not have any such secure SMI to
handle the same while kexec disables the outer cache.

Signed-off-by: srinidhi kasagar <[email-masked]>
---
 arch/arm/mach-ux500/cache-l2x0.c |   48 +++++--------------------------------
 1 files changed, 7 insertions(+), 41 deletions(-)

diff --git a/arch/arm/mach-ux500/cache-l2x0.c b/arch/arm/mach-ux500/cache-l2x0.c
index 122ddde..45111c8 100644
--- a/arch/arm/mach-ux500/cache-l2x0.c
+++ b/arch/arm/mach-ux500/cache-l2x0.c
@@ -12,44 +12,6 @@
 
 static void __iomem *l2x0_base;
 
-static inline void ux500_cache_wait(void __iomem *reg, unsigned long mask)
-{
-	/* wait for the operation to complete */
-	while (readl_relaxed(reg) & mask)
-		cpu_relax();
-}
-
-static inline void ux500_cache_sync(void)
-{
-	writel_relaxed(0, l2x0_base + L2X0_CACHE_SYNC);
-	ux500_cache_wait(l2x0_base + L2X0_CACHE_SYNC, 1);
-}
-
-/*
- * The L2 cache cannot be turned off in the non-secure world.
- * Dummy until a secure service is in place.
- */
-static void ux500_l2x0_disable(void)
-{
-}
-
-/*
- * This is only called when doing a kexec, just after turning off the L2
- * and L1 cache, and it is surrounded by a spinlock in the generic version.
- * However, we're not really turning off the L2 cache right now and the
- * PL310 does not support exclusive accesses (used to implement the spinlock).
- * So, the invalidation needs to be done without the spinlock.
- */
-static void ux500_l2x0_inv_all(void)
-{
-	uint32_t l2x0_way_mask = (1<<16) - 1;	/* Bitmask of active ways */
-
-	/* invalidate all ways */
-	writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
-	ux500_cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
-	ux500_cache_sync();
-}
-
 static int __init ux500_l2x0_unlock(void)
 {
 	int i;
@@ -85,9 +47,13 @@ static int __init ux500_l2x0_init(void)
 	/* 64KB way size, 8 way associativity, force WA */
 	l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff);
 
-	/* Override invalidate function */
-	outer_cache.disable = ux500_l2x0_disable;
-	outer_cache.inv_all = ux500_l2x0_inv_all;
+	/*
+	 * We can't disable l2 as we are in non secure mode, currently
+	 * this seems being called only during kexec path. So let's
+	 * override outer.disable with nasty assignment until we have
+	 * some SMI service available.
+	 */
+	outer_cache.disable = NULL;
 
 	return 0;
 }
-- 
1.7.4.3