void __iomem *reg_base;
struct notifier_block pm_notifier;
struct notifier_block reboot_notifier;
+ bool is_running; /* 1:enable 0:disable */
};
static void aml_update_bits(void __iomem *reg, unsigned int mask,
if (wdev->boot_queue)
cancel_delayed_work(&wdev->boot_queue);
#endif
+ wdev->is_running = true;
dev_info(wdev->dev, "start watchdog\n");
+
return 0;
}
mutex_lock(&wdev->lock);
disable_watchdog(wdev);
mutex_unlock(&wdev->lock);
+ wdev->is_running = false;
dev_info(wdev->dev, "stop watchdog\n");
return 0;
unsigned int aml_wdt_get_timeleft(struct watchdog_device *wdog)
{
struct aml_wdt_dev *wdev = watchdog_get_drvdata(wdog);
- unsigned int timeleft;
+ unsigned long timeleft, tick;
mutex_lock(&wdev->lock);
timeleft = read_watchdog_tcnt(wdev);
+ tick = readl(wdev->reg_base + TCNT) & 0xffff;
mutex_unlock(&wdev->lock);
- return timeleft/wdev->one_second;
+
+ return (tick - timeleft)/wdev->one_second;
}
static void boot_moniter_work(struct work_struct *work)
wdev = container_of(nb, struct aml_wdt_dev, pm_notifier);
if (event == PM_SUSPEND_PREPARE) {
- disable_watchdog(wdev);
- dev_info(wdev->dev,
- "pm_notify: disable watchdog, event = %lu\n", event);
+ if (wdev->is_running) {
+ disable_watchdog(wdev);
+ dev_info(wdev->dev,
+ "pm_notify: disable watchdog, event = %lu\n", event);
+ }
}
if (event == PM_POST_SUSPEND) {
- enable_watchdog(wdev);
- dev_info(wdev->dev,
- "pm_notify: enable watchdog, event = %lu\n", event);
+ if (wdev->is_running) {
+ enable_watchdog(wdev);
+ dev_info(wdev->dev,
+ "pm_notify: enable watchdog, event = %lu\n", event);
+ }
}
return NOTIFY_OK;
}
watchdog_set_drvdata(aml_wdt, wdev);
platform_set_drvdata(pdev, aml_wdt);
+ wdev->is_running = false;
if (wdev->reset_watchdog_method == 1) {
INIT_DELAYED_WORK(&wdev->boot_queue, boot_moniter_work);
mod_delayed_work(system_freezable_wq, &wdev->boot_queue,
round_jiffies(msecs_to_jiffies(wdev->reset_watchdog_time*1000)));
- enable_watchdog(wdev);
- set_watchdog_cnt(wdev,
- wdev->default_timeout * wdev->one_second);
+ aml_wdt_start(aml_wdt);
dev_info(wdev->dev, "creat work queue for watch dog\n");
}
ret = watchdog_register_device(aml_wdt);