From 10ebd8556b7990499c896a550e3d416b444211e6 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Fri, 10 May 2024 02:23:07 +0000 Subject: [PATCH] add led --- kernel/arch/arm/mach-exynos/platsmp.c | 86 +++++++++++++++++------------------------- 1 files changed, 35 insertions(+), 51 deletions(-) diff --git a/kernel/arch/arm/mach-exynos/platsmp.c b/kernel/arch/arm/mach-exynos/platsmp.c index 17dca0f..d7fedbb 100644 --- a/kernel/arch/arm/mach-exynos/platsmp.c +++ b/kernel/arch/arm/mach-exynos/platsmp.c @@ -22,11 +22,12 @@ #include <asm/smp_scu.h> #include <asm/firmware.h> -#include <mach/map.h> - #include "common.h" extern void exynos4_secondary_startup(void); + +/* XXX exynos_pen_release is cargo culted code - DO NOT COPY XXX */ +volatile int exynos_pen_release = -1; #ifdef CONFIG_HOTPLUG_CPU static inline void cpu_leave_lowpower(u32 core_id) @@ -57,7 +58,7 @@ wfi(); - if (pen_release == core_id) { + if (exynos_pen_release == core_id) { /* * OK, proper wakeup, we're done */ @@ -185,7 +186,7 @@ static void __iomem *cpu_boot_reg_base(void) { - if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1) + if (soc_is_exynos4210() && exynos_rev() == EXYNOS4210_REV_1_1) return pmu_base_addr + S5P_INFORM5; return sysram_base_addr; } @@ -211,13 +212,20 @@ */ void exynos_core_restart(u32 core_id) { + unsigned int timeout = 16; u32 val; if (!of_machine_is_compatible("samsung,exynos3250")) return; - while (!pmu_raw_readl(S5P_PMU_SPARE2)) + while (timeout && !pmu_raw_readl(S5P_PMU_SPARE2)) { + timeout--; udelay(10); + } + if (timeout == 0) { + pr_err("cpu core %u restart failed\n", core_id); + return; + } udelay(10); val = pmu_raw_readl(EXYNOS_ARM_CORE_STATUS(core_id)); @@ -228,18 +236,20 @@ } /* - * Write pen_release in a way that is guaranteed to be visible to all - * observers, irrespective of whether they're taking part in coherency + * XXX CARGO CULTED CODE - DO NOT COPY XXX + * + * Write exynos_pen_release in a way that is guaranteed to be visible to + * all observers, irrespective of whether they're taking part in coherency * or not. This is necessary for the hotplug code to work reliably. */ -static void write_pen_release(int val) +static void exynos_write_pen_release(int val) { - pen_release = val; + exynos_pen_release = val; smp_wmb(); - sync_cache_w(&pen_release); + sync_cache_w(&exynos_pen_release); } -static DEFINE_RAW_SPINLOCK(boot_lock); +static DEFINE_SPINLOCK(boot_lock); static void exynos_secondary_init(unsigned int cpu) { @@ -247,13 +257,13 @@ * let the primary processor know we're out of the * pen, then head off into the C entry point */ - write_pen_release(-1); + exynos_write_pen_release(-1); /* * Synchronise with the boot thread. */ - raw_spin_lock(&boot_lock); - raw_spin_unlock(&boot_lock); + spin_lock(&boot_lock); + spin_unlock(&boot_lock); } int exynos_set_boot_addr(u32 core_id, unsigned long boot_addr) @@ -317,17 +327,17 @@ * Set synchronisation state between this boot processor * and the secondary one */ - raw_spin_lock(&boot_lock); + spin_lock(&boot_lock); /* * The secondary processor is waiting to be released from * the holding pen - release it, then wait for it to flag - * that it has been released by resetting pen_release. + * that it has been released by resetting exynos_pen_release. * - * Note that "pen_release" is the hardware CPU core ID, whereas + * Note that "exynos_pen_release" is the hardware CPU core ID, whereas * "cpu" is Linux's internal ID. */ - write_pen_release(core_id); + exynos_write_pen_release(core_id); if (!exynos_cpu_power_state(core_id)) { exynos_cpu_power_up(core_id); @@ -336,15 +346,15 @@ /* wait max 10 ms until cpu1 is on */ while (exynos_cpu_power_state(core_id) != S5P_CORE_LOCAL_PWR_EN) { - if (timeout-- == 0) + if (timeout == 0) break; - + timeout--; mdelay(1); } if (timeout == 0) { printk(KERN_ERR "cpu1 power enable failed"); - raw_spin_unlock(&boot_lock); + spin_unlock(&boot_lock); return -ETIMEDOUT; } } @@ -376,13 +386,13 @@ else arch_send_wakeup_ipi_mask(cpumask_of(cpu)); - if (pen_release == -1) + if (exynos_pen_release == -1) break; udelay(10); } - if (pen_release != -1) + if (exynos_pen_release != -1) ret = -ETIMEDOUT; /* @@ -390,45 +400,19 @@ * calibrations, then wait for it to finish */ fail: - raw_spin_unlock(&boot_lock); + spin_unlock(&boot_lock); - return pen_release != -1 ? ret : 0; + return exynos_pen_release != -1 ? ret : 0; } static void __init exynos_smp_prepare_cpus(unsigned int max_cpus) { - int i; - exynos_sysram_init(); exynos_set_delayed_reset_assertion(true); if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) exynos_scu_enable(); - - /* - * Write the address of secondary startup into the - * system-wide flags register. The boot monitor waits - * until it receives a soft interrupt, and then the - * secondary CPU branches to this address. - * - * Try using firmware operation first and fall back to - * boot register if it fails. - */ - for (i = 1; i < max_cpus; ++i) { - unsigned long boot_addr; - u32 mpidr; - u32 core_id; - int ret; - - mpidr = cpu_logical_map(i); - core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0); - boot_addr = __pa_symbol(exynos4_secondary_startup); - - ret = exynos_set_boot_addr(core_id, boot_addr); - if (ret) - break; - } } #ifdef CONFIG_HOTPLUG_CPU -- Gitblit v1.6.2