aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Redfearn <matt.redfearn@mips.com>2018-02-20 04:58:16 -0500
committerJames Hogan <jhogan@kernel.org>2018-03-09 08:53:26 -0500
commitb2ed33a895676738dfad11cedcba1e3a0a8b6203 (patch)
treea9014cce241b25f4822bf2f3301194d4b651eb44
parentce6828faeb543d00f0697997c858bd82b5905670 (diff)
MIPS: pm-cps: Block system suspend when a JTAG probe is present
If a JTAG probe is connected to a MIPS cluster, then the CPC detects it and latches the CPC.STAT_CONF.EJTAG_PROBE bit to 1. While set, attempting to send a power-down command to a core will be blocked, and the CPC will instead send the core to clock-off state. This can interfere with systems fully entering a low power state where all cores, CM, GIC, etc are powered down. Detect that a JTAG probe is / has been connected to the cluster and block the suspend attempt. Attempting to suspend the system while a JTAG probe is connected now yields: # echo mem > /sys/power/state [ 11.654000] PM: Syncing filesystems ... done. [ 11.658000] JTAG probe is connected - abort suspend -sh: echo: write error: Operation not permitted # To restore suspend, the JTAG probe should be disconnected or put into quiescent state. Platform code can then clear the CPC.STAT_CONF.EJTAG_PROBE bit. Reported-by: Ed Blake <ed.blake@sondrel.com> Signed-off-by: Matt Redfearn <matt.redfearn@mips.com> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Paul Burton <paul.burton@mips.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/18641/ Signed-off-by: James Hogan <jhogan@kernel.org>
-rw-r--r--arch/mips/kernel/pm-cps.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c
index 421e06dfee72..55c3fbeb2df6 100644
--- a/arch/mips/kernel/pm-cps.c
+++ b/arch/mips/kernel/pm-cps.c
@@ -12,6 +12,7 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/percpu.h> 13#include <linux/percpu.h>
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/suspend.h>
15 16
16#include <asm/asm-offsets.h> 17#include <asm/asm-offsets.h>
17#include <asm/cacheflush.h> 18#include <asm/cacheflush.h>
@@ -670,6 +671,34 @@ static int cps_pm_online_cpu(unsigned int cpu)
670 return 0; 671 return 0;
671} 672}
672 673
674static int cps_pm_power_notifier(struct notifier_block *this,
675 unsigned long event, void *ptr)
676{
677 unsigned int stat;
678
679 switch (event) {
680 case PM_SUSPEND_PREPARE:
681 stat = read_cpc_cl_stat_conf();
682 /*
683 * If we're attempting to suspend the system and power down all
684 * of the cores, the JTAG detect bit indicates that the CPC will
685 * instead put the cores into clock-off state. In this state
686 * a connected debugger can cause the CPU to attempt
687 * interactions with the powered down system. At best this will
688 * fail. At worst, it can hang the NoC, requiring a hard reset.
689 * To avoid this, just block system suspend if a JTAG probe
690 * is detected.
691 */
692 if (stat & CPC_Cx_STAT_CONF_EJTAG_PROBE) {
693 pr_warn("JTAG probe is connected - abort suspend\n");
694 return NOTIFY_BAD;
695 }
696 return NOTIFY_DONE;
697 default:
698 return NOTIFY_DONE;
699 }
700}
701
673static int __init cps_pm_init(void) 702static int __init cps_pm_init(void)
674{ 703{
675 /* A CM is required for all non-coherent states */ 704 /* A CM is required for all non-coherent states */
@@ -705,6 +734,8 @@ static int __init cps_pm_init(void)
705 pr_warn("pm-cps: no CPC, clock & power gating unavailable\n"); 734 pr_warn("pm-cps: no CPC, clock & power gating unavailable\n");
706 } 735 }
707 736
737 pm_notifier(cps_pm_power_notifier, 0);
738
708 return cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "mips/cps_pm:online", 739 return cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "mips/cps_pm:online",
709 cps_pm_online_cpu, NULL); 740 cps_pm_online_cpu, NULL);
710} 741}