diff options
author | Christophe Leroy <christophe.leroy@c-s.fr> | 2013-12-04 01:32:14 -0500 |
---|---|---|
committer | Wim Van Sebroeck <wim@iguana.be> | 2014-01-28 15:27:08 -0500 |
commit | d5cfaf0a8554ad6b0e74955c7217ed24b2cadc9b (patch) | |
tree | 0a69d7903427f72591173202fa9c33e867262844 /drivers/watchdog/mpc8xxx_wdt.c | |
parent | 15edd9eedd61ac7be53d63ffa6a7208d4479cece (diff) |
watchdog: mpc8xxx_wdt convert to watchdog core
Convert mpc8xxx_wdt.c to the new watchdog API.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
Diffstat (limited to 'drivers/watchdog/mpc8xxx_wdt.c')
-rw-r--r-- | drivers/watchdog/mpc8xxx_wdt.c | 110 |
1 files changed, 37 insertions, 73 deletions
diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c index d82152077fd9..c1f65b4c0aa4 100644 --- a/drivers/watchdog/mpc8xxx_wdt.c +++ b/drivers/watchdog/mpc8xxx_wdt.c | |||
@@ -73,9 +73,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " | |||
73 | * to 0 | 73 | * to 0 |
74 | */ | 74 | */ |
75 | static int prescale = 1; | 75 | static int prescale = 1; |
76 | static unsigned int timeout_sec; | ||
77 | 76 | ||
78 | static unsigned long wdt_is_open; | ||
79 | static DEFINE_SPINLOCK(wdt_spinlock); | 77 | static DEFINE_SPINLOCK(wdt_spinlock); |
80 | 78 | ||
81 | static void mpc8xxx_wdt_keepalive(void) | 79 | static void mpc8xxx_wdt_keepalive(void) |
@@ -87,39 +85,23 @@ static void mpc8xxx_wdt_keepalive(void) | |||
87 | spin_unlock(&wdt_spinlock); | 85 | spin_unlock(&wdt_spinlock); |
88 | } | 86 | } |
89 | 87 | ||
88 | static struct watchdog_device mpc8xxx_wdt_dev; | ||
90 | static void mpc8xxx_wdt_timer_ping(unsigned long arg); | 89 | static void mpc8xxx_wdt_timer_ping(unsigned long arg); |
91 | static DEFINE_TIMER(wdt_timer, mpc8xxx_wdt_timer_ping, 0, 0); | 90 | static DEFINE_TIMER(wdt_timer, mpc8xxx_wdt_timer_ping, 0, |
91 | (unsigned long)&mpc8xxx_wdt_dev); | ||
92 | 92 | ||
93 | static void mpc8xxx_wdt_timer_ping(unsigned long arg) | 93 | static void mpc8xxx_wdt_timer_ping(unsigned long arg) |
94 | { | 94 | { |
95 | struct watchdog_device *w = (struct watchdog_device *)arg; | ||
96 | |||
95 | mpc8xxx_wdt_keepalive(); | 97 | mpc8xxx_wdt_keepalive(); |
96 | /* We're pinging it twice faster than needed, just to be sure. */ | 98 | /* We're pinging it twice faster than needed, just to be sure. */ |
97 | mod_timer(&wdt_timer, jiffies + HZ * timeout_sec / 2); | 99 | mod_timer(&wdt_timer, jiffies + HZ * w->timeout / 2); |
98 | } | ||
99 | |||
100 | static void mpc8xxx_wdt_pr_warn(const char *msg) | ||
101 | { | ||
102 | pr_crit("%s, expect the %s soon!\n", msg, | ||
103 | reset ? "reset" : "machine check exception"); | ||
104 | } | 100 | } |
105 | 101 | ||
106 | static ssize_t mpc8xxx_wdt_write(struct file *file, const char __user *buf, | 102 | static int mpc8xxx_wdt_start(struct watchdog_device *w) |
107 | size_t count, loff_t *ppos) | ||
108 | { | ||
109 | if (count) | ||
110 | mpc8xxx_wdt_keepalive(); | ||
111 | return count; | ||
112 | } | ||
113 | |||
114 | static int mpc8xxx_wdt_open(struct inode *inode, struct file *file) | ||
115 | { | 103 | { |
116 | u32 tmp = SWCRR_SWEN; | 104 | u32 tmp = SWCRR_SWEN; |
117 | if (test_and_set_bit(0, &wdt_is_open)) | ||
118 | return -EBUSY; | ||
119 | |||
120 | /* Once we start the watchdog we can't stop it */ | ||
121 | if (nowayout) | ||
122 | __module_get(THIS_MODULE); | ||
123 | 105 | ||
124 | /* Good, fire up the show */ | 106 | /* Good, fire up the show */ |
125 | if (prescale) | 107 | if (prescale) |
@@ -133,59 +115,37 @@ static int mpc8xxx_wdt_open(struct inode *inode, struct file *file) | |||
133 | 115 | ||
134 | del_timer_sync(&wdt_timer); | 116 | del_timer_sync(&wdt_timer); |
135 | 117 | ||
136 | return nonseekable_open(inode, file); | 118 | return 0; |
137 | } | 119 | } |
138 | 120 | ||
139 | static int mpc8xxx_wdt_release(struct inode *inode, struct file *file) | 121 | static int mpc8xxx_wdt_ping(struct watchdog_device *w) |
140 | { | 122 | { |
141 | if (!nowayout) | 123 | mpc8xxx_wdt_keepalive(); |
142 | mpc8xxx_wdt_timer_ping(0); | ||
143 | else | ||
144 | mpc8xxx_wdt_pr_warn("watchdog closed"); | ||
145 | clear_bit(0, &wdt_is_open); | ||
146 | return 0; | 124 | return 0; |
147 | } | 125 | } |
148 | 126 | ||
149 | static long mpc8xxx_wdt_ioctl(struct file *file, unsigned int cmd, | 127 | static int mpc8xxx_wdt_stop(struct watchdog_device *w) |
150 | unsigned long arg) | ||
151 | { | 128 | { |
152 | void __user *argp = (void __user *)arg; | 129 | mod_timer(&wdt_timer, jiffies); |
153 | int __user *p = argp; | 130 | return 0; |
154 | static const struct watchdog_info ident = { | ||
155 | .options = WDIOF_KEEPALIVEPING, | ||
156 | .firmware_version = 1, | ||
157 | .identity = "MPC8xxx", | ||
158 | }; | ||
159 | |||
160 | switch (cmd) { | ||
161 | case WDIOC_GETSUPPORT: | ||
162 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; | ||
163 | case WDIOC_GETSTATUS: | ||
164 | case WDIOC_GETBOOTSTATUS: | ||
165 | return put_user(0, p); | ||
166 | case WDIOC_KEEPALIVE: | ||
167 | mpc8xxx_wdt_keepalive(); | ||
168 | return 0; | ||
169 | case WDIOC_GETTIMEOUT: | ||
170 | return put_user(timeout_sec, p); | ||
171 | default: | ||
172 | return -ENOTTY; | ||
173 | } | ||
174 | } | 131 | } |
175 | 132 | ||
176 | static const struct file_operations mpc8xxx_wdt_fops = { | 133 | static struct watchdog_info mpc8xxx_wdt_info = { |
177 | .owner = THIS_MODULE, | 134 | .options = WDIOF_KEEPALIVEPING, |
178 | .llseek = no_llseek, | 135 | .firmware_version = 1, |
179 | .write = mpc8xxx_wdt_write, | 136 | .identity = "MPC8xxx", |
180 | .unlocked_ioctl = mpc8xxx_wdt_ioctl, | ||
181 | .open = mpc8xxx_wdt_open, | ||
182 | .release = mpc8xxx_wdt_release, | ||
183 | }; | 137 | }; |
184 | 138 | ||
185 | static struct miscdevice mpc8xxx_wdt_miscdev = { | 139 | static struct watchdog_ops mpc8xxx_wdt_ops = { |
186 | .minor = WATCHDOG_MINOR, | 140 | .owner = THIS_MODULE, |
187 | .name = "watchdog", | 141 | .start = mpc8xxx_wdt_start, |
188 | .fops = &mpc8xxx_wdt_fops, | 142 | .ping = mpc8xxx_wdt_ping, |
143 | .stop = mpc8xxx_wdt_stop, | ||
144 | }; | ||
145 | |||
146 | static struct watchdog_device mpc8xxx_wdt_dev = { | ||
147 | .info = &mpc8xxx_wdt_info, | ||
148 | .ops = &mpc8xxx_wdt_ops, | ||
189 | }; | 149 | }; |
190 | 150 | ||
191 | static const struct of_device_id mpc8xxx_wdt_match[]; | 151 | static const struct of_device_id mpc8xxx_wdt_match[]; |
@@ -197,6 +157,7 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev) | |||
197 | const struct mpc8xxx_wdt_type *wdt_type; | 157 | const struct mpc8xxx_wdt_type *wdt_type; |
198 | u32 freq = fsl_get_sys_freq(); | 158 | u32 freq = fsl_get_sys_freq(); |
199 | bool enabled; | 159 | bool enabled; |
160 | unsigned int timeout_sec; | ||
200 | 161 | ||
201 | match = of_match_device(mpc8xxx_wdt_match, &ofdev->dev); | 162 | match = of_match_device(mpc8xxx_wdt_match, &ofdev->dev); |
202 | if (!match) | 163 | if (!match) |
@@ -223,6 +184,7 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev) | |||
223 | else | 184 | else |
224 | timeout_sec = timeout / freq; | 185 | timeout_sec = timeout / freq; |
225 | 186 | ||
187 | mpc8xxx_wdt_dev.timeout = timeout_sec; | ||
226 | #ifdef MODULE | 188 | #ifdef MODULE |
227 | ret = mpc8xxx_wdt_init_late(); | 189 | ret = mpc8xxx_wdt_init_late(); |
228 | if (ret) | 190 | if (ret) |
@@ -238,7 +200,7 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev) | |||
238 | * userspace handles it. | 200 | * userspace handles it. |
239 | */ | 201 | */ |
240 | if (enabled) | 202 | if (enabled) |
241 | mpc8xxx_wdt_timer_ping(0); | 203 | mod_timer(&wdt_timer, jiffies); |
242 | return 0; | 204 | return 0; |
243 | err_unmap: | 205 | err_unmap: |
244 | iounmap(wd_base); | 206 | iounmap(wd_base); |
@@ -248,9 +210,10 @@ err_unmap: | |||
248 | 210 | ||
249 | static int mpc8xxx_wdt_remove(struct platform_device *ofdev) | 211 | static int mpc8xxx_wdt_remove(struct platform_device *ofdev) |
250 | { | 212 | { |
251 | mpc8xxx_wdt_pr_warn("watchdog removed"); | 213 | pr_crit("Watchdog removed, expect the %s soon!\n", |
214 | reset ? "reset" : "machine check exception"); | ||
252 | del_timer_sync(&wdt_timer); | 215 | del_timer_sync(&wdt_timer); |
253 | misc_deregister(&mpc8xxx_wdt_miscdev); | 216 | watchdog_unregister_device(&mpc8xxx_wdt_dev); |
254 | iounmap(wd_base); | 217 | iounmap(wd_base); |
255 | 218 | ||
256 | return 0; | 219 | return 0; |
@@ -302,10 +265,11 @@ static int mpc8xxx_wdt_init_late(void) | |||
302 | if (!wd_base) | 265 | if (!wd_base) |
303 | return -ENODEV; | 266 | return -ENODEV; |
304 | 267 | ||
305 | ret = misc_register(&mpc8xxx_wdt_miscdev); | 268 | watchdog_set_nowayout(&mpc8xxx_wdt_dev, nowayout); |
269 | |||
270 | ret = watchdog_register_device(&mpc8xxx_wdt_dev); | ||
306 | if (ret) { | 271 | if (ret) { |
307 | pr_err("cannot register miscdev on minor=%d (err=%d)\n", | 272 | pr_err("cannot register watchdog device (err=%d)\n", ret); |
308 | WATCHDOG_MINOR, ret); | ||
309 | return ret; | 273 | return ret; |
310 | } | 274 | } |
311 | return 0; | 275 | return 0; |