soc: qcom: Add a die notifier for qcom watchdog

To give sufficient time to die notifier to complete
their work, add a watchdog die notifier, to reset the
watchdog. Also, increase priority of watchdog panic
notifier and make minidump oops notifiers run after
watchdog oops notifiers.

Change-Id: Ifc53cc5c3b1ecc1554a971b9f2334319cad62bfd
Signed-off-by: Neeraj Upadhyay <neeraju@codeaurora.org>
This commit is contained in:
Neeraj Upadhyay 2020-09-18 10:19:14 +05:30
parent ae23001f63
commit 047ca2390b
3 changed files with 38 additions and 8 deletions

View File

@ -949,7 +949,7 @@ static int md_die_context_notify(struct notifier_block *self,
static struct notifier_block md_die_context_nb = {
.notifier_call = md_die_context_notify,
.priority = INT_MAX
.priority = INT_MAX - 2, /* < msm watchdog die notifier */
};
#endif
@ -1009,7 +1009,7 @@ static int md_panic_handler(struct notifier_block *this,
static struct notifier_block md_panic_blk = {
.notifier_call = md_panic_handler,
.priority = INT_MAX,
.priority = INT_MAX - 2, /* < msm watchdog panic notifier */
};
static int md_register_minidump_entry(char *name, u64 virt_addr,

View File

@ -25,6 +25,7 @@
#include <linux/kernel_stat.h>
#include <linux/irq_cpustat.h>
#include <linux/kallsyms.h>
#include <linux/kdebug.h>
#define MASK_SIZE 32
#define COMPARE_RET -1
@ -397,6 +398,16 @@ static struct syscore_ops qcom_wdt_syscore_ops = {
#endif
};
static void qcom_wdt_reset_on_oops(struct msm_watchdog_data *wdog_dd,
int timeout)
{
wdog_dd->ops->set_bark_time((timeout + 10) * 1000,
wdog_dd);
wdog_dd->ops->set_bite_time((timeout + 10) * 1000,
wdog_dd);
wdog_dd->ops->reset_wdt(wdog_dd);
}
static int qcom_wdt_panic_handler(struct notifier_block *this,
unsigned long event, void *ptr)
{
@ -411,15 +422,32 @@ static int qcom_wdt_panic_handler(struct notifier_block *this,
if (panic_timeout == 0) {
wdog_dd->ops->disable_wdt(wdog_dd);
} else {
wdog_dd->ops->set_bark_time((panic_timeout + 10) * 1000,
wdog_dd);
wdog_dd->ops->set_bite_time((panic_timeout + 10) * 1000,
wdog_dd);
wdog_dd->ops->reset_wdt(wdog_dd);
qcom_wdt_reset_on_oops(wdog_dd, panic_timeout);
}
return NOTIFY_DONE;
}
#ifdef CONFIG_QCOM_MINIDUMP_PANIC_DUMP
static int qcom_wdt_die_handler(struct notifier_block *this,
unsigned long val, void *data)
{
struct msm_watchdog_data *wdog_dd = container_of(this,
struct msm_watchdog_data, die_blk);
qcom_wdt_reset_on_oops(wdog_dd, 5);
return NOTIFY_DONE;
}
static void qcom_wdt_register_die_notifier(struct msm_watchdog_data *wdog_dd)
{
wdog_dd->die_blk.notifier_call = qcom_wdt_die_handler;
wdog_dd->die_blk.priority = INT_MAX - 1;
register_die_notifier(&wdog_dd->die_blk);
}
#else
static void qcom_wdt_register_die_notifier(struct msm_watchdog_data *wdog_dd) { }
#endif
static void qcom_wdt_disable(struct msm_watchdog_data *wdog_dd)
{
wdog_dd->ops->disable_wdt(wdog_dd);
@ -797,10 +825,11 @@ static int qcom_wdt_init(struct msm_watchdog_data *wdog_dd,
delay_time = msecs_to_jiffies(wdog_dd->pet_time);
wdog_dd->ops->set_bark_time(wdog_dd->bark_time, wdog_dd);
wdog_dd->ops->set_bite_time(wdog_dd->bark_time + 3 * 1000, wdog_dd);
wdog_dd->panic_blk.priority = WDOG_BITE_EARLY_PANIC ? INT_MAX - 1 : 0;
wdog_dd->panic_blk.priority = INT_MAX - 1;
wdog_dd->panic_blk.notifier_call = qcom_wdt_panic_handler;
atomic_notifier_chain_register(&panic_notifier_list,
&wdog_dd->panic_blk);
qcom_wdt_register_die_notifier(wdog_dd);
wdog_dd->restart_blk.priority = 255;
wdog_dd->restart_blk.notifier_call = restart_wdog_handler;
register_restart_handler(&wdog_dd->restart_blk);

View File

@ -122,6 +122,7 @@ struct msm_watchdog_data {
cpumask_t alive_mask;
struct mutex disable_lock;
struct notifier_block panic_blk;
struct notifier_block die_blk;
struct notifier_block wdog_cpu_pm_nb;
struct notifier_block restart_blk;