summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-mx6/plat_hotplug.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/arch/arm/mach-mx6/plat_hotplug.c b/arch/arm/mach-mx6/plat_hotplug.c
index 67847655dc86..20a33329f472 100644
--- a/arch/arm/mach-mx6/plat_hotplug.c
+++ b/arch/arm/mach-mx6/plat_hotplug.c
@@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/smp.h>
+#include <linux/delay.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <linux/io.h>
@@ -27,12 +28,21 @@
#include <asm/cacheflush.h>
extern unsigned int num_cpu_idle_lock;
+void __iomem *src_base = IO_ADDRESS(SRC_BASE_ADDR);
int platform_cpu_kill(unsigned int cpu)
{
- void __iomem *src_base = IO_ADDRESS(SRC_BASE_ADDR);
unsigned int val;
+ val = jiffies;
+ /* wait secondary cpu to die, timeout is 50ms */
+ while (__raw_readl(src_base + SRC_GPR1_OFFSET + (8 * cpu) + 4) == 0) {
+ if (time_after(jiffies, (unsigned long)(val + HZ / 20))) {
+ printk(KERN_WARNING "cpu %d: cpu could not die\n", cpu);
+ break;
+ }
+ }
+
/*
* we're ready for shutdown now, so do it
*/
@@ -51,6 +61,7 @@ int platform_cpu_kill(unsigned int cpu)
}
}
+ __raw_writel(0x0, src_base + SRC_GPR1_OFFSET + (8 * cpu) + 4);
return 1;
}
@@ -81,12 +92,23 @@ void platform_cpu_die(unsigned int cpu)
: "=&r" (v)
: "r" (0), "Ir" (CR_C), "Ir" (0x40)
: "cc");
- /* tell cpu0 to kill me */
+ /* Tell cpu0 to kill this core, as this core's cache is
+ already disabled, and we want to set a flag to tell cpu0
+ to kill this core, so I write the flag to this core's SRC
+ parameter register, after cpu0 kill this core, it will
+ clear this register. */
+
+ __raw_writel(0x1, src_base + SRC_GPR1_OFFSET + (8 * cpu) + 4);
+
for (;;) {
/*
* Execute WFI
*/
- cpu_do_idle();
+ asm(".word 0xe320f003\n"
+ :
+ :
+ : "memory", "cc");
+ printk(KERN_ERR "cpu %d wake up from wfi !!!\n", cpu);
}
asm volatile(
" mrc p15, 0, %0, c1, c0, 0\n" /* Enable D cache in SCTLR */
@@ -98,6 +120,7 @@ void platform_cpu_die(unsigned int cpu)
: "=&r" (v)
: "Ir" (CR_C), "Ir" (0x40)
: "cc");
+ __raw_writel(0x0, src_base + SRC_GPR1_OFFSET + (8 * cpu) + 4);
}
int platform_cpu_disable(unsigned int cpu)