diff options
-rw-r--r-- | drivers/watchdog/gpio_wdt.c | 60 |
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 | ||
53 | static 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 | |||
53 | static void gpio_wdt_start_impl(struct gpio_wdt_priv *priv) | 82 | static 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 | ||
61 | static int gpio_wdt_start(struct watchdog_device *wdd) | 90 | static 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 | ||
100 | static 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 | |||
129 | static int gpio_wdt_notify_sys(struct notifier_block *nb, unsigned long code, | 129 | static int gpio_wdt_notify_sys(struct notifier_block *nb, unsigned long code, |
130 | void *unused) | 130 | void *unused) |
131 | { | 131 | { |