diff options
Diffstat (limited to 'arch/arm/mach-exynos/platsmp.c')
-rw-r--r-- | arch/arm/mach-exynos/platsmp.c | 34 |
1 files changed, 19 insertions, 15 deletions
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) | |||
90 | static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle) | 90 | static 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 | } |