diff options
| -rw-r--r-- | arch/mips/include/asm/pm-cps.h | 6 | ||||
| -rw-r--r-- | arch/mips/kernel/pm-cps.c | 22 |
2 files changed, 22 insertions, 6 deletions
diff --git a/arch/mips/include/asm/pm-cps.h b/arch/mips/include/asm/pm-cps.h index 625eda53d571..89d58d80b77b 100644 --- a/arch/mips/include/asm/pm-cps.h +++ b/arch/mips/include/asm/pm-cps.h | |||
| @@ -13,10 +13,12 @@ | |||
| 13 | 13 | ||
| 14 | /* | 14 | /* |
| 15 | * The CM & CPC can only handle coherence & power control on a per-core basis, | 15 | * The CM & CPC can only handle coherence & power control on a per-core basis, |
| 16 | * thus in an MT system the VPEs within each core are coupled and can only | 16 | * thus in an MT system the VP(E)s within each core are coupled and can only |
| 17 | * enter or exit states requiring CM or CPC assistance in unison. | 17 | * enter or exit states requiring CM or CPC assistance in unison. |
| 18 | */ | 18 | */ |
| 19 | #ifdef CONFIG_MIPS_MT | 19 | #if defined(CONFIG_CPU_MIPSR6) |
| 20 | # define coupled_coherence cpu_has_vp | ||
| 21 | #elif defined(CONFIG_MIPS_MT) | ||
| 20 | # define coupled_coherence cpu_has_mipsmt | 22 | # define coupled_coherence cpu_has_mipsmt |
| 21 | #else | 23 | #else |
| 22 | # define coupled_coherence 0 | 24 | # define coupled_coherence 0 |
diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c index b3a7d36ada5a..440e79259566 100644 --- a/arch/mips/kernel/pm-cps.c +++ b/arch/mips/kernel/pm-cps.c | |||
| @@ -129,7 +129,7 @@ int cps_pm_enter_state(enum cps_pm_state state) | |||
| 129 | return -EINVAL; | 129 | return -EINVAL; |
| 130 | 130 | ||
| 131 | /* Calculate which coupled CPUs (VPEs) are online */ | 131 | /* Calculate which coupled CPUs (VPEs) are online */ |
| 132 | #ifdef CONFIG_MIPS_MT | 132 | #if defined(CONFIG_MIPS_MT) || defined(CONFIG_CPU_MIPSR6) |
| 133 | if (cpu_online(cpu)) { | 133 | if (cpu_online(cpu)) { |
| 134 | cpumask_and(coupled_mask, cpu_online_mask, | 134 | cpumask_and(coupled_mask, cpu_online_mask, |
| 135 | &cpu_sibling_map[cpu]); | 135 | &cpu_sibling_map[cpu]); |
| @@ -431,7 +431,8 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) | |||
| 431 | uasm_i_lw(&p, t0, 0, r_nc_count); | 431 | uasm_i_lw(&p, t0, 0, r_nc_count); |
| 432 | uasm_il_bltz(&p, &r, t0, lbl_secondary_cont); | 432 | uasm_il_bltz(&p, &r, t0, lbl_secondary_cont); |
| 433 | uasm_i_ehb(&p); | 433 | uasm_i_ehb(&p); |
| 434 | uasm_i_yield(&p, zero, t1); | 434 | if (cpu_has_mipsmt) |
| 435 | uasm_i_yield(&p, zero, t1); | ||
| 435 | uasm_il_b(&p, &r, lbl_poll_cont); | 436 | uasm_il_b(&p, &r, lbl_poll_cont); |
| 436 | uasm_i_nop(&p); | 437 | uasm_i_nop(&p); |
| 437 | } else { | 438 | } else { |
| @@ -439,8 +440,21 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) | |||
| 439 | * The core will lose power & this VPE will not continue | 440 | * The core will lose power & this VPE will not continue |
| 440 | * so it can simply halt here. | 441 | * so it can simply halt here. |
| 441 | */ | 442 | */ |
| 442 | uasm_i_addiu(&p, t0, zero, TCHALT_H); | 443 | if (cpu_has_mipsmt) { |
| 443 | uasm_i_mtc0(&p, t0, 2, 4); | 444 | /* Halt the VPE via C0 tchalt register */ |
| 445 | uasm_i_addiu(&p, t0, zero, TCHALT_H); | ||
| 446 | uasm_i_mtc0(&p, t0, 2, 4); | ||
| 447 | } else if (cpu_has_vp) { | ||
| 448 | /* Halt the VP via the CPC VP_STOP register */ | ||
| 449 | unsigned int vpe_id; | ||
| 450 | |||
| 451 | vpe_id = cpu_vpe_id(&cpu_data[cpu]); | ||
| 452 | uasm_i_addiu(&p, t0, zero, 1 << vpe_id); | ||
| 453 | UASM_i_LA(&p, t1, (long)addr_cpc_cl_vp_stop()); | ||
| 454 | uasm_i_sw(&p, t0, 0, t1); | ||
| 455 | } else { | ||
| 456 | BUG(); | ||
| 457 | } | ||
| 444 | uasm_build_label(&l, p, lbl_secondary_hang); | 458 | uasm_build_label(&l, p, lbl_secondary_hang); |
| 445 | uasm_il_b(&p, &r, lbl_secondary_hang); | 459 | uasm_il_b(&p, &r, lbl_secondary_hang); |
| 446 | uasm_i_nop(&p); | 460 | uasm_i_nop(&p); |
