|
@@ -12,6 +12,7 @@
|
|
|
#include <linux/init.h>
|
|
|
#include <linux/percpu.h>
|
|
|
#include <linux/slab.h>
|
|
|
+#include <linux/suspend.h>
|
|
|
|
|
|
#include <asm/asm-offsets.h>
|
|
|
#include <asm/cacheflush.h>
|
|
@@ -670,6 +671,34 @@ static int cps_pm_online_cpu(unsigned int cpu)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int cps_pm_power_notifier(struct notifier_block *this,
|
|
|
+ unsigned long event, void *ptr)
|
|
|
+{
|
|
|
+ unsigned int stat;
|
|
|
+
|
|
|
+ switch (event) {
|
|
|
+ case PM_SUSPEND_PREPARE:
|
|
|
+ stat = read_cpc_cl_stat_conf();
|
|
|
+ /*
|
|
|
+ * If we're attempting to suspend the system and power down all
|
|
|
+ * of the cores, the JTAG detect bit indicates that the CPC will
|
|
|
+ * instead put the cores into clock-off state. In this state
|
|
|
+ * a connected debugger can cause the CPU to attempt
|
|
|
+ * interactions with the powered down system. At best this will
|
|
|
+ * fail. At worst, it can hang the NoC, requiring a hard reset.
|
|
|
+ * To avoid this, just block system suspend if a JTAG probe
|
|
|
+ * is detected.
|
|
|
+ */
|
|
|
+ if (stat & CPC_Cx_STAT_CONF_EJTAG_PROBE) {
|
|
|
+ pr_warn("JTAG probe is connected - abort suspend\n");
|
|
|
+ return NOTIFY_BAD;
|
|
|
+ }
|
|
|
+ return NOTIFY_DONE;
|
|
|
+ default:
|
|
|
+ return NOTIFY_DONE;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static int __init cps_pm_init(void)
|
|
|
{
|
|
|
/* A CM is required for all non-coherent states */
|
|
@@ -705,6 +734,8 @@ static int __init cps_pm_init(void)
|
|
|
pr_warn("pm-cps: no CPC, clock & power gating unavailable\n");
|
|
|
}
|
|
|
|
|
|
+ pm_notifier(cps_pm_power_notifier, 0);
|
|
|
+
|
|
|
return cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "mips/cps_pm:online",
|
|
|
cps_pm_online_cpu, NULL);
|
|
|
}
|