diff options
author | Paul Burton <paul.burton@imgtec.com> | 2014-04-14 11:25:29 -0400 |
---|---|---|
committer | Paul Burton <paul.burton@imgtec.com> | 2014-05-28 11:20:36 -0400 |
commit | d050894435cdc78807e714a0148527542a583e87 (patch) | |
tree | 39f95ee57dbe42e78945365e2b166161a24cc804 /arch/mips | |
parent | f08dbf8a61462aa122b9b5077849a3f4bd84702a (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.c | 11 |
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 | ||
20 | void gic_send_ipi_single(int cpu, unsigned int action) | 21 | void 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 | ||