Skip to content

Commit

Permalink
MIPS: smp-cps: Add support for CPU hotplug of MIPSr6 processors
Browse files Browse the repository at this point in the history
Introduce support for hotplug of Virtual Processors in MIPSr6 systems.
The method is simpler than the VPE parallel from the now-deprecated MT
ASE, it can now simply write the VP_STOP register with the mask of VPs
to halt, and use the VP_RUNNING register to determine when the VP has
halted.

Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
Reviewed-by: Paul Burton <paul.burton@imgtec.com>
Cc: Matt Redfearn <matt.redfearn@imgtec.com>
Cc: Qais Yousef <qais.yousef@imgtec.com>
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/13752/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
  • Loading branch information
mpredfearn authored and ralfbaechle committed Jul 24, 2016
1 parent 9736c61 commit 0d2808f
Showing 1 changed file with 27 additions and 5 deletions.
32 changes: 27 additions & 5 deletions arch/mips/kernel/smp-cps.c
Original file line number Diff line number Diff line change
Expand Up @@ -412,14 +412,16 @@ static enum {

void play_dead(void)
{
unsigned cpu, core;
unsigned int cpu, core, vpe_id;

local_irq_disable();
idle_task_exit();
cpu = smp_processor_id();
cpu_death = CPU_DEATH_POWER;

if (cpu_has_mipsmt) {
pr_debug("CPU%d going offline\n", cpu);

if (cpu_has_mipsmt || cpu_has_vp) {
core = cpu_data[cpu].core;

/* Look for another online VPE within the core */
Expand All @@ -440,10 +442,21 @@ void play_dead(void)
complete(&cpu_death_chosen);

if (cpu_death == CPU_DEATH_HALT) {
/* Halt this TC */
write_c0_tchalt(TCHALT_H);
instruction_hazard();
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);
}
Expand All @@ -470,6 +483,7 @@ static void wait_for_sibling_halt(void *ptr_cpu)
static void cps_cpu_die(unsigned int cpu)
{
unsigned core = cpu_data[cpu].core;
unsigned int vpe_id = cpu_vpe_id(&cpu_data[cpu]);
unsigned stat;
int err;

Expand Down Expand Up @@ -498,10 +512,12 @@ static void cps_cpu_die(unsigned int cpu)
* in which case the CPC will refuse to power down the core.
*/
do {
mips_cm_lock_other(core, vpe_id);
mips_cpc_lock_other(core);
stat = read_cpc_co_stat_conf();
stat &= CPC_Cx_STAT_CONF_SEQSTATE_MSK;
mips_cpc_unlock_other();
mips_cm_unlock_other();
} while (stat != CPC_Cx_STAT_CONF_SEQSTATE_D0 &&
stat != CPC_Cx_STAT_CONF_SEQSTATE_D2 &&
stat != CPC_Cx_STAT_CONF_SEQSTATE_U2);
Expand All @@ -518,6 +534,12 @@ static void cps_cpu_die(unsigned int cpu)
(void *)(unsigned long)cpu, 1);
if (err)
panic("Failed to call remote sibling CPU\n");
} else if (cpu_has_vp) {
do {
mips_cm_lock_other(core, vpe_id);
stat = read_cpc_co_vp_running();
mips_cm_unlock_other();
} while (stat & (1 << vpe_id));
}
}

Expand Down

0 comments on commit 0d2808f

Please sign in to comment.