aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorPaul Burton <paul.burton@imgtec.com>2014-04-14 11:25:29 -0400
committerPaul Burton <paul.burton@imgtec.com>2014-05-28 11:20:36 -0400
commitd050894435cdc78807e714a0148527542a583e87 (patch)
tree39f95ee57dbe42e78945365e2b166161a24cc804 /arch/mips
parentf08dbf8a61462aa122b9b5077849a3f4bd84702a (diff)
cpuidle: cpuidle-cps: add MIPS CPS cpuidle driver
This patch adds a cpuidle driver for systems based around the MIPS Coherent Processing System (CPS) architecture. It supports four idle states: - The standard MIPS wait instruction. - The non-coherent wait, clock gated & power gated states exposed by the recently added pm-cps layer. The pm-cps layer is used to enter all the deep idle states. Since cores in the clock or power gated states cannot service interrupts, the gic_send_ipi_single function is modified to send a power up command for the appropriate core to the CPC in cases where the target CPU has marked itself potentially incoherent. Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/kernel/smp-gic.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/arch/mips/kernel/smp-gic.c b/arch/mips/kernel/smp-gic.c
index 3bb1f92ab525..3b21a96d1ccb 100644
--- a/arch/mips/kernel/smp-gic.c
+++ b/arch/mips/kernel/smp-gic.c
@@ -15,12 +15,14 @@
15#include <linux/printk.h> 15#include <linux/printk.h>
16 16
17#include <asm/gic.h> 17#include <asm/gic.h>
18#include <asm/mips-cpc.h>
18#include <asm/smp-ops.h> 19#include <asm/smp-ops.h>
19 20
20void gic_send_ipi_single(int cpu, unsigned int action) 21void gic_send_ipi_single(int cpu, unsigned int action)
21{ 22{
22 unsigned long flags; 23 unsigned long flags;
23 unsigned int intr; 24 unsigned int intr;
25 unsigned int core = cpu_data[cpu].core;
24 26
25 pr_debug("CPU%d: %s cpu %d action %u status %08x\n", 27 pr_debug("CPU%d: %s cpu %d action %u status %08x\n",
26 smp_processor_id(), __func__, cpu, action, read_c0_status()); 28 smp_processor_id(), __func__, cpu, action, read_c0_status());
@@ -41,6 +43,15 @@ void gic_send_ipi_single(int cpu, unsigned int action)
41 } 43 }
42 44
43 gic_send_ipi(intr); 45 gic_send_ipi(intr);
46
47 if (mips_cpc_present() && (core != current_cpu_data.core)) {
48 while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) {
49 mips_cpc_lock_other(core);
50 write_cpc_co_cmd(CPC_Cx_CMD_PWRUP);
51 mips_cpc_unlock_other();
52 }
53 }
54
44 local_irq_restore(flags); 55 local_irq_restore(flags);
45} 56}
46 57