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: Elliot Berman <eberman@codeaurora.org>
This commit is contained in:
parent
205d6619be
commit
ad4ce8c7d2
@ -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();
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user