[PATCH 1/5] ARM: EXYNOS: fix the hotplug for Cortex-A15
Lorenzo Pieralisi
lorenzo.pieralisi at arm.com
Tue Nov 6 08:55:02 EST 2012
On Tue, Nov 06, 2012 at 12:17:02PM +0000, Santosh Shilimkar wrote:
> On Tuesday 06 November 2012 12:12 AM, Abhilash Kesavan wrote:
> > The sequence of cpu_enter_lowpower() for Cortex-A15
> > is different from the sequence for Cortex-A9.
> Are you sure ? Apart from integrated cache vs external, there
> should be no change. And L2 doesn't need to come into picture
> while powering down just a CPU.
Reiterating Santosh point in here. v7 shutdown procedure is and has to
be identical across all v7 cores. There is not such a thing as "A15
specific" shutdown procedure.
Embedded L2 will come into the picture on multi-cluster systems, for the
time being L2 must not be flushed when hotplugging a CPU in a single cluster
so the LoUIS API is to be used here.
> > This patch implements cpu_enter_lowpower() for EXYNOS5
> > SoC which has Cortex-A15 cores.
> >
> > Signed-off-by: Changhwan Youn <chaos.youn at samsung.com>
> > Cc: Russell King <rmk+kernel at arm.linux.org.uk>
> > Signed-off-by: Kukjin Kim <kgene.kim at samsung.com>
> > Tested-by: Abhilash Kesavan <a.kesavan at samsung.com>
> > ---
> > arch/arm/mach-exynos/hotplug.c | 45 +++++++++++++++++++++++++++++++++++++--
> > 1 files changed, 42 insertions(+), 3 deletions(-)
> >
> > diff --git a/arch/arm/mach-exynos/hotplug.c b/arch/arm/mach-exynos/hotplug.c
> > index f4d7dd2..8c06c4f 100644
> > --- a/arch/arm/mach-exynos/hotplug.c
> > +++ b/arch/arm/mach-exynos/hotplug.c
> > @@ -20,10 +20,11 @@
> > #include <asm/smp_plat.h>
> >
> > #include <mach/regs-pmu.h>
> > +#include <plat/cpu.h>
> >
> > #include "common.h"
> >
> > -static inline void cpu_enter_lowpower(void)
> > +static inline void cpu_enter_lowpower_a9(void)
> > {
> > unsigned int v;
> >
> > @@ -45,6 +46,35 @@ static inline void cpu_enter_lowpower(void)
> > : "cc");
> > }
> >
> > +static inline void cpu_enter_lowpower_a15(void)
> > +{
> > + unsigned int v;
> > +
> > + asm volatile(
> > + " mrc p15, 0, %0, c1, c0, 0\n"
> > + " bic %0, %0, %1\n"
> > + " mcr p15, 0, %0, c1, c0, 0\n"
> > + : "=&r" (v)
> > + : "Ir" (CR_C)
> > + : "cc");
> > +
> > + flush_cache_all();
> > +
> Why are flushing all the cache levels ?
> flush_kern_louis() should be enough for CPU power
> down.
Agree with Santosh again.
>
> > + asm volatile(
> > + /*
> > + * Turn off coherency
> > + */
> > + " mrc p15, 0, %0, c1, c0, 1\n"
> > + " bic %0, %0, %1\n"
> > + " mcr p15, 0, %0, c1, c0, 1\n"
> > + : "=&r" (v)
> > + : "Ir" (0x40)
> > + : "cc");
> > +
> > + isb();
> > + dsb();
> > +}
> > +
> The above sequence should work on A9 as well. In general you should have
> CPU power down code under one code block and avoid making use of stack
> in between. Otherwise you will end up with stack corruption because of
> the memory view change after C bit is disabled.
>
> Regards
> Santosh
The above sequence does not work on A9 since A9 does not look-up the
caches when the C bit is cleared. It is an accident waiting to happen,
as Santosh explained.
The sequence:
- clear C bit
- clean L1
- exit SMP
must be written in assembly with no access to any data whatsoever, no stack,
_nothing_.
There is some code in the works to consolidate this procedure once for all but
all bits and pieces are already in the kernel.
Lorenzo
More information about the linux-arm-kernel
mailing list