Santosh Shilimkar <santosh.shilimkar@xxxxxx> writes: > The SGI(Software Generated Interrupts) are not wakeup capable from > low power states. This is known limitation on OMAP4 and needs to be > worked around by using software forced clockdomain wake-up. CPU0 forces > the CPU1 clockdomain to software force wakeup. After the wakeup, CPU1 > restores its clockdomain hardware supervised mode. > > More details can be found in OMAP4430 TRM - Version J > Section : > 4.3.4.2 Power States of CPU0 and CPU1 > > Signed-off-by: Santosh Shilimkar <santosh.shilimkar@xxxxxx> > Reviewed-by: Kevin Hilman <khilman@xxxxxx> > --- > arch/arm/mach-omap2/omap-hotplug.c | 9 +++++++++ > arch/arm/mach-omap2/omap-smp.c | 27 ++++++++++++++++++++++++++- > 2 files changed, 35 insertions(+), 1 deletions(-) > > diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c > index 9f8f097..cf4ab15 100644 > --- a/arch/arm/mach-omap2/omap-hotplug.c > +++ b/arch/arm/mach-omap2/omap-hotplug.c > @@ -23,6 +23,7 @@ > #include <mach/omap-wakeupgen.h> > > #include "powerdomain.h" > +#include "clockdomain.h" > > int platform_cpu_kill(unsigned int cpu) > { > @@ -36,6 +37,11 @@ int platform_cpu_kill(unsigned int cpu) > void platform_cpu_die(unsigned int cpu) > { > unsigned int this_cpu; > + static struct clockdomain *cpu1_clkdm; > + > + /* To avoid cpu1 clockdomain lookup every time */ minor: comment doesn't really match code and could just be removed > + if (!cpu1_clkdm) > + cpu1_clkdm = clkdm_lookup("mpu1_clkdm"); > > flush_cache_all(); > dsb(); > @@ -59,6 +65,9 @@ void platform_cpu_die(unsigned int cpu) > * OK, proper wakeup, we're done > */ > omap_wakeupgen_irqmask_all(this_cpu, 0); > + > + /* Restore clockdomain to hardware supervised */ > + clkdm_allow_idle(cpu1_clkdm); > break; > } > pr_debug("CPU%u: spurious wakeup call\n", cpu); > diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c > index b105a29..31c9b79 100644 > --- a/arch/arm/mach-omap2/omap-smp.c > +++ b/arch/arm/mach-omap2/omap-smp.c > @@ -25,6 +25,8 @@ > #include <mach/hardware.h> > #include <mach/omap4-common.h> > > +#include "clockdomain.h" > + > /* SCU base address */ > void __iomem *scu_base; > > @@ -48,6 +50,8 @@ void __cpuinit platform_secondary_init(unsigned int cpu) > > int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) > { > + static struct clockdomain *cpu1_clkdm; > + static bool booted; > /* > * Set synchronisation state between this boot processor > * and the secondary one > @@ -63,7 +67,28 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) > omap_modify_auxcoreboot0(0x200, 0xfffffdff); > flush_cache_all(); > smp_wmb(); > - smp_cross_call(cpumask_of(cpu), 1); > + > + /* To avoid cpu1 clockdomain lookup every time */ ditto > + if (!cpu1_clkdm) > + cpu1_clkdm = clkdm_lookup("mpu1_clkdm"); > + > + /* > + * The SGI(Software Generated Interrupts) are not wakeup capable > + * from low power states. This is known limitation on OMAP4 and > + * needs to be worked around by using software forced clockdomain > + * wake-up. To wakeup CPU1, CPU0 forces the CPU1 clockdomain to > + * software force wakeup. After the wakeup, CPU1 restores its > + * clockdomain hardware supervised mode. > + * More details can be found in OMAP4430 TRM - Version J > + * Section : > + * 4.3.4.2 Power States of CPU0 and CPU1 > + */ > + if (booted) { > + clkdm_wakeup(cpu1_clkdm); > + } else { > + dsb_sev(); > + booted = true; > + } > > /* > * Now the secondary core is starting up let it run its -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html