mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-12 05:24:12 +08:00
MIPS: kexec: CPS systems to halt nonboot CPUs
Share code between play_dead() and cps_kexec_nonboot_cpu(). Register the latter to mp_ops for kexec. Signed-off-by: Dengcheng Zhu <dzhu@wavecomp.com> Signed-off-by: Paul Burton <paul.burton@mips.com> Patchwork: https://patchwork.linux-mips.org/patch/20567/ Cc: pburton@wavecomp.com Cc: ralf@linux-mips.org Cc: linux-mips@linux-mips.org Cc: rachel.mozes@intel.com
This commit is contained in:
parent
62cac480f3
commit
1447864bee
@ -398,6 +398,55 @@ static void cps_smp_finish(void)
|
|||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_KEXEC)
|
||||||
|
|
||||||
|
enum cpu_death {
|
||||||
|
CPU_DEATH_HALT,
|
||||||
|
CPU_DEATH_POWER,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void cps_shutdown_this_cpu(enum cpu_death death)
|
||||||
|
{
|
||||||
|
unsigned int cpu, core, vpe_id;
|
||||||
|
|
||||||
|
cpu = smp_processor_id();
|
||||||
|
core = cpu_core(&cpu_data[cpu]);
|
||||||
|
|
||||||
|
if (death == CPU_DEATH_HALT) {
|
||||||
|
vpe_id = cpu_vpe_id(&cpu_data[cpu]);
|
||||||
|
|
||||||
|
pr_debug("Halting core %d VP%d\n", core, vpe_id);
|
||||||
|
if (cpu_has_mipsmt) {
|
||||||
|
/* Halt this TC */
|
||||||
|
write_c0_tchalt(TCHALT_H);
|
||||||
|
instruction_hazard();
|
||||||
|
} else if (cpu_has_vp) {
|
||||||
|
write_cpc_cl_vp_stop(1 << vpe_id);
|
||||||
|
|
||||||
|
/* Ensure that the VP_STOP register is written */
|
||||||
|
wmb();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pr_debug("Gating power to core %d\n", core);
|
||||||
|
/* Power down the core */
|
||||||
|
cps_pm_enter_state(CPS_PM_POWER_GATED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_KEXEC
|
||||||
|
|
||||||
|
static void cps_kexec_nonboot_cpu(void)
|
||||||
|
{
|
||||||
|
if (cpu_has_mipsmt || cpu_has_vp)
|
||||||
|
cps_shutdown_this_cpu(CPU_DEATH_HALT);
|
||||||
|
else
|
||||||
|
cps_shutdown_this_cpu(CPU_DEATH_POWER);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_KEXEC */
|
||||||
|
|
||||||
|
#endif /* CONFIG_HOTPLUG_CPU || CONFIG_KEXEC */
|
||||||
|
|
||||||
#ifdef CONFIG_HOTPLUG_CPU
|
#ifdef CONFIG_HOTPLUG_CPU
|
||||||
|
|
||||||
static int cps_cpu_disable(void)
|
static int cps_cpu_disable(void)
|
||||||
@ -421,19 +470,15 @@ static int cps_cpu_disable(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static unsigned cpu_death_sibling;
|
static unsigned cpu_death_sibling;
|
||||||
static enum {
|
static enum cpu_death cpu_death;
|
||||||
CPU_DEATH_HALT,
|
|
||||||
CPU_DEATH_POWER,
|
|
||||||
} cpu_death;
|
|
||||||
|
|
||||||
void play_dead(void)
|
void play_dead(void)
|
||||||
{
|
{
|
||||||
unsigned int cpu, core, vpe_id;
|
unsigned int cpu;
|
||||||
|
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
idle_task_exit();
|
idle_task_exit();
|
||||||
cpu = smp_processor_id();
|
cpu = smp_processor_id();
|
||||||
core = cpu_core(&cpu_data[cpu]);
|
|
||||||
cpu_death = CPU_DEATH_POWER;
|
cpu_death = CPU_DEATH_POWER;
|
||||||
|
|
||||||
pr_debug("CPU%d going offline\n", cpu);
|
pr_debug("CPU%d going offline\n", cpu);
|
||||||
@ -456,25 +501,7 @@ void play_dead(void)
|
|||||||
/* This CPU has chosen its way out */
|
/* This CPU has chosen its way out */
|
||||||
(void)cpu_report_death();
|
(void)cpu_report_death();
|
||||||
|
|
||||||
if (cpu_death == CPU_DEATH_HALT) {
|
cps_shutdown_this_cpu(cpu_death);
|
||||||
vpe_id = cpu_vpe_id(&cpu_data[cpu]);
|
|
||||||
|
|
||||||
pr_debug("Halting core %d VP%d\n", core, vpe_id);
|
|
||||||
if (cpu_has_mipsmt) {
|
|
||||||
/* Halt this TC */
|
|
||||||
write_c0_tchalt(TCHALT_H);
|
|
||||||
instruction_hazard();
|
|
||||||
} else if (cpu_has_vp) {
|
|
||||||
write_cpc_cl_vp_stop(1 << vpe_id);
|
|
||||||
|
|
||||||
/* Ensure that the VP_STOP register is written */
|
|
||||||
wmb();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pr_debug("Gating power to core %d\n", core);
|
|
||||||
/* Power down the core */
|
|
||||||
cps_pm_enter_state(CPS_PM_POWER_GATED);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This should never be reached */
|
/* This should never be reached */
|
||||||
panic("Failed to offline CPU %u", cpu);
|
panic("Failed to offline CPU %u", cpu);
|
||||||
@ -593,6 +620,9 @@ static const struct plat_smp_ops cps_smp_ops = {
|
|||||||
.cpu_disable = cps_cpu_disable,
|
.cpu_disable = cps_cpu_disable,
|
||||||
.cpu_die = cps_cpu_die,
|
.cpu_die = cps_cpu_die,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_KEXEC
|
||||||
|
.kexec_nonboot_cpu = cps_kexec_nonboot_cpu,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
bool mips_cps_smp_in_use(void)
|
bool mips_cps_smp_in_use(void)
|
||||||
|
Loading…
Reference in New Issue
Block a user