aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-04-10 06:01:59 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-04-10 06:01:59 -0400
commitbe770021011f00bd6220c87876292053221ca5f1 (patch)
tree004a568289a595082119064edf07503170153c19 /drivers/watchdog
parente5e02de0665ef2477e7a018193051387c6fe0fbc (diff)
parentf321c9cbf3bbf86f6e6153419eaf93ad085e3d74 (diff)
Merge back earlier suspend/hibernate material for v4.1.
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/iTCO_wdt.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index 05ee0bf88ce9..3c3fd417ddeb 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -51,6 +51,7 @@
51#define DRV_VERSION "1.11" 51#define DRV_VERSION "1.11"
52 52
53/* Includes */ 53/* Includes */
54#include <linux/acpi.h> /* For ACPI support */
54#include <linux/module.h> /* For module specific items */ 55#include <linux/module.h> /* For module specific items */
55#include <linux/moduleparam.h> /* For new moduleparam's */ 56#include <linux/moduleparam.h> /* For new moduleparam's */
56#include <linux/types.h> /* For standard types (like size_t) */ 57#include <linux/types.h> /* For standard types (like size_t) */
@@ -103,6 +104,8 @@ static struct { /* this is private data for the iTCO_wdt device */
103 struct platform_device *dev; 104 struct platform_device *dev;
104 /* the PCI-device */ 105 /* the PCI-device */
105 struct pci_dev *pdev; 106 struct pci_dev *pdev;
107 /* whether or not the watchdog has been suspended */
108 bool suspended;
106} iTCO_wdt_private; 109} iTCO_wdt_private;
107 110
108/* module parameters */ 111/* module parameters */
@@ -571,12 +574,60 @@ static void iTCO_wdt_shutdown(struct platform_device *dev)
571 iTCO_wdt_stop(NULL); 574 iTCO_wdt_stop(NULL);
572} 575}
573 576
577#ifdef CONFIG_PM_SLEEP
578/*
579 * Suspend-to-idle requires this, because it stops the ticks and timekeeping, so
580 * the watchdog cannot be pinged while in that state. In ACPI sleep states the
581 * watchdog is stopped by the platform firmware.
582 */
583
584#ifdef CONFIG_ACPI
585static inline bool need_suspend(void)
586{
587 return acpi_target_system_state() == ACPI_STATE_S0;
588}
589#else
590static inline bool need_suspend(void) { return true; }
591#endif
592
593static int iTCO_wdt_suspend_noirq(struct device *dev)
594{
595 int ret = 0;
596
597 iTCO_wdt_private.suspended = false;
598 if (watchdog_active(&iTCO_wdt_watchdog_dev) && need_suspend()) {
599 ret = iTCO_wdt_stop(&iTCO_wdt_watchdog_dev);
600 if (!ret)
601 iTCO_wdt_private.suspended = true;
602 }
603 return ret;
604}
605
606static int iTCO_wdt_resume_noirq(struct device *dev)
607{
608 if (iTCO_wdt_private.suspended)
609 iTCO_wdt_start(&iTCO_wdt_watchdog_dev);
610
611 return 0;
612}
613
614static struct dev_pm_ops iTCO_wdt_pm = {
615 .suspend_noirq = iTCO_wdt_suspend_noirq,
616 .resume_noirq = iTCO_wdt_resume_noirq,
617};
618
619#define ITCO_WDT_PM_OPS (&iTCO_wdt_pm)
620#else
621#define ITCO_WDT_PM_OPS NULL
622#endif /* CONFIG_PM_SLEEP */
623
574static struct platform_driver iTCO_wdt_driver = { 624static struct platform_driver iTCO_wdt_driver = {
575 .probe = iTCO_wdt_probe, 625 .probe = iTCO_wdt_probe,
576 .remove = iTCO_wdt_remove, 626 .remove = iTCO_wdt_remove,
577 .shutdown = iTCO_wdt_shutdown, 627 .shutdown = iTCO_wdt_shutdown,
578 .driver = { 628 .driver = {
579 .name = DRV_NAME, 629 .name = DRV_NAME,
630 .pm = ITCO_WDT_PM_OPS,
580 }, 631 },
581}; 632};
582 633