aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-highbank
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-highbank')
-rw-r--r--arch/arm/mach-highbank/highbank.c2
-rw-r--r--arch/arm/mach-highbank/hotplug.c2
-rw-r--r--arch/arm/mach-highbank/platsmp.c12
-rw-r--r--arch/arm/mach-highbank/pm.c19
-rw-r--r--arch/arm/mach-highbank/sysregs.h23
-rw-r--r--arch/arm/mach-highbank/system.c4
6 files changed, 42 insertions, 20 deletions
diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c
index dc248167d206..981dc1e1da51 100644
--- a/arch/arm/mach-highbank/highbank.c
+++ b/arch/arm/mach-highbank/highbank.c
@@ -135,7 +135,7 @@ static struct sys_timer highbank_timer = {
135 135
136static void highbank_power_off(void) 136static void highbank_power_off(void)
137{ 137{
138 hignbank_set_pwr_shutdown(); 138 highbank_set_pwr_shutdown();
139 139
140 while (1) 140 while (1)
141 cpu_do_idle(); 141 cpu_do_idle();
diff --git a/arch/arm/mach-highbank/hotplug.c b/arch/arm/mach-highbank/hotplug.c
index 7b60faccd551..f30c52843396 100644
--- a/arch/arm/mach-highbank/hotplug.c
+++ b/arch/arm/mach-highbank/hotplug.c
@@ -30,7 +30,7 @@ void __ref highbank_cpu_die(unsigned int cpu)
30{ 30{
31 flush_cache_all(); 31 flush_cache_all();
32 32
33 highbank_set_cpu_jump(cpu, secondary_startup); 33 highbank_set_cpu_jump(cpu, phys_to_virt(0));
34 highbank_set_core_pwr(); 34 highbank_set_core_pwr();
35 35
36 cpu_do_idle(); 36 cpu_do_idle();
diff --git a/arch/arm/mach-highbank/platsmp.c b/arch/arm/mach-highbank/platsmp.c
index 1129957f6c1d..4ecc864ac8b9 100644
--- a/arch/arm/mach-highbank/platsmp.c
+++ b/arch/arm/mach-highbank/platsmp.c
@@ -32,6 +32,7 @@ static void __cpuinit highbank_secondary_init(unsigned int cpu)
32 32
33static int __cpuinit highbank_boot_secondary(unsigned int cpu, struct task_struct *idle) 33static int __cpuinit highbank_boot_secondary(unsigned int cpu, struct task_struct *idle)
34{ 34{
35 highbank_set_cpu_jump(cpu, secondary_startup);
35 gic_raise_softirq(cpumask_of(cpu), 0); 36 gic_raise_softirq(cpumask_of(cpu), 0);
36 return 0; 37 return 0;
37} 38}
@@ -61,19 +62,8 @@ static void __init highbank_smp_init_cpus(void)
61 62
62static void __init highbank_smp_prepare_cpus(unsigned int max_cpus) 63static void __init highbank_smp_prepare_cpus(unsigned int max_cpus)
63{ 64{
64 int i;
65
66 if (scu_base_addr) 65 if (scu_base_addr)
67 scu_enable(scu_base_addr); 66 scu_enable(scu_base_addr);
68
69 /*
70 * Write the address of secondary startup into the jump table
71 * The cores are in wfi and wait until they receive a soft interrupt
72 * and a non-zero value to jump to. Then the secondary CPU branches
73 * to this address.
74 */
75 for (i = 1; i < max_cpus; i++)
76 highbank_set_cpu_jump(i, secondary_startup);
77} 67}
78 68
79struct smp_operations highbank_smp_ops __initdata = { 69struct smp_operations highbank_smp_ops __initdata = {
diff --git a/arch/arm/mach-highbank/pm.c b/arch/arm/mach-highbank/pm.c
index 74aa135966f0..04eddb4f4380 100644
--- a/arch/arm/mach-highbank/pm.c
+++ b/arch/arm/mach-highbank/pm.c
@@ -14,10 +14,12 @@
14 * this program. If not, see <http://www.gnu.org/licenses/>. 14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16 16
17#include <linux/cpu_pm.h>
17#include <linux/init.h> 18#include <linux/init.h>
18#include <linux/io.h> 19#include <linux/io.h>
19#include <linux/suspend.h> 20#include <linux/suspend.h>
20 21
22#include <asm/cacheflush.h>
21#include <asm/proc-fns.h> 23#include <asm/proc-fns.h>
22#include <asm/suspend.h> 24#include <asm/suspend.h>
23 25
@@ -26,16 +28,31 @@
26 28
27static int highbank_suspend_finish(unsigned long val) 29static int highbank_suspend_finish(unsigned long val)
28{ 30{
31 outer_flush_all();
32 outer_disable();
33
34 highbank_set_pwr_suspend();
35
29 cpu_do_idle(); 36 cpu_do_idle();
37
38 highbank_clear_pwr_request();
30 return 0; 39 return 0;
31} 40}
32 41
33static int highbank_pm_enter(suspend_state_t state) 42static int highbank_pm_enter(suspend_state_t state)
34{ 43{
35 hignbank_set_pwr_suspend(); 44 cpu_pm_enter();
45 cpu_cluster_pm_enter();
46
36 highbank_set_cpu_jump(0, cpu_resume); 47 highbank_set_cpu_jump(0, cpu_resume);
37 cpu_suspend(0, highbank_suspend_finish); 48 cpu_suspend(0, highbank_suspend_finish);
38 49
50 cpu_cluster_pm_exit();
51 cpu_pm_exit();
52
53 highbank_smc1(0x102, 0x1);
54 if (scu_base_addr)
55 scu_enable(scu_base_addr);
39 return 0; 56 return 0;
40} 57}
41 58
diff --git a/arch/arm/mach-highbank/sysregs.h b/arch/arm/mach-highbank/sysregs.h
index e13e8ea7c6cb..70af9d13fcef 100644
--- a/arch/arm/mach-highbank/sysregs.h
+++ b/arch/arm/mach-highbank/sysregs.h
@@ -44,28 +44,43 @@ static inline void highbank_set_core_pwr(void)
44 writel_relaxed(1, sregs_base + SREG_CPU_PWR_CTRL(cpu)); 44 writel_relaxed(1, sregs_base + SREG_CPU_PWR_CTRL(cpu));
45} 45}
46 46
47static inline void hignbank_set_pwr_suspend(void) 47static inline void highbank_clear_core_pwr(void)
48{
49 int cpu = cpu_logical_map(smp_processor_id());
50 if (scu_base_addr)
51 scu_power_mode(scu_base_addr, SCU_PM_NORMAL);
52 else
53 writel_relaxed(0, sregs_base + SREG_CPU_PWR_CTRL(cpu));
54}
55
56static inline void highbank_set_pwr_suspend(void)
48{ 57{
49 writel(HB_PWR_SUSPEND, sregs_base + HB_SREG_A9_PWR_REQ); 58 writel(HB_PWR_SUSPEND, sregs_base + HB_SREG_A9_PWR_REQ);
50 highbank_set_core_pwr(); 59 highbank_set_core_pwr();
51} 60}
52 61
53static inline void hignbank_set_pwr_shutdown(void) 62static inline void highbank_set_pwr_shutdown(void)
54{ 63{
55 writel(HB_PWR_SHUTDOWN, sregs_base + HB_SREG_A9_PWR_REQ); 64 writel(HB_PWR_SHUTDOWN, sregs_base + HB_SREG_A9_PWR_REQ);
56 highbank_set_core_pwr(); 65 highbank_set_core_pwr();
57} 66}
58 67
59static inline void hignbank_set_pwr_soft_reset(void) 68static inline void highbank_set_pwr_soft_reset(void)
60{ 69{
61 writel(HB_PWR_SOFT_RESET, sregs_base + HB_SREG_A9_PWR_REQ); 70 writel(HB_PWR_SOFT_RESET, sregs_base + HB_SREG_A9_PWR_REQ);
62 highbank_set_core_pwr(); 71 highbank_set_core_pwr();
63} 72}
64 73
65static inline void hignbank_set_pwr_hard_reset(void) 74static inline void highbank_set_pwr_hard_reset(void)
66{ 75{
67 writel(HB_PWR_HARD_RESET, sregs_base + HB_SREG_A9_PWR_REQ); 76 writel(HB_PWR_HARD_RESET, sregs_base + HB_SREG_A9_PWR_REQ);
68 highbank_set_core_pwr(); 77 highbank_set_core_pwr();
69} 78}
70 79
80static inline void highbank_clear_pwr_request(void)
81{
82 writel(~0UL, sregs_base + HB_SREG_A9_PWR_REQ);
83 highbank_clear_core_pwr();
84}
85
71#endif 86#endif
diff --git a/arch/arm/mach-highbank/system.c b/arch/arm/mach-highbank/system.c
index aed96ad9bd4a..37d8384dcf19 100644
--- a/arch/arm/mach-highbank/system.c
+++ b/arch/arm/mach-highbank/system.c
@@ -22,9 +22,9 @@
22void highbank_restart(char mode, const char *cmd) 22void highbank_restart(char mode, const char *cmd)
23{ 23{
24 if (mode == 'h') 24 if (mode == 'h')
25 hignbank_set_pwr_hard_reset(); 25 highbank_set_pwr_hard_reset();
26 else 26 else
27 hignbank_set_pwr_soft_reset(); 27 highbank_set_pwr_soft_reset();
28 28
29 while (1) 29 while (1)
30 cpu_do_idle(); 30 cpu_do_idle();