Merge "soc: wdog: Ensure missing user watchdog pet can trigger bite"

This commit is contained in:
qctecmdr 2021-07-05 03:02:08 -07:00 • committed by Gerrit - the friendly Code Review server
commit 67683b3310
2 changed files with 30 additions and 0 deletions

View file

@ -371,6 +371,8 @@ int qcom_wdt_pet_suspend(struct device *dev)
wdog_dd->freeze_in_progress = true;
spin_unlock(&wdog_dd->freeze_lock);
del_timer_sync(&wdog_dd->pet_timer);
if (wdog_dd->user_pet_enabled)
del_timer_sync(&wdog_dd->user_pet_timer);
return 0;
}
EXPORT_SYMBOL(qcom_wdt_pet_suspend);
@ -390,6 +392,11 @@ int qcom_wdt_pet_resume(struct device *dev)
spin_lock(&wdog_dd->freeze_lock);
wdog_dd->pet_timer.expires = jiffies + delay_time;
add_timer(&wdog_dd->pet_timer);
if (wdog_dd->user_pet_enabled) {
delay_time = msecs_to_jiffies(wdog_dd->bark_time + 3 * 1000);
wdog_dd->user_pet_timer.expires = jiffies + delay_time;
add_timer(&wdog_dd->user_pet_timer);
}
wdog_dd->freeze_in_progress = false;
spin_unlock(&wdog_dd->freeze_lock);
return 0;
@ -480,6 +487,8 @@ static void qcom_wdt_disable(struct msm_watchdog_data *wdog_dd)
qcom_wdt_unregister_die_notifier(wdog_dd);
unregister_restart_handler(&wdog_dd->restart_blk);
del_timer_sync(&wdog_dd->pet_timer);
if (wdog_dd->user_pet_enabled)
del_timer_sync(&wdog_dd->user_pet_timer);
wdog_dd->ops->disable_wdt(wdog_dd);
dev_err(wdog_dd->dev, "QCOM Apps Watchdog deactivated\n");
}
@ -583,6 +592,8 @@ static ssize_t qcom_wdt_user_pet_enabled_set(struct device *dev,
{
struct msm_watchdog_data *wdog_dd = dev_get_drvdata(dev);
int ret;
unsigned long delay_time = 0;
bool already_enabled = wdog_dd->user_pet_enabled;
ret = strtobool(buf, &wdog_dd->user_pet_enabled);
if (ret) {
@ -590,6 +601,12 @@ static ssize_t qcom_wdt_user_pet_enabled_set(struct device *dev,
return ret;
}
delay_time = msecs_to_jiffies(wdog_dd->bark_time + 3 * 1000);
if (wdog_dd->user_pet_enabled)
mod_timer(&wdog_dd->user_pet_timer, jiffies + delay_time);
else if (already_enabled)
del_timer_sync(&wdog_dd->user_pet_timer);
__qcom_wdt_user_pet(wdog_dd);
return count;
@ -650,6 +667,15 @@ static void qcom_wdt_pet_task_wakeup(struct timer_list *t)
wdog_dd->timer_fired = sched_clock();
wake_up(&wdog_dd->pet_complete);
}
static void qcom_wdt_user_pet_bite(struct timer_list *t)
{
struct msm_watchdog_data *wdog_dd =
from_timer(wdog_dd, t, user_pet_timer);
if (!wdog_dd->user_pet_complete) {
dev_info(wdog_dd->dev, "QCOM Apps Watchdog user pet timeout!\n");
qcom_wdt_trigger_bite();
}
}
static __ref int qcom_wdt_kthread(void *arg)
{
@ -751,6 +777,8 @@ int qcom_wdt_remove(struct platform_device *pdev)
irq_dispose_mapping(wdog_dd->bark_irq);
dev_info(wdog_dd->dev, "QCOM Apps Watchdog Exit - Deactivated\n");
del_timer_sync(&wdog_dd->pet_timer);
if (wdog_dd->user_pet_enabled)
del_timer_sync(&wdog_dd->user_pet_timer);
wdog_dd->timer_expired = true;
wdog_dd->user_pet_complete = true;
kthread_stop(wdog_dd->watchdog_task);
@ -895,6 +923,7 @@ static int qcom_wdt_init(struct msm_watchdog_data *wdog_dd,
timer_setup(&wdog_dd->pet_timer, qcom_wdt_pet_task_wakeup, 0);
wdog_dd->pet_timer.expires = jiffies + delay_time;
add_timer(&wdog_dd->pet_timer);
timer_setup(&wdog_dd->user_pet_timer, qcom_wdt_user_pet_bite, 0);
val = BIT(EN);
if (wdog_dd->wakeup_irq_enable)
val |= BIT(UNMASKED_INT_EN);

View file

@ -149,6 +149,7 @@ struct msm_watchdog_data {
struct qcom_irq_info ipi_counts[NR_IPI];
unsigned int tot_irq_count[NR_CPUS];
atomic_t irq_counts_running;
struct timer_list user_pet_timer;
};
extern void qcom_wdt_trigger_bite(void);