hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/arch/arm/mach-exynos/platsmp.c
....@@ -22,11 +22,12 @@
2222 #include <asm/smp_scu.h>
2323 #include <asm/firmware.h>
2424
25
-#include <mach/map.h>
26
-
2725 #include "common.h"
2826
2927 extern void exynos4_secondary_startup(void);
28
+
29
+/* XXX exynos_pen_release is cargo culted code - DO NOT COPY XXX */
30
+volatile int exynos_pen_release = -1;
3031
3132 #ifdef CONFIG_HOTPLUG_CPU
3233 static inline void cpu_leave_lowpower(u32 core_id)
....@@ -57,7 +58,7 @@
5758
5859 wfi();
5960
60
- if (pen_release == core_id) {
61
+ if (exynos_pen_release == core_id) {
6162 /*
6263 * OK, proper wakeup, we're done
6364 */
....@@ -185,7 +186,7 @@
185186
186187 static void __iomem *cpu_boot_reg_base(void)
187188 {
188
- if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1)
189
+ if (soc_is_exynos4210() && exynos_rev() == EXYNOS4210_REV_1_1)
189190 return pmu_base_addr + S5P_INFORM5;
190191 return sysram_base_addr;
191192 }
....@@ -211,13 +212,20 @@
211212 */
212213 void exynos_core_restart(u32 core_id)
213214 {
215
+ unsigned int timeout = 16;
214216 u32 val;
215217
216218 if (!of_machine_is_compatible("samsung,exynos3250"))
217219 return;
218220
219
- while (!pmu_raw_readl(S5P_PMU_SPARE2))
221
+ while (timeout && !pmu_raw_readl(S5P_PMU_SPARE2)) {
222
+ timeout--;
220223 udelay(10);
224
+ }
225
+ if (timeout == 0) {
226
+ pr_err("cpu core %u restart failed\n", core_id);
227
+ return;
228
+ }
221229 udelay(10);
222230
223231 val = pmu_raw_readl(EXYNOS_ARM_CORE_STATUS(core_id));
....@@ -228,18 +236,20 @@
228236 }
229237
230238 /*
231
- * Write pen_release in a way that is guaranteed to be visible to all
232
- * observers, irrespective of whether they're taking part in coherency
239
+ * XXX CARGO CULTED CODE - DO NOT COPY XXX
240
+ *
241
+ * Write exynos_pen_release in a way that is guaranteed to be visible to
242
+ * all observers, irrespective of whether they're taking part in coherency
233243 * or not. This is necessary for the hotplug code to work reliably.
234244 */
235
-static void write_pen_release(int val)
245
+static void exynos_write_pen_release(int val)
236246 {
237
- pen_release = val;
247
+ exynos_pen_release = val;
238248 smp_wmb();
239
- sync_cache_w(&pen_release);
249
+ sync_cache_w(&exynos_pen_release);
240250 }
241251
242
-static DEFINE_RAW_SPINLOCK(boot_lock);
252
+static DEFINE_SPINLOCK(boot_lock);
243253
244254 static void exynos_secondary_init(unsigned int cpu)
245255 {
....@@ -247,13 +257,13 @@
247257 * let the primary processor know we're out of the
248258 * pen, then head off into the C entry point
249259 */
250
- write_pen_release(-1);
260
+ exynos_write_pen_release(-1);
251261
252262 /*
253263 * Synchronise with the boot thread.
254264 */
255
- raw_spin_lock(&boot_lock);
256
- raw_spin_unlock(&boot_lock);
265
+ spin_lock(&boot_lock);
266
+ spin_unlock(&boot_lock);
257267 }
258268
259269 int exynos_set_boot_addr(u32 core_id, unsigned long boot_addr)
....@@ -317,17 +327,17 @@
317327 * Set synchronisation state between this boot processor
318328 * and the secondary one
319329 */
320
- raw_spin_lock(&boot_lock);
330
+ spin_lock(&boot_lock);
321331
322332 /*
323333 * The secondary processor is waiting to be released from
324334 * the holding pen - release it, then wait for it to flag
325
- * that it has been released by resetting pen_release.
335
+ * that it has been released by resetting exynos_pen_release.
326336 *
327
- * Note that "pen_release" is the hardware CPU core ID, whereas
337
+ * Note that "exynos_pen_release" is the hardware CPU core ID, whereas
328338 * "cpu" is Linux's internal ID.
329339 */
330
- write_pen_release(core_id);
340
+ exynos_write_pen_release(core_id);
331341
332342 if (!exynos_cpu_power_state(core_id)) {
333343 exynos_cpu_power_up(core_id);
....@@ -336,15 +346,15 @@
336346 /* wait max 10 ms until cpu1 is on */
337347 while (exynos_cpu_power_state(core_id)
338348 != S5P_CORE_LOCAL_PWR_EN) {
339
- if (timeout-- == 0)
349
+ if (timeout == 0)
340350 break;
341
-
351
+ timeout--;
342352 mdelay(1);
343353 }
344354
345355 if (timeout == 0) {
346356 printk(KERN_ERR "cpu1 power enable failed");
347
- raw_spin_unlock(&boot_lock);
357
+ spin_unlock(&boot_lock);
348358 return -ETIMEDOUT;
349359 }
350360 }
....@@ -376,13 +386,13 @@
376386 else
377387 arch_send_wakeup_ipi_mask(cpumask_of(cpu));
378388
379
- if (pen_release == -1)
389
+ if (exynos_pen_release == -1)
380390 break;
381391
382392 udelay(10);
383393 }
384394
385
- if (pen_release != -1)
395
+ if (exynos_pen_release != -1)
386396 ret = -ETIMEDOUT;
387397
388398 /*
....@@ -390,45 +400,19 @@
390400 * calibrations, then wait for it to finish
391401 */
392402 fail:
393
- raw_spin_unlock(&boot_lock);
403
+ spin_unlock(&boot_lock);
394404
395
- return pen_release != -1 ? ret : 0;
405
+ return exynos_pen_release != -1 ? ret : 0;
396406 }
397407
398408 static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
399409 {
400
- int i;
401
-
402410 exynos_sysram_init();
403411
404412 exynos_set_delayed_reset_assertion(true);
405413
406414 if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
407415 exynos_scu_enable();
408
-
409
- /*
410
- * Write the address of secondary startup into the
411
- * system-wide flags register. The boot monitor waits
412
- * until it receives a soft interrupt, and then the
413
- * secondary CPU branches to this address.
414
- *
415
- * Try using firmware operation first and fall back to
416
- * boot register if it fails.
417
- */
418
- for (i = 1; i < max_cpus; ++i) {
419
- unsigned long boot_addr;
420
- u32 mpidr;
421
- u32 core_id;
422
- int ret;
423
-
424
- mpidr = cpu_logical_map(i);
425
- core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
426
- boot_addr = __pa_symbol(exynos4_secondary_startup);
427
-
428
- ret = exynos_set_boot_addr(core_id, boot_addr);
429
- if (ret)
430
- break;
431
- }
432416 }
433417
434418 #ifdef CONFIG_HOTPLUG_CPU