aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/omap-hotplug.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/omap-hotplug.c')
-rw-r--r--arch/arm/mach-omap2/omap-hotplug.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c
index 4976b93..f69cd5c 100644
--- a/arch/arm/mach-omap2/omap-hotplug.c
+++ b/arch/arm/mach-omap2/omap-hotplug.c
@@ -19,7 +19,13 @@
#include <linux/smp.h>
#include <asm/cacheflush.h>
+#include <asm/hardware/gic.h>
+
#include <mach/omap4-common.h>
+#include <mach/omap-wakeupgen.h>
+
+#include "powerdomain.h"
+#include "clockdomain.h"
int platform_cpu_kill(unsigned int cpu)
{
@@ -32,6 +38,12 @@ int platform_cpu_kill(unsigned int cpu)
*/
void platform_cpu_die(unsigned int cpu)
{
+ unsigned int this_cpu;
+ static struct clockdomain *cpu1_clkdm;
+
+ if (!cpu1_clkdm)
+ cpu1_clkdm = clkdm_lookup("mpu1_clkdm");
+
flush_cache_all();
dsb();
@@ -39,18 +51,26 @@ void platform_cpu_die(unsigned int cpu)
* we're ready for shutdown now, so do it
*/
if (omap_modify_auxcoreboot0(0x0, 0x200) != 0x0)
- printk(KERN_CRIT "Secure clear status failed\n");
+ pr_err("Secure clear status failed\n");
for (;;) {
/*
- * Execute WFI
+ * Enter into low power state
+ * clear all interrupt wakeup sources
*/
- do_wfi();
-
- if (omap_read_auxcoreboot0() == cpu) {
+ omap_wakeupgen_irqmask_all(cpu, 1);
+ gic_cpu_disable();
+ omap4_enter_lowpower(cpu, PWRDM_POWER_OFF);
+ this_cpu = hard_smp_processor_id();
+ if (omap_read_auxcoreboot0() == this_cpu) {
/*
* OK, proper wakeup, we're done
*/
+ omap_wakeupgen_irqmask_all(this_cpu, 0);
+ gic_cpu_enable();
+
+ /* Restore clockdomain to hardware supervised */
+ clkdm_allow_idle(cpu1_clkdm);
break;
}
pr_debug("CPU%u: spurious wakeup call\n", cpu);