From de284083666a483db01ae2708622822fb7cc184f Mon Sep 17 00:00:00 2001 From: Bastian Hecht Date: Wed, 9 Jan 2013 19:41:52 +0000 Subject: [PATCH] --- yaml --- r: 355503 b: refs/heads/master c: 20aa11358d52e1a3fc037d601ffe704e6f55c5fb h: refs/heads/master i: 355501: 141f86233eb6e9b33cb453382769f09f7fe09552 355499: 4049617e5ca1aaeac2e243ef581a95893cae7f82 355495: f33ad250c6d8835e344fb78fd13e0903b785c876 355487: 88cb43d61004f3aaad839de832256b9e8030e884 v: v3 --- [refs] | 2 +- trunk/arch/arm/mach-shmobile/smp-sh73a0.c | 36 +++++++++++++++++++---- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/[refs] b/[refs] index 1eebd3288dec..7b452408b3cc 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 33419a69a56436dda8e9187cf09ff0bde74d8a01 +refs/heads/master: 20aa11358d52e1a3fc037d601ffe704e6f55c5fb diff --git a/trunk/arch/arm/mach-shmobile/smp-sh73a0.c b/trunk/arch/arm/mach-shmobile/smp-sh73a0.c index 430b44ea85f2..9812ea3255c9 100644 --- a/trunk/arch/arm/mach-shmobile/smp-sh73a0.c +++ b/trunk/arch/arm/mach-shmobile/smp-sh73a0.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,8 @@ #define SBAR IOMEM(0xe6180020) #define APARMBAREA IOMEM(0xe6f10020) +#define PSTR_SHUTDOWN_MODE 3 + static void __iomem *scu_base_addr(void) { return (void __iomem *)0xf0000000; @@ -92,16 +95,20 @@ static void __init sh73a0_smp_init_cpus(void) shmobile_smp_init_cpus(ncores); } -static int __maybe_unused sh73a0_cpu_kill(unsigned int cpu) +#ifdef CONFIG_HOTPLUG_CPU +static int sh73a0_cpu_kill(unsigned int cpu) { + int k; + u32 pstr; - /* this function is running on another CPU than the offline target, - * here we need wait for shutdown code in platform_cpu_die() to - * finish before asking SoC-specific code to power off the CPU core. + /* + * wait until the power status register confirms the shutdown of the + * offline target */ for (k = 0; k < 1000; k++) { - if (shmobile_cpu_is_dead(cpu)) + pstr = (__raw_readl(PSTR) >> (4 * cpu)) & 3; + if (pstr == PSTR_SHUTDOWN_MODE) return 1; mdelay(1); @@ -110,6 +117,23 @@ static int __maybe_unused sh73a0_cpu_kill(unsigned int cpu) return 0; } +static void sh73a0_cpu_die(unsigned int cpu) +{ + /* + * The ARM MPcore does not issue a cache coherency request for the L1 + * cache when powering off single CPUs. We must take care of this and + * further caches. + */ + dsb(); + flush_cache_all(); + + /* Set power off mode. This takes the CPU out of the MP cluster */ + scu_power_mode(scu_base_addr(), SCU_PM_POWEROFF); + + /* Enter shutdown mode */ + cpu_do_idle(); +} +#endif /* CONFIG_HOTPLUG_CPU */ struct smp_operations sh73a0_smp_ops __initdata = { .smp_init_cpus = sh73a0_smp_init_cpus, @@ -118,7 +142,7 @@ struct smp_operations sh73a0_smp_ops __initdata = { .smp_boot_secondary = sh73a0_boot_secondary, #ifdef CONFIG_HOTPLUG_CPU .cpu_kill = sh73a0_cpu_kill, - .cpu_die = shmobile_cpu_die, + .cpu_die = sh73a0_cpu_die, .cpu_disable = shmobile_cpu_disable, #endif };