Loading arch/arm/mach-exynos/Makefile +0 −3 Original line number Diff line number Diff line Loading @@ -17,9 +17,6 @@ obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o CFLAGS_hotplug.o += -march=armv7-a plus_sec := $(call as-instr,.arch_extension sec,+sec) AFLAGS_exynos-smc.o :=-Wa,-march=armv7-a$(plus_sec) AFLAGS_sleep.o :=-Wa,-march=armv7-a$(plus_sec) Loading arch/arm/mach-exynos/common.h +0 −2 Original line number Diff line number Diff line Loading @@ -139,8 +139,6 @@ extern void exynos_cpu_resume_ns(void); extern struct smp_operations exynos_smp_ops; extern void exynos_cpu_die(unsigned int cpu); /* PMU(Power Management Unit) support */ #define PMU_TABLE_END (-1U) Loading arch/arm/mach-exynos/hotplug.cdeleted 100644 → 0 +0 −91 Original line number Diff line number Diff line /* * Cloned from linux/arch/arm/mach-realview/hotplug.c * * Copyright (C) 2002 ARM Ltd. * All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include <linux/kernel.h> #include <linux/errno.h> #include <linux/smp.h> #include <linux/io.h> #include <asm/cacheflush.h> #include <asm/cp15.h> #include <asm/smp_plat.h> #include "common.h" #include "regs-pmu.h" 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 inline void platform_do_lowpower(unsigned int cpu, int *spurious) { u32 mpidr = cpu_logical_map(cpu); u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0); for (;;) { /* Turn the CPU off on next WFI instruction. */ exynos_cpu_power_down(core_id); wfi(); if (pen_release == core_id) { /* * OK, proper wakeup, we're done */ break; } /* * Getting here, means that we have come out of WFI without * having been woken up - this shouldn't happen * * Just note it happening - when we're woken, we can report * its occurrence. */ (*spurious)++; } } /* * platform-specific code to shutdown a CPU * * Called with IRQs disabled */ void __ref exynos_cpu_die(unsigned int cpu) { int spurious = 0; v7_exit_coherency_flush(louis); platform_do_lowpower(cpu, &spurious); /* * bring this CPU back into the world of cache * coherency, and then restore interrupts */ cpu_leave_lowpower(); if (spurious) pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious); } arch/arm/mach-exynos/platsmp.c +113 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <linux/of_address.h> #include <asm/cacheflush.h> #include <asm/cp15.h> #include <asm/smp_plat.h> #include <asm/smp_scu.h> #include <asm/firmware.h> Loading @@ -33,6 +34,88 @@ extern void exynos4_secondary_startup(void); /* * Set or clear the USE_DELAYED_RESET_ASSERTION option, set on Exynos4 SoCs * during hot-(un)plugging CPUx. * * The feature can be cleared safely during first boot of secondary CPU. * * Exynos4 SoCs require setting USE_DELAYED_RESET_ASSERTION during powering * down a CPU so the CPU idle clock down feature could properly detect global * idle state when CPUx is off. */ static void exynos_set_delayed_reset_assertion(u32 core_id, bool enable) { if (soc_is_exynos4()) { unsigned int tmp; tmp = pmu_raw_readl(EXYNOS_ARM_CORE_OPTION(core_id)); if (enable) tmp |= S5P_USE_DELAYED_RESET_ASSERTION; else tmp &= ~(S5P_USE_DELAYED_RESET_ASSERTION); pmu_raw_writel(tmp, EXYNOS_ARM_CORE_OPTION(core_id)); } } #ifdef CONFIG_HOTPLUG_CPU static inline void cpu_leave_lowpower(u32 core_id) { 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"); exynos_set_delayed_reset_assertion(core_id, false); } static inline void platform_do_lowpower(unsigned int cpu, int *spurious) { u32 mpidr = cpu_logical_map(cpu); u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0); for (;;) { /* Turn the CPU off on next WFI instruction. */ exynos_cpu_power_down(core_id); /* * Exynos4 SoCs require setting * USE_DELAYED_RESET_ASSERTION so the CPU idle * clock down feature could properly detect * global idle state when CPUx is off. */ exynos_set_delayed_reset_assertion(core_id, true); wfi(); if (pen_release == core_id) { /* * OK, proper wakeup, we're done */ break; } /* * Getting here, means that we have come out of WFI without * having been woken up - this shouldn't happen * * Just note it happening - when we're woken, we can report * its occurrence. */ (*spurious)++; } } #endif /* CONFIG_HOTPLUG_CPU */ /** * exynos_core_power_down : power down the specified cpu * @cpu : the cpu to power down Loading Loading @@ -260,6 +343,9 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle) udelay(10); } /* No harm if this is called during first boot of secondary CPU */ exynos_set_delayed_reset_assertion(core_id, false); /* * now the secondary core is starting up let it run its * calibrations, then wait for it to finish Loading Loading @@ -341,6 +427,33 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus) } } #ifdef CONFIG_HOTPLUG_CPU /* * platform-specific code to shutdown a CPU * * Called with IRQs disabled */ static void exynos_cpu_die(unsigned int cpu) { int spurious = 0; u32 mpidr = cpu_logical_map(cpu); u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0); v7_exit_coherency_flush(louis); platform_do_lowpower(cpu, &spurious); /* * bring this CPU back into the world of cache * coherency, and then restore interrupts */ cpu_leave_lowpower(core_id); if (spurious) pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious); } #endif /* CONFIG_HOTPLUG_CPU */ struct smp_operations exynos_smp_ops __initdata = { .smp_init_cpus = exynos_smp_init_cpus, .smp_prepare_cpus = exynos_smp_prepare_cpus, Loading arch/arm/mach-exynos/regs-pmu.h +3 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #define S5P_USE_STANDBY_WFI0 (1 << 16) #define S5P_USE_STANDBY_WFE0 (1 << 24) #define S5P_USE_DELAYED_RESET_ASSERTION BIT(12) #define EXYNOS_CORE_PO_RESET(n) ((1 << 4) << n) #define EXYNOS_WAKEUP_FROM_LOWPWR (1 << 28) Loading Loading @@ -108,6 +109,8 @@ (EXYNOS_ARM_CORE0_CONFIGURATION + (0x80 * (_nr))) #define EXYNOS_ARM_CORE_STATUS(_nr) \ (EXYNOS_ARM_CORE_CONFIGURATION(_nr) + 0x4) #define EXYNOS_ARM_CORE_OPTION(_nr) \ (EXYNOS_ARM_CORE_CONFIGURATION(_nr) + 0x8) #define EXYNOS_ARM_COMMON_CONFIGURATION 0x2500 #define EXYNOS_COMMON_CONFIGURATION(_nr) \ Loading Loading
arch/arm/mach-exynos/Makefile +0 −3 Original line number Diff line number Diff line Loading @@ -17,9 +17,6 @@ obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o CFLAGS_hotplug.o += -march=armv7-a plus_sec := $(call as-instr,.arch_extension sec,+sec) AFLAGS_exynos-smc.o :=-Wa,-march=armv7-a$(plus_sec) AFLAGS_sleep.o :=-Wa,-march=armv7-a$(plus_sec) Loading
arch/arm/mach-exynos/common.h +0 −2 Original line number Diff line number Diff line Loading @@ -139,8 +139,6 @@ extern void exynos_cpu_resume_ns(void); extern struct smp_operations exynos_smp_ops; extern void exynos_cpu_die(unsigned int cpu); /* PMU(Power Management Unit) support */ #define PMU_TABLE_END (-1U) Loading
arch/arm/mach-exynos/hotplug.cdeleted 100644 → 0 +0 −91 Original line number Diff line number Diff line /* * Cloned from linux/arch/arm/mach-realview/hotplug.c * * Copyright (C) 2002 ARM Ltd. * All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include <linux/kernel.h> #include <linux/errno.h> #include <linux/smp.h> #include <linux/io.h> #include <asm/cacheflush.h> #include <asm/cp15.h> #include <asm/smp_plat.h> #include "common.h" #include "regs-pmu.h" 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 inline void platform_do_lowpower(unsigned int cpu, int *spurious) { u32 mpidr = cpu_logical_map(cpu); u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0); for (;;) { /* Turn the CPU off on next WFI instruction. */ exynos_cpu_power_down(core_id); wfi(); if (pen_release == core_id) { /* * OK, proper wakeup, we're done */ break; } /* * Getting here, means that we have come out of WFI without * having been woken up - this shouldn't happen * * Just note it happening - when we're woken, we can report * its occurrence. */ (*spurious)++; } } /* * platform-specific code to shutdown a CPU * * Called with IRQs disabled */ void __ref exynos_cpu_die(unsigned int cpu) { int spurious = 0; v7_exit_coherency_flush(louis); platform_do_lowpower(cpu, &spurious); /* * bring this CPU back into the world of cache * coherency, and then restore interrupts */ cpu_leave_lowpower(); if (spurious) pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious); }
arch/arm/mach-exynos/platsmp.c +113 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <linux/of_address.h> #include <asm/cacheflush.h> #include <asm/cp15.h> #include <asm/smp_plat.h> #include <asm/smp_scu.h> #include <asm/firmware.h> Loading @@ -33,6 +34,88 @@ extern void exynos4_secondary_startup(void); /* * Set or clear the USE_DELAYED_RESET_ASSERTION option, set on Exynos4 SoCs * during hot-(un)plugging CPUx. * * The feature can be cleared safely during first boot of secondary CPU. * * Exynos4 SoCs require setting USE_DELAYED_RESET_ASSERTION during powering * down a CPU so the CPU idle clock down feature could properly detect global * idle state when CPUx is off. */ static void exynos_set_delayed_reset_assertion(u32 core_id, bool enable) { if (soc_is_exynos4()) { unsigned int tmp; tmp = pmu_raw_readl(EXYNOS_ARM_CORE_OPTION(core_id)); if (enable) tmp |= S5P_USE_DELAYED_RESET_ASSERTION; else tmp &= ~(S5P_USE_DELAYED_RESET_ASSERTION); pmu_raw_writel(tmp, EXYNOS_ARM_CORE_OPTION(core_id)); } } #ifdef CONFIG_HOTPLUG_CPU static inline void cpu_leave_lowpower(u32 core_id) { 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"); exynos_set_delayed_reset_assertion(core_id, false); } static inline void platform_do_lowpower(unsigned int cpu, int *spurious) { u32 mpidr = cpu_logical_map(cpu); u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0); for (;;) { /* Turn the CPU off on next WFI instruction. */ exynos_cpu_power_down(core_id); /* * Exynos4 SoCs require setting * USE_DELAYED_RESET_ASSERTION so the CPU idle * clock down feature could properly detect * global idle state when CPUx is off. */ exynos_set_delayed_reset_assertion(core_id, true); wfi(); if (pen_release == core_id) { /* * OK, proper wakeup, we're done */ break; } /* * Getting here, means that we have come out of WFI without * having been woken up - this shouldn't happen * * Just note it happening - when we're woken, we can report * its occurrence. */ (*spurious)++; } } #endif /* CONFIG_HOTPLUG_CPU */ /** * exynos_core_power_down : power down the specified cpu * @cpu : the cpu to power down Loading Loading @@ -260,6 +343,9 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle) udelay(10); } /* No harm if this is called during first boot of secondary CPU */ exynos_set_delayed_reset_assertion(core_id, false); /* * now the secondary core is starting up let it run its * calibrations, then wait for it to finish Loading Loading @@ -341,6 +427,33 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus) } } #ifdef CONFIG_HOTPLUG_CPU /* * platform-specific code to shutdown a CPU * * Called with IRQs disabled */ static void exynos_cpu_die(unsigned int cpu) { int spurious = 0; u32 mpidr = cpu_logical_map(cpu); u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0); v7_exit_coherency_flush(louis); platform_do_lowpower(cpu, &spurious); /* * bring this CPU back into the world of cache * coherency, and then restore interrupts */ cpu_leave_lowpower(core_id); if (spurious) pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious); } #endif /* CONFIG_HOTPLUG_CPU */ struct smp_operations exynos_smp_ops __initdata = { .smp_init_cpus = exynos_smp_init_cpus, .smp_prepare_cpus = exynos_smp_prepare_cpus, Loading
arch/arm/mach-exynos/regs-pmu.h +3 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #define S5P_USE_STANDBY_WFI0 (1 << 16) #define S5P_USE_STANDBY_WFE0 (1 << 24) #define S5P_USE_DELAYED_RESET_ASSERTION BIT(12) #define EXYNOS_CORE_PO_RESET(n) ((1 << 4) << n) #define EXYNOS_WAKEUP_FROM_LOWPWR (1 << 28) Loading Loading @@ -108,6 +109,8 @@ (EXYNOS_ARM_CORE0_CONFIGURATION + (0x80 * (_nr))) #define EXYNOS_ARM_CORE_STATUS(_nr) \ (EXYNOS_ARM_CORE_CONFIGURATION(_nr) + 0x4) #define EXYNOS_ARM_CORE_OPTION(_nr) \ (EXYNOS_ARM_CORE_CONFIGURATION(_nr) + 0x8) #define EXYNOS_ARM_COMMON_CONFIGURATION 0x2500 #define EXYNOS_COMMON_CONFIGURATION(_nr) \ Loading