--- zzzz-none-000/linux-4.19.183/arch/arm64/kernel/smp_spin_table.c 2021-03-24 10:07:39.000000000 +0000 +++ bcm63-7530ax-756/linux-4.19.183/arch/arm64/kernel/smp_spin_table.c 2023-06-28 08:54:18.000000000 +0000 @@ -112,7 +112,138 @@ return 0; } +#if defined CONFIG_BCM_KF_ARM64_BCM963XX && defined CONFIG_HOTPLUG_CPU +extern void cpu_cache_off(void); +extern void flush_cache_all(void); + +# ifdef CONFIG_BCM94908 +# include "bcm_map_part.h" + +static int smp_spin_table_cpu_boot(unsigned int cpu) +{ + if (BIUCTRL->cpu_pwr_zone_ctrl[cpu] & BIU_CPU_CTRL_PWR_ZONE_CTRL_ZONE_RESET) { + BIUCTRL->power_cfg |= BIU_CPU_CTRL_PWR_CFG_CPU0_BPCM_INIT_ON << cpu; + BIUCTRL->cpu_pwr_zone_ctrl[cpu] = BIU_CPU_CTRL_PWR_ZONE_CTRL_PWR_UP_REQ | + (BIUCTRL->cpu_pwr_zone_ctrl[cpu] & ~BIU_CPU_CTRL_PWR_ZONE_CTRL_PWR_DN_REQ); + + udelay(100); // wait for cpu to come out of reset + } + + /* + * Update the pen release flag. + */ + write_pen_release(cpu_logical_map(cpu)); + + /* + * Send an event, causing the secondaries to read pen_release. + */ + sev(); + + return 0; +} + +static void smp_spin_table_cpu_die(unsigned int cpu) +{ + wmb(); + cpu_cache_off(); + flush_cache_all(); + + udelay(10); // delay after cache flush + + BIUCTRL->power_cfg &= ~(BIU_CPU_CTRL_PWR_CFG_CPU0_BPCM_INIT_ON << cpu); + BIUCTRL->cpu_pwr_zone_ctrl[cpu] = BIU_CPU_CTRL_PWR_ZONE_CTRL_PWR_DN_REQ | + (BIUCTRL->cpu_pwr_zone_ctrl[cpu] & ~BIU_CPU_CTRL_PWR_ZONE_CTRL_PWR_UP_REQ); + + while (1) cpu_do_idle(); + /*NOTREACHED*/ +} + +#define smp_spin_table_cpu_kill 0 + +# elif (defined (CONFIG_BCM96858) || defined(CONFIG_BCM963158)) +# if defined(CONFIG_BCM_PMC) +# include "pmc_cpu.h" + +static struct completion cpu_flush[NR_CPUS]; + + +static int smp_spin_table_cpu_boot(unsigned int cpu) +{ + int rc; + + rc = pmc_cpu_init(cpu); + if (rc == 0) + udelay(100); // wait for cpu to come out of reset + + /* + * Update the pen release flag. + */ + write_pen_release(cpu_logical_map(cpu)); + + /* + * Send an event, causing the secondaries to read pen_release. + */ + sev(); + + return 0; +} + +static void smp_spin_table_cpu_die(unsigned int cpu) +{ + init_completion(&cpu_flush[cpu]); + wmb(); + + //cpu_cache_off(); + flush_cache_all(); + + complete(&cpu_flush[cpu]); + wmb(); + + while (1) cpu_do_idle(); + + /*NOTREACHED*/ +} + +static int smp_spin_table_cpu_kill(unsigned int cpu) +{ + if (wait_for_completion_timeout(&cpu_flush[cpu], msecs_to_jiffies(10)) == 0) + return -1; + + udelay(10); // delay after cache flush + + return pmc_cpu_shutdown(cpu); +} + +# endif +#elif defined(CONFIG_BCM963146) || defined(CONFIG_BCM94912) || defined(CONFIG_BCM96813) + +static void smp_spin_table_cpu_die(unsigned int cpu) +{ +return; +} +static int smp_spin_table_cpu_kill(unsigned int cpu) +{ +return 0; +} +static int smp_spin_table_cpu_boot(unsigned int cpu) +{ + /* + * Update the pen release flag. + */ + write_pen_release(cpu_logical_map(cpu)); + + /* + * Send an event, causing the secondaries to read pen_release. + */ + sev(); + + return 0; +} + +#endif + +#else static int smp_spin_table_cpu_boot(unsigned int cpu) { /* @@ -127,10 +258,15 @@ return 0; } +#endif const struct cpu_operations smp_spin_table_ops = { .name = "spin-table", .cpu_init = smp_spin_table_cpu_init, .cpu_prepare = smp_spin_table_cpu_prepare, .cpu_boot = smp_spin_table_cpu_boot, +#if defined CONFIG_BCM_KF_ARM64_BCM963XX && defined CONFIG_HOTPLUG_CPU + .cpu_kill = smp_spin_table_cpu_kill, + .cpu_die = smp_spin_table_cpu_die, +#endif };