|
|
@@ -23,7 +23,6 @@
|
|
|
#include <asm/smp_plat.h>
|
|
|
#include <asm/suspend.h>
|
|
|
#include "common.h"
|
|
|
-#include "platsmp-apmu.h"
|
|
|
#include "rcar-gen2.h"
|
|
|
|
|
|
static struct {
|
|
|
@@ -87,6 +86,104 @@ static int __maybe_unused apmu_wrap(int cpu, int (*fn)(void __iomem *p, int cpu)
|
|
|
return p ? fn(p, apmu_cpus[cpu].bit) : -EINVAL;
|
|
|
}
|
|
|
|
|
|
+#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_SUSPEND)
|
|
|
+/* nicked from arch/arm/mach-exynos/hotplug.c */
|
|
|
+static inline void cpu_enter_lowpower_a15(void)
|
|
|
+{
|
|
|
+ unsigned int v;
|
|
|
+
|
|
|
+ asm volatile(
|
|
|
+ " mrc p15, 0, %0, c1, c0, 0\n"
|
|
|
+ " bic %0, %0, %1\n"
|
|
|
+ " mcr p15, 0, %0, c1, c0, 0\n"
|
|
|
+ : "=&r" (v)
|
|
|
+ : "Ir" (CR_C)
|
|
|
+ : "cc");
|
|
|
+
|
|
|
+ flush_cache_louis();
|
|
|
+
|
|
|
+ asm volatile(
|
|
|
+ /*
|
|
|
+ * Turn off coherency
|
|
|
+ */
|
|
|
+ " mrc p15, 0, %0, c1, c0, 1\n"
|
|
|
+ " bic %0, %0, %1\n"
|
|
|
+ " mcr p15, 0, %0, c1, c0, 1\n"
|
|
|
+ : "=&r" (v)
|
|
|
+ : "Ir" (0x40)
|
|
|
+ : "cc");
|
|
|
+
|
|
|
+ isb();
|
|
|
+ dsb();
|
|
|
+}
|
|
|
+
|
|
|
+static void shmobile_smp_apmu_cpu_shutdown(unsigned int cpu)
|
|
|
+{
|
|
|
+
|
|
|
+ /* Select next sleep mode using the APMU */
|
|
|
+ apmu_wrap(cpu, apmu_power_off);
|
|
|
+
|
|
|
+ /* Do ARM specific CPU shutdown */
|
|
|
+ cpu_enter_lowpower_a15();
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
+#if defined(CONFIG_HOTPLUG_CPU)
|
|
|
+static void shmobile_smp_apmu_cpu_die(unsigned int cpu)
|
|
|
+{
|
|
|
+ /* For this particular CPU deregister boot vector */
|
|
|
+ shmobile_smp_hook(cpu, 0, 0);
|
|
|
+
|
|
|
+ /* Shutdown CPU core */
|
|
|
+ shmobile_smp_apmu_cpu_shutdown(cpu);
|
|
|
+
|
|
|
+ /* jump to shared mach-shmobile sleep / reset code */
|
|
|
+ shmobile_smp_sleep();
|
|
|
+}
|
|
|
+
|
|
|
+static int shmobile_smp_apmu_cpu_kill(unsigned int cpu)
|
|
|
+{
|
|
|
+ return apmu_wrap(cpu, apmu_power_off_poll);
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
+#if defined(CONFIG_SUSPEND)
|
|
|
+static int shmobile_smp_apmu_do_suspend(unsigned long cpu)
|
|
|
+{
|
|
|
+ shmobile_smp_hook(cpu, __pa_symbol(cpu_resume), 0);
|
|
|
+ shmobile_smp_apmu_cpu_shutdown(cpu);
|
|
|
+ cpu_do_idle(); /* WFI selects Core Standby */
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+static inline void cpu_leave_lowpower(void)
|
|
|
+{
|
|
|
+ unsigned int v;
|
|
|
+
|
|
|
+ asm volatile("mrc p15, 0, %0, c1, c0, 0\n"
|
|
|
+ " orr %0, %0, %1\n"
|
|
|
+ " mcr p15, 0, %0, c1, c0, 0\n"
|
|
|
+ " mrc p15, 0, %0, c1, c0, 1\n"
|
|
|
+ " orr %0, %0, %2\n"
|
|
|
+ " mcr p15, 0, %0, c1, c0, 1\n"
|
|
|
+ : "=&r" (v)
|
|
|
+ : "Ir" (CR_C), "Ir" (0x40)
|
|
|
+ : "cc");
|
|
|
+}
|
|
|
+
|
|
|
+static int shmobile_smp_apmu_enter_suspend(suspend_state_t state)
|
|
|
+{
|
|
|
+ cpu_suspend(smp_processor_id(), shmobile_smp_apmu_do_suspend);
|
|
|
+ cpu_leave_lowpower();
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+void __init shmobile_smp_apmu_suspend_init(void)
|
|
|
+{
|
|
|
+ shmobile_suspend_ops.enter = shmobile_smp_apmu_enter_suspend;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
#ifdef CONFIG_SMP
|
|
|
static void apmu_init_cpu(struct resource *res, int cpu, int bit)
|
|
|
{
|
|
|
@@ -162,7 +259,8 @@ static void __init shmobile_smp_apmu_setup_boot(void)
|
|
|
shmobile_boot_fn_gen2 = shmobile_boot_fn;
|
|
|
}
|
|
|
|
|
|
-int shmobile_smp_apmu_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
|
|
+static int shmobile_smp_apmu_boot_secondary(unsigned int cpu,
|
|
|
+ struct task_struct *idle)
|
|
|
{
|
|
|
/* For this particular CPU register boot vector */
|
|
|
shmobile_smp_hook(cpu, __pa_symbol(shmobile_boot_apmu), 0);
|
|
|
@@ -189,101 +287,3 @@ static struct smp_operations apmu_smp_ops __initdata = {
|
|
|
|
|
|
CPU_METHOD_OF_DECLARE(shmobile_smp_apmu, "renesas,apmu", &apmu_smp_ops);
|
|
|
#endif /* CONFIG_SMP */
|
|
|
-
|
|
|
-#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_SUSPEND)
|
|
|
-/* nicked from arch/arm/mach-exynos/hotplug.c */
|
|
|
-static inline void cpu_enter_lowpower_a15(void)
|
|
|
-{
|
|
|
- unsigned int v;
|
|
|
-
|
|
|
- asm volatile(
|
|
|
- " mrc p15, 0, %0, c1, c0, 0\n"
|
|
|
- " bic %0, %0, %1\n"
|
|
|
- " mcr p15, 0, %0, c1, c0, 0\n"
|
|
|
- : "=&r" (v)
|
|
|
- : "Ir" (CR_C)
|
|
|
- : "cc");
|
|
|
-
|
|
|
- flush_cache_louis();
|
|
|
-
|
|
|
- asm volatile(
|
|
|
- /*
|
|
|
- * Turn off coherency
|
|
|
- */
|
|
|
- " mrc p15, 0, %0, c1, c0, 1\n"
|
|
|
- " bic %0, %0, %1\n"
|
|
|
- " mcr p15, 0, %0, c1, c0, 1\n"
|
|
|
- : "=&r" (v)
|
|
|
- : "Ir" (0x40)
|
|
|
- : "cc");
|
|
|
-
|
|
|
- isb();
|
|
|
- dsb();
|
|
|
-}
|
|
|
-
|
|
|
-static void shmobile_smp_apmu_cpu_shutdown(unsigned int cpu)
|
|
|
-{
|
|
|
-
|
|
|
- /* Select next sleep mode using the APMU */
|
|
|
- apmu_wrap(cpu, apmu_power_off);
|
|
|
-
|
|
|
- /* Do ARM specific CPU shutdown */
|
|
|
- cpu_enter_lowpower_a15();
|
|
|
-}
|
|
|
-#endif
|
|
|
-
|
|
|
-#if defined(CONFIG_HOTPLUG_CPU)
|
|
|
-void shmobile_smp_apmu_cpu_die(unsigned int cpu)
|
|
|
-{
|
|
|
- /* For this particular CPU deregister boot vector */
|
|
|
- shmobile_smp_hook(cpu, 0, 0);
|
|
|
-
|
|
|
- /* Shutdown CPU core */
|
|
|
- shmobile_smp_apmu_cpu_shutdown(cpu);
|
|
|
-
|
|
|
- /* jump to shared mach-shmobile sleep / reset code */
|
|
|
- shmobile_smp_sleep();
|
|
|
-}
|
|
|
-
|
|
|
-int shmobile_smp_apmu_cpu_kill(unsigned int cpu)
|
|
|
-{
|
|
|
- return apmu_wrap(cpu, apmu_power_off_poll);
|
|
|
-}
|
|
|
-#endif
|
|
|
-
|
|
|
-#if defined(CONFIG_SUSPEND)
|
|
|
-static int shmobile_smp_apmu_do_suspend(unsigned long cpu)
|
|
|
-{
|
|
|
- shmobile_smp_hook(cpu, __pa_symbol(cpu_resume), 0);
|
|
|
- shmobile_smp_apmu_cpu_shutdown(cpu);
|
|
|
- cpu_do_idle(); /* WFI selects Core Standby */
|
|
|
- return 1;
|
|
|
-}
|
|
|
-
|
|
|
-static inline void cpu_leave_lowpower(void)
|
|
|
-{
|
|
|
- unsigned int v;
|
|
|
-
|
|
|
- asm volatile("mrc p15, 0, %0, c1, c0, 0\n"
|
|
|
- " orr %0, %0, %1\n"
|
|
|
- " mcr p15, 0, %0, c1, c0, 0\n"
|
|
|
- " mrc p15, 0, %0, c1, c0, 1\n"
|
|
|
- " orr %0, %0, %2\n"
|
|
|
- " mcr p15, 0, %0, c1, c0, 1\n"
|
|
|
- : "=&r" (v)
|
|
|
- : "Ir" (CR_C), "Ir" (0x40)
|
|
|
- : "cc");
|
|
|
-}
|
|
|
-
|
|
|
-static int shmobile_smp_apmu_enter_suspend(suspend_state_t state)
|
|
|
-{
|
|
|
- cpu_suspend(smp_processor_id(), shmobile_smp_apmu_do_suspend);
|
|
|
- cpu_leave_lowpower();
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-void __init shmobile_smp_apmu_suspend_init(void)
|
|
|
-{
|
|
|
- shmobile_suspend_ops.enter = shmobile_smp_apmu_enter_suspend;
|
|
|
-}
|
|
|
-#endif
|