aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/watchdog/gpio_wdt.c60
1 files changed, 30 insertions, 30 deletions
diff --git a/drivers/watchdog/gpio_wdt.c b/drivers/watchdog/gpio_wdt.c
index 57d30f1f55ab..5e16b0983e2a 100644
--- a/drivers/watchdog/gpio_wdt.c
+++ b/drivers/watchdog/gpio_wdt.c
@@ -50,12 +50,41 @@ static void gpio_wdt_disable(struct gpio_wdt_priv *priv)
50 gpio_direction_input(priv->gpio); 50 gpio_direction_input(priv->gpio);
51} 51}
52 52
53static void gpio_wdt_hwping(unsigned long data)
54{
55 struct watchdog_device *wdd = (struct watchdog_device *)data;
56 struct gpio_wdt_priv *priv = watchdog_get_drvdata(wdd);
57
58 if (priv->armed && time_after(jiffies, priv->last_jiffies +
59 msecs_to_jiffies(wdd->timeout * 1000))) {
60 dev_crit(wdd->dev, "Timer expired. System will reboot soon!\n");
61 return;
62 }
63
64 /* Restart timer */
65 mod_timer(&priv->timer, jiffies + priv->hw_margin);
66
67 switch (priv->hw_algo) {
68 case HW_ALGO_TOGGLE:
69 /* Toggle output pin */
70 priv->state = !priv->state;
71 gpio_set_value_cansleep(priv->gpio, priv->state);
72 break;
73 case HW_ALGO_LEVEL:
74 /* Pulse */
75 gpio_set_value_cansleep(priv->gpio, !priv->active_low);
76 udelay(1);
77 gpio_set_value_cansleep(priv->gpio, priv->active_low);
78 break;
79 }
80}
81
53static void gpio_wdt_start_impl(struct gpio_wdt_priv *priv) 82static void gpio_wdt_start_impl(struct gpio_wdt_priv *priv)
54{ 83{
55 priv->state = priv->active_low; 84 priv->state = priv->active_low;
56 gpio_direction_output(priv->gpio, priv->state); 85 gpio_direction_output(priv->gpio, priv->state);
57 priv->last_jiffies = jiffies; 86 priv->last_jiffies = jiffies;
58 mod_timer(&priv->timer, priv->last_jiffies + priv->hw_margin); 87 gpio_wdt_hwping((unsigned long)&priv->wdd);
59} 88}
60 89
61static int gpio_wdt_start(struct watchdog_device *wdd) 90static int gpio_wdt_start(struct watchdog_device *wdd)
@@ -97,35 +126,6 @@ static int gpio_wdt_set_timeout(struct watchdog_device *wdd, unsigned int t)
97 return gpio_wdt_ping(wdd); 126 return gpio_wdt_ping(wdd);
98} 127}
99 128
100static void gpio_wdt_hwping(unsigned long data)
101{
102 struct watchdog_device *wdd = (struct watchdog_device *)data;
103 struct gpio_wdt_priv *priv = watchdog_get_drvdata(wdd);
104
105 if (priv->armed && time_after(jiffies, priv->last_jiffies +
106 msecs_to_jiffies(wdd->timeout * 1000))) {
107 dev_crit(wdd->dev, "Timer expired. System will reboot soon!\n");
108 return;
109 }
110
111 /* Restart timer */
112 mod_timer(&priv->timer, jiffies + priv->hw_margin);
113
114 switch (priv->hw_algo) {
115 case HW_ALGO_TOGGLE:
116 /* Toggle output pin */
117 priv->state = !priv->state;
118 gpio_set_value_cansleep(priv->gpio, priv->state);
119 break;
120 case HW_ALGO_LEVEL:
121 /* Pulse */
122 gpio_set_value_cansleep(priv->gpio, !priv->active_low);
123 udelay(1);
124 gpio_set_value_cansleep(priv->gpio, priv->active_low);
125 break;
126 }
127}
128
129static int gpio_wdt_notify_sys(struct notifier_block *nb, unsigned long code, 129static int gpio_wdt_notify_sys(struct notifier_block *nb, unsigned long code,
130 void *unused) 130 void *unused)
131{ 131{