Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ad4ce8c7 authored by Elliot Berman's avatar Elliot Berman
Browse files

soc: qcom: Add watchdog bite in panic



Add watchdog bite in panic by registering a restart handler. Also add
support for an earlier watchdog bite in the panic handler itself, which
should provide a better context for post-mortem analysis.

Change-Id: Ib6530fa754b78fd26a9f7d5a348b1e7ceb3c1f96
Signed-off-by: default avatarElliot Berman <eberman@codeaurora.org>
parent 205d6619
Loading
Loading
Loading
Loading
+0 −7
Original line number Diff line number Diff line
@@ -502,13 +502,6 @@ static int do_msm_restart(struct notifier_block *unused, unsigned long action,

	msm_restart_prepare(cmd);

	/*
	 * Trigger a watchdog bite here and if this fails,
	 * device will take the usual restart path.
	 */
	if (WDOG_BITE_ON_PANIC && in_panic)
		msm_trigger_wdog_bite();

	qcom_scm_disable_sdi();
	qcom_scm_halt_spmi_pmic_arbiter();
	deassert_ps_hold();
+11 −1
Original line number Diff line number Diff line
@@ -783,7 +783,7 @@ config QCOM_WATCHDOG
          not catch any early lockups.

config QCOM_FORCE_WDOG_BITE_ON_PANIC
	bool "QCOM force watchdog bite"
	bool "QCOM force watchdog bite on panic"
	depends on QCOM_WATCHDOG
	help
	  This forces a watchdog bite when the device restarts
@@ -791,6 +791,16 @@ config QCOM_FORCE_WDOG_BITE_ON_PANIC
	  this provides additional debugging
	  information.

config QCOM_WDOG_BITE_EARLY_PANIC
	bool "QCOM early panic watchdog bite"
	depends on QCOM_WATCHDOG && QCOM_FORCE_WDOG_BITE_ON_PANIC
	help
	  This forces a watchdog bite early in panic sequence. On certain
	  MSM SoCs, this provides us additional debugging information at the
	  context of the crash. If this option is disabled, then bite occurs
	  later in panic, which permits more of the restart sequence to run
	  (e.g. more dmesg to flushed to console).

config MSM_SPCOM
         depends on QCOM_GLINK
         tristate "Secure Processor Communication over RPMSG"
+28 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include <linux/cpu_pm.h>
#include <linux/platform_device.h>
#include <linux/wait.h>
#include <linux/reboot.h>
#include <linux/qcom_scm.h>
#include <soc/qcom/minidump.h>
#include <soc/qcom/watchdog.h>
@@ -68,8 +69,10 @@ struct msm_watchdog_data {
	cpumask_t alive_mask;
	struct mutex disable_lock;
	bool irq_ppi;
	bool in_panic;
	struct msm_watchdog_data __percpu **wdog_cpu_dd;
	struct notifier_block panic_blk;
	struct notifier_block restart_blk;

	bool enabled;
	bool user_pet_enabled;
@@ -168,6 +171,11 @@ static int panic_wdog_handler(struct notifier_block *this,
{
	struct msm_watchdog_data *wdog_dd = container_of(this,
				struct msm_watchdog_data, panic_blk);
	wdog_dd->in_panic = true;
	if (WDOG_BITE_EARLY_PANIC) {
		pr_info("Triggering early bite\n");
		msm_trigger_wdog_bite();
	}
	if (panic_timeout == 0) {
		__raw_writel(0, wdog_dd->base + WDT0_EN);
		/* Make sure watchdog is enabled before notifying the caller */
@@ -206,6 +214,22 @@ static void wdog_disable(struct msm_watchdog_data *wdog_dd)
	dev_err(wdog_dd->dev, "MSM Apps Watchdog deactivated\n");
}

static int restart_wdog_handler(struct notifier_block *this,
			       unsigned long event, void *ptr)
{
	struct msm_watchdog_data *wdog_dd = container_of(this,
				struct msm_watchdog_data, restart_blk);
	if (WDOG_BITE_ON_PANIC && wdog_dd->in_panic) {
		/*
		 * Trigger a watchdog bite here and if this fails,
		 * device will take the usual restart path.
		 */
		pr_info("Triggering late bite\n");
		msm_trigger_wdog_bite();
	}
	return NOTIFY_DONE;
}

static ssize_t wdog_disable_get(struct device *dev,
				struct device_attribute *attr, char *buf)
{
@@ -587,9 +611,13 @@ static void init_watchdog_data(struct msm_watchdog_data *wdog_dd)
	__raw_writel(timeout, wdog_dd->base + WDT0_BARK_TIME);
	__raw_writel(timeout + 3*WDT_HZ, wdog_dd->base + WDT0_BITE_TIME);

	wdog_dd->panic_blk.priority = WDOG_BITE_EARLY_PANIC ? INT_MAX - 1 : 0;
	wdog_dd->panic_blk.notifier_call = panic_wdog_handler;
	atomic_notifier_chain_register(&panic_notifier_list,
				       &wdog_dd->panic_blk);
	wdog_dd->restart_blk.priority = 255;
	wdog_dd->restart_blk.notifier_call = restart_wdog_handler;
	register_restart_handler(&wdog_dd->restart_blk);
	mutex_init(&wdog_dd->disable_lock);
	init_waitqueue_head(&wdog_dd->pet_complete);
	wdog_dd->timer_expired = false;
+6 −0
Original line number Diff line number Diff line
@@ -12,6 +12,12 @@
#define WDOG_BITE_ON_PANIC 0
#endif

#ifdef CONFIG_QCOM_WDOG_BITE_EARLY_PANIC
#define WDOG_BITE_EARLY_PANIC 1
#else
#define WDOG_BITE_EARLY_PANIC 0
#endif

#if IS_ENABLED(CONFIG_QCOM_WATCHDOG)
void msm_trigger_wdog_bite(void);
#else