aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-exynos
diff options
context:
space:
mode:
authorTomasz Figa <t.figa@samsung.com>2014-07-15 13:59:18 -0400
committerOlof Johansson <olof@lixom.net>2014-07-18 20:12:57 -0400
commit9637f30e6b7bc394c08fa9d27d63622f141142e9 (patch)
treec74803fdc530a45f1045154c5d5bf841545485ed /arch/arm/mach-exynos
parente5c6cac6e3977d1add2f64a0b1c6565fa4c94429 (diff)
ARM: EXYNOS: Fix core ID used by platsmp and hotplug code
When CPU topology is specified in device tree, cpu_logical_map() does not return core ID anymore, but rather full MPIDR value. This breaks existing calculation of PMU register offsets on Exynos SoCs. This patch fixes the problem by adjusting the code to use only core ID bits of the value returned by cpu_logical_map() to allow CPU topology to be specified in device tree on Exynos SoCs. Signed-off-by: Tomasz Figa <t.figa@samsung.com> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com> Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'arch/arm/mach-exynos')
-rw-r--r--arch/arm/mach-exynos/hotplug.c10
-rw-r--r--arch/arm/mach-exynos/platsmp.c34
2 files changed, 25 insertions, 19 deletions
diff --git a/arch/arm/mach-exynos/hotplug.c b/arch/arm/mach-exynos/hotplug.c
index 8a134d019cb3..920a4baa53cd 100644
--- a/arch/arm/mach-exynos/hotplug.c
+++ b/arch/arm/mach-exynos/hotplug.c
@@ -40,15 +40,17 @@ static inline void cpu_leave_lowpower(void)
40 40
41static inline void platform_do_lowpower(unsigned int cpu, int *spurious) 41static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
42{ 42{
43 u32 mpidr = cpu_logical_map(cpu);
44 u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
45
43 for (;;) { 46 for (;;) {
44 47
45 /* make cpu1 to be turned off at next WFI command */ 48 /* Turn the CPU off on next WFI instruction. */
46 if (cpu == 1) 49 exynos_cpu_power_down(core_id);
47 exynos_cpu_power_down(cpu);
48 50
49 wfi(); 51 wfi();
50 52
51 if (pen_release == cpu_logical_map(cpu)) { 53 if (pen_release == core_id) {
52 /* 54 /*
53 * OK, proper wakeup, we're done 55 * OK, proper wakeup, we're done
54 */ 56 */
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index 1c8d31e39520..50b9aad5e27b 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -90,7 +90,8 @@ static void exynos_secondary_init(unsigned int cpu)
90static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle) 90static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
91{ 91{
92 unsigned long timeout; 92 unsigned long timeout;
93 unsigned long phys_cpu = cpu_logical_map(cpu); 93 u32 mpidr = cpu_logical_map(cpu);
94 u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
94 int ret = -ENOSYS; 95 int ret = -ENOSYS;
95 96
96 /* 97 /*
@@ -104,17 +105,18 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
104 * the holding pen - release it, then wait for it to flag 105 * the holding pen - release it, then wait for it to flag
105 * that it has been released by resetting pen_release. 106 * that it has been released by resetting pen_release.
106 * 107 *
107 * Note that "pen_release" is the hardware CPU ID, whereas 108 * Note that "pen_release" is the hardware CPU core ID, whereas
108 * "cpu" is Linux's internal ID. 109 * "cpu" is Linux's internal ID.
109 */ 110 */
110 write_pen_release(phys_cpu); 111 write_pen_release(core_id);
111 112
112 if (!exynos_cpu_power_state(cpu)) { 113 if (!exynos_cpu_power_state(core_id)) {
113 exynos_cpu_power_up(cpu); 114 exynos_cpu_power_up(core_id);
114 timeout = 10; 115 timeout = 10;
115 116
116 /* wait max 10 ms until cpu1 is on */ 117 /* wait max 10 ms until cpu1 is on */
117 while (exynos_cpu_power_state(cpu) != S5P_CORE_LOCAL_PWR_EN) { 118 while (exynos_cpu_power_state(core_id)
119 != S5P_CORE_LOCAL_PWR_EN) {
118 if (timeout-- == 0) 120 if (timeout-- == 0)
119 break; 121 break;
120 122
@@ -145,20 +147,20 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
145 * Try to set boot address using firmware first 147 * Try to set boot address using firmware first
146 * and fall back to boot register if it fails. 148 * and fall back to boot register if it fails.
147 */ 149 */
148 ret = call_firmware_op(set_cpu_boot_addr, phys_cpu, boot_addr); 150 ret = call_firmware_op(set_cpu_boot_addr, core_id, boot_addr);
149 if (ret && ret != -ENOSYS) 151 if (ret && ret != -ENOSYS)
150 goto fail; 152 goto fail;
151 if (ret == -ENOSYS) { 153 if (ret == -ENOSYS) {
152 void __iomem *boot_reg = cpu_boot_reg(phys_cpu); 154 void __iomem *boot_reg = cpu_boot_reg(core_id);
153 155
154 if (IS_ERR(boot_reg)) { 156 if (IS_ERR(boot_reg)) {
155 ret = PTR_ERR(boot_reg); 157 ret = PTR_ERR(boot_reg);
156 goto fail; 158 goto fail;
157 } 159 }
158 __raw_writel(boot_addr, cpu_boot_reg(phys_cpu)); 160 __raw_writel(boot_addr, cpu_boot_reg(core_id));
159 } 161 }
160 162
161 call_firmware_op(cpu_boot, phys_cpu); 163 call_firmware_op(cpu_boot, core_id);
162 164
163 arch_send_wakeup_ipi_mask(cpumask_of(cpu)); 165 arch_send_wakeup_ipi_mask(cpumask_of(cpu));
164 166
@@ -227,22 +229,24 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
227 * boot register if it fails. 229 * boot register if it fails.
228 */ 230 */
229 for (i = 1; i < max_cpus; ++i) { 231 for (i = 1; i < max_cpus; ++i) {
230 unsigned long phys_cpu;
231 unsigned long boot_addr; 232 unsigned long boot_addr;
233 u32 mpidr;
234 u32 core_id;
232 int ret; 235 int ret;
233 236
234 phys_cpu = cpu_logical_map(i); 237 mpidr = cpu_logical_map(i);
238 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
235 boot_addr = virt_to_phys(exynos4_secondary_startup); 239 boot_addr = virt_to_phys(exynos4_secondary_startup);
236 240
237 ret = call_firmware_op(set_cpu_boot_addr, phys_cpu, boot_addr); 241 ret = call_firmware_op(set_cpu_boot_addr, core_id, boot_addr);
238 if (ret && ret != -ENOSYS) 242 if (ret && ret != -ENOSYS)
239 break; 243 break;
240 if (ret == -ENOSYS) { 244 if (ret == -ENOSYS) {
241 void __iomem *boot_reg = cpu_boot_reg(phys_cpu); 245 void __iomem *boot_reg = cpu_boot_reg(core_id);
242 246
243 if (IS_ERR(boot_reg)) 247 if (IS_ERR(boot_reg))
244 break; 248 break;
245 __raw_writel(boot_addr, cpu_boot_reg(phys_cpu)); 249 __raw_writel(boot_addr, cpu_boot_reg(core_id));
246 } 250 }
247 } 251 }
248} 252}