lkml.org 
[lkml]   [2019]   [Nov]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH v7 09/17] arm: tegra20: cpuidle: Handle case where secondary CPU hangs on entering LP2
Date
It is possible that something may go wrong with the secondary CPU, in that
case it is much nicer to get a dump of the flow-controller state before
hanging machine.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
arch/arm/mach-tegra/cpuidle-tegra20.c | 46 +++++++++++++++++++++++++--
1 file changed, 44 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-tegra/cpuidle-tegra20.c b/arch/arm/mach-tegra/cpuidle-tegra20.c
index 77702dd42479..bc5873e92af5 100644
--- a/arch/arm/mach-tegra/cpuidle-tegra20.c
+++ b/arch/arm/mach-tegra/cpuidle-tegra20.c
@@ -83,14 +83,56 @@ static inline void tegra20_wake_cpu1_from_reset(void)
}
#endif

+static void tegra20_report_cpus_state(void)
+{
+ unsigned int cpu, lcpu;
+
+ pr_err("secondary CPU taking too long to park\n");
+
+ for_each_cpu(lcpu, cpu_possible_mask) {
+ cpu = cpu_logical_map(lcpu);
+
+ pr_err("cpu%u: online=%d flowctrl_csr=0x%08x\n",
+ cpu, cpu_online(lcpu), flowctrl_read_cpu_csr(cpu));
+ }
+}
+
+static int tegra20_wait_for_secondary_cpu_parking(void)
+{
+ unsigned int retries = 3;
+
+ while (retries--) {
+ ktime_t timeout = ktime_add_ms(ktime_get(), 500);
+
+ /*
+ * The primary CPU0 core shall wait for the secondaries
+ * shutdown in order to power-off CPU's cluster safely.
+ * The timeout value depends on the current CPU frequency,
+ * it takes about 40-150us in average and over 1000us in
+ * a worst case scenario.
+ */
+ do {
+ if (tegra_cpu_rail_off_ready())
+ return 0;
+
+ } while (ktime_before(ktime_get(), timeout));
+
+ tegra20_report_cpus_state();
+ }
+
+ pr_err("timed out waiting secondaries to park\n");
+
+ return -ETIMEDOUT;
+}
+
static bool tegra20_cpu_cluster_power_down(struct cpuidle_device *dev,
struct cpuidle_driver *drv,
int index)
{
bool ret;

- while (!tegra_cpu_rail_off_ready())
- cpu_relax();
+ if (tegra20_wait_for_secondary_cpu_parking())
+ return false;

ret = !tegra_pm_enter_lp2();

--
2.23.0
\
 
 \ /
  Last update: 2019-11-11 22:17    [W:0.070 / U:0.636 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site