1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* |
3 | * watchdog_dev.c |
4 | * |
5 | * (c) Copyright 2008-2011 Alan Cox <alan@lxorguk.ukuu.org.uk>, |
6 | * All Rights Reserved. |
7 | * |
8 | * (c) Copyright 2008-2011 Wim Van Sebroeck <wim@iguana.be>. |
9 | * |
10 | * (c) Copyright 2021 Hewlett Packard Enterprise Development LP. |
11 | * |
12 | * This source code is part of the generic code that can be used |
13 | * by all the watchdog timer drivers. |
14 | * |
15 | * This part of the generic code takes care of the following |
16 | * misc device: /dev/watchdog. |
17 | * |
18 | * Based on source code of the following authors: |
19 | * Matt Domsch <Matt_Domsch@dell.com>, |
20 | * Rob Radez <rob@osinvestor.com>, |
21 | * Rusty Lynch <rusty@linux.co.intel.com> |
22 | * Satyam Sharma <satyam@infradead.org> |
23 | * Randy Dunlap <randy.dunlap@oracle.com> |
24 | * |
25 | * Neither Alan Cox, CymruNet Ltd., Wim Van Sebroeck nor Iguana vzw. |
26 | * admit liability nor provide warranty for any of this software. |
27 | * This material is provided "AS-IS" and at no charge. |
28 | */ |
29 | |
30 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
31 | |
32 | #include <linux/cdev.h> /* For character device */ |
33 | #include <linux/errno.h> /* For the -ENODEV/... values */ |
34 | #include <linux/fs.h> /* For file operations */ |
35 | #include <linux/init.h> /* For __init/__exit/... */ |
36 | #include <linux/hrtimer.h> /* For hrtimers */ |
37 | #include <linux/kernel.h> /* For printk/panic/... */ |
38 | #include <linux/kstrtox.h> /* For kstrto* */ |
39 | #include <linux/kthread.h> /* For kthread_work */ |
40 | #include <linux/miscdevice.h> /* For handling misc devices */ |
41 | #include <linux/module.h> /* For module stuff/... */ |
42 | #include <linux/mutex.h> /* For mutexes */ |
43 | #include <linux/slab.h> /* For memory functions */ |
44 | #include <linux/types.h> /* For standard types (like size_t) */ |
45 | #include <linux/watchdog.h> /* For watchdog specific items */ |
46 | #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ |
47 | |
48 | #include "watchdog_core.h" |
49 | #include "watchdog_pretimeout.h" |
50 | |
51 | #include <trace/events/watchdog.h> |
52 | |
53 | /* the dev_t structure to store the dynamically allocated watchdog devices */ |
54 | static dev_t watchdog_devt; |
55 | /* Reference to watchdog device behind /dev/watchdog */ |
56 | static struct watchdog_core_data *old_wd_data; |
57 | |
58 | static struct kthread_worker *watchdog_kworker; |
59 | |
60 | static bool handle_boot_enabled = |
61 | IS_ENABLED(CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED); |
62 | |
63 | static unsigned open_timeout = CONFIG_WATCHDOG_OPEN_TIMEOUT; |
64 | |
65 | static bool watchdog_past_open_deadline(struct watchdog_core_data *data) |
66 | { |
67 | return ktime_after(cmp1: ktime_get(), cmp2: data->open_deadline); |
68 | } |
69 | |
70 | static void watchdog_set_open_deadline(struct watchdog_core_data *data) |
71 | { |
72 | data->open_deadline = open_timeout ? |
73 | ktime_get() + ktime_set(secs: open_timeout, nsecs: 0) : KTIME_MAX; |
74 | } |
75 | |
76 | static inline bool watchdog_need_worker(struct watchdog_device *wdd) |
77 | { |
78 | /* All variables in milli-seconds */ |
79 | unsigned int hm = wdd->max_hw_heartbeat_ms; |
80 | unsigned int t = wdd->timeout * 1000; |
81 | |
82 | /* |
83 | * A worker to generate heartbeat requests is needed if all of the |
84 | * following conditions are true. |
85 | * - Userspace activated the watchdog. |
86 | * - The driver provided a value for the maximum hardware timeout, and |
87 | * thus is aware that the framework supports generating heartbeat |
88 | * requests. |
89 | * - Userspace requests a longer timeout than the hardware can handle. |
90 | * |
91 | * Alternatively, if userspace has not opened the watchdog |
92 | * device, we take care of feeding the watchdog if it is |
93 | * running. |
94 | */ |
95 | return (hm && watchdog_active(wdd) && t > hm) || |
96 | (t && !watchdog_active(wdd) && watchdog_hw_running(wdd)); |
97 | } |
98 | |
99 | static ktime_t watchdog_next_keepalive(struct watchdog_device *wdd) |
100 | { |
101 | struct watchdog_core_data *wd_data = wdd->wd_data; |
102 | unsigned int timeout_ms = wdd->timeout * 1000; |
103 | ktime_t keepalive_interval; |
104 | ktime_t last_heartbeat, latest_heartbeat; |
105 | ktime_t virt_timeout; |
106 | unsigned int hw_heartbeat_ms; |
107 | |
108 | if (watchdog_active(wdd)) |
109 | virt_timeout = ktime_add(wd_data->last_keepalive, |
110 | ms_to_ktime(timeout_ms)); |
111 | else |
112 | virt_timeout = wd_data->open_deadline; |
113 | |
114 | hw_heartbeat_ms = min_not_zero(timeout_ms, wdd->max_hw_heartbeat_ms); |
115 | keepalive_interval = ms_to_ktime(ms: hw_heartbeat_ms / 2); |
116 | |
117 | /* |
118 | * To ensure that the watchdog times out wdd->timeout seconds |
119 | * after the most recent ping from userspace, the last |
120 | * worker ping has to come in hw_heartbeat_ms before this timeout. |
121 | */ |
122 | last_heartbeat = ktime_sub(virt_timeout, ms_to_ktime(hw_heartbeat_ms)); |
123 | latest_heartbeat = ktime_sub(last_heartbeat, ktime_get()); |
124 | if (ktime_before(cmp1: latest_heartbeat, cmp2: keepalive_interval)) |
125 | return latest_heartbeat; |
126 | return keepalive_interval; |
127 | } |
128 | |
129 | static inline void watchdog_update_worker(struct watchdog_device *wdd) |
130 | { |
131 | struct watchdog_core_data *wd_data = wdd->wd_data; |
132 | |
133 | if (watchdog_need_worker(wdd)) { |
134 | ktime_t t = watchdog_next_keepalive(wdd); |
135 | |
136 | if (t > 0) |
137 | hrtimer_start(timer: &wd_data->timer, tim: t, |
138 | mode: HRTIMER_MODE_REL_HARD); |
139 | } else { |
140 | hrtimer_cancel(timer: &wd_data->timer); |
141 | } |
142 | } |
143 | |
144 | static int __watchdog_ping(struct watchdog_device *wdd) |
145 | { |
146 | struct watchdog_core_data *wd_data = wdd->wd_data; |
147 | ktime_t earliest_keepalive, now; |
148 | int err; |
149 | |
150 | earliest_keepalive = ktime_add(wd_data->last_hw_keepalive, |
151 | ms_to_ktime(wdd->min_hw_heartbeat_ms)); |
152 | now = ktime_get(); |
153 | |
154 | if (ktime_after(cmp1: earliest_keepalive, cmp2: now)) { |
155 | hrtimer_start(timer: &wd_data->timer, |
156 | ktime_sub(earliest_keepalive, now), |
157 | mode: HRTIMER_MODE_REL_HARD); |
158 | return 0; |
159 | } |
160 | |
161 | wd_data->last_hw_keepalive = now; |
162 | |
163 | if (wdd->ops->ping) { |
164 | err = wdd->ops->ping(wdd); /* ping the watchdog */ |
165 | trace_watchdog_ping(wdd, err); |
166 | } else { |
167 | err = wdd->ops->start(wdd); /* restart watchdog */ |
168 | trace_watchdog_start(wdd, err); |
169 | } |
170 | |
171 | if (err == 0) |
172 | watchdog_hrtimer_pretimeout_start(wdd); |
173 | |
174 | watchdog_update_worker(wdd); |
175 | |
176 | return err; |
177 | } |
178 | |
179 | /* |
180 | * watchdog_ping - ping the watchdog |
181 | * @wdd: The watchdog device to ping |
182 | * |
183 | * If the watchdog has no own ping operation then it needs to be |
184 | * restarted via the start operation. This wrapper function does |
185 | * exactly that. |
186 | * We only ping when the watchdog device is running. |
187 | * The caller must hold wd_data->lock. |
188 | * |
189 | * Return: 0 on success, error otherwise. |
190 | */ |
191 | static int watchdog_ping(struct watchdog_device *wdd) |
192 | { |
193 | struct watchdog_core_data *wd_data = wdd->wd_data; |
194 | |
195 | if (!watchdog_hw_running(wdd)) |
196 | return 0; |
197 | |
198 | set_bit(_WDOG_KEEPALIVE, addr: &wd_data->status); |
199 | |
200 | wd_data->last_keepalive = ktime_get(); |
201 | return __watchdog_ping(wdd); |
202 | } |
203 | |
204 | static bool watchdog_worker_should_ping(struct watchdog_core_data *wd_data) |
205 | { |
206 | struct watchdog_device *wdd = wd_data->wdd; |
207 | |
208 | if (!wdd) |
209 | return false; |
210 | |
211 | if (watchdog_active(wdd)) |
212 | return true; |
213 | |
214 | return watchdog_hw_running(wdd) && !watchdog_past_open_deadline(data: wd_data); |
215 | } |
216 | |
217 | static void watchdog_ping_work(struct kthread_work *work) |
218 | { |
219 | struct watchdog_core_data *wd_data; |
220 | |
221 | wd_data = container_of(work, struct watchdog_core_data, work); |
222 | |
223 | mutex_lock(&wd_data->lock); |
224 | if (watchdog_worker_should_ping(wd_data)) |
225 | __watchdog_ping(wdd: wd_data->wdd); |
226 | mutex_unlock(lock: &wd_data->lock); |
227 | } |
228 | |
229 | static enum hrtimer_restart watchdog_timer_expired(struct hrtimer *timer) |
230 | { |
231 | struct watchdog_core_data *wd_data; |
232 | |
233 | wd_data = container_of(timer, struct watchdog_core_data, timer); |
234 | |
235 | kthread_queue_work(worker: watchdog_kworker, work: &wd_data->work); |
236 | return HRTIMER_NORESTART; |
237 | } |
238 | |
239 | /* |
240 | * watchdog_start - wrapper to start the watchdog |
241 | * @wdd: The watchdog device to start |
242 | * |
243 | * Start the watchdog if it is not active and mark it active. |
244 | * The caller must hold wd_data->lock. |
245 | * |
246 | * Return: 0 on success or a negative errno code for failure. |
247 | */ |
248 | static int watchdog_start(struct watchdog_device *wdd) |
249 | { |
250 | struct watchdog_core_data *wd_data = wdd->wd_data; |
251 | ktime_t started_at; |
252 | int err; |
253 | |
254 | if (watchdog_active(wdd)) |
255 | return 0; |
256 | |
257 | set_bit(_WDOG_KEEPALIVE, addr: &wd_data->status); |
258 | |
259 | started_at = ktime_get(); |
260 | if (watchdog_hw_running(wdd) && wdd->ops->ping) { |
261 | err = __watchdog_ping(wdd); |
262 | if (err == 0) { |
263 | set_bit(WDOG_ACTIVE, addr: &wdd->status); |
264 | watchdog_hrtimer_pretimeout_start(wdd); |
265 | } |
266 | } else { |
267 | err = wdd->ops->start(wdd); |
268 | trace_watchdog_start(wdd, err); |
269 | if (err == 0) { |
270 | set_bit(WDOG_ACTIVE, addr: &wdd->status); |
271 | set_bit(WDOG_HW_RUNNING, addr: &wdd->status); |
272 | wd_data->last_keepalive = started_at; |
273 | wd_data->last_hw_keepalive = started_at; |
274 | watchdog_update_worker(wdd); |
275 | watchdog_hrtimer_pretimeout_start(wdd); |
276 | } |
277 | } |
278 | |
279 | return err; |
280 | } |
281 | |
282 | /* |
283 | * watchdog_stop - wrapper to stop the watchdog |
284 | * @wdd: The watchdog device to stop |
285 | * |
286 | * Stop the watchdog if it is still active and unmark it active. |
287 | * If the 'nowayout' feature was set, the watchdog cannot be stopped. |
288 | * The caller must hold wd_data->lock. |
289 | * |
290 | * Return: 0 on success or a negative errno code for failure. |
291 | */ |
292 | static int watchdog_stop(struct watchdog_device *wdd) |
293 | { |
294 | int err = 0; |
295 | |
296 | if (!watchdog_active(wdd)) |
297 | return 0; |
298 | |
299 | if (test_bit(WDOG_NO_WAY_OUT, &wdd->status)) { |
300 | pr_info("watchdog%d: nowayout prevents watchdog being stopped!\n" , |
301 | wdd->id); |
302 | return -EBUSY; |
303 | } |
304 | |
305 | if (wdd->ops->stop) { |
306 | clear_bit(WDOG_HW_RUNNING, addr: &wdd->status); |
307 | err = wdd->ops->stop(wdd); |
308 | trace_watchdog_stop(wdd, err); |
309 | } else { |
310 | set_bit(WDOG_HW_RUNNING, addr: &wdd->status); |
311 | } |
312 | |
313 | if (err == 0) { |
314 | clear_bit(WDOG_ACTIVE, addr: &wdd->status); |
315 | watchdog_update_worker(wdd); |
316 | watchdog_hrtimer_pretimeout_stop(wdd); |
317 | } |
318 | |
319 | return err; |
320 | } |
321 | |
322 | /* |
323 | * watchdog_get_status - wrapper to get the watchdog status |
324 | * @wdd: The watchdog device to get the status from |
325 | * |
326 | * Get the watchdog's status flags. |
327 | * The caller must hold wd_data->lock. |
328 | * |
329 | * Return: watchdog's status flags. |
330 | */ |
331 | static unsigned int watchdog_get_status(struct watchdog_device *wdd) |
332 | { |
333 | struct watchdog_core_data *wd_data = wdd->wd_data; |
334 | unsigned int status; |
335 | |
336 | if (wdd->ops->status) |
337 | status = wdd->ops->status(wdd); |
338 | else |
339 | status = wdd->bootstatus & (WDIOF_CARDRESET | |
340 | WDIOF_OVERHEAT | |
341 | WDIOF_FANFAULT | |
342 | WDIOF_EXTERN1 | |
343 | WDIOF_EXTERN2 | |
344 | WDIOF_POWERUNDER | |
345 | WDIOF_POWEROVER); |
346 | |
347 | if (test_bit(_WDOG_ALLOW_RELEASE, &wd_data->status)) |
348 | status |= WDIOF_MAGICCLOSE; |
349 | |
350 | if (test_and_clear_bit(_WDOG_KEEPALIVE, addr: &wd_data->status)) |
351 | status |= WDIOF_KEEPALIVEPING; |
352 | |
353 | if (IS_ENABLED(CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT)) |
354 | status |= WDIOF_PRETIMEOUT; |
355 | |
356 | return status; |
357 | } |
358 | |
359 | /* |
360 | * watchdog_set_timeout - set the watchdog timer timeout |
361 | * @wdd: The watchdog device to set the timeout for |
362 | * @timeout: Timeout to set in seconds |
363 | * |
364 | * The caller must hold wd_data->lock. |
365 | * |
366 | * Return: 0 if successful, error otherwise. |
367 | */ |
368 | static int watchdog_set_timeout(struct watchdog_device *wdd, |
369 | unsigned int timeout) |
370 | { |
371 | int err = 0; |
372 | |
373 | if (!(wdd->info->options & WDIOF_SETTIMEOUT)) |
374 | return -EOPNOTSUPP; |
375 | |
376 | if (watchdog_timeout_invalid(wdd, t: timeout)) |
377 | return -EINVAL; |
378 | |
379 | if (wdd->ops->set_timeout) { |
380 | err = wdd->ops->set_timeout(wdd, timeout); |
381 | trace_watchdog_set_timeout(wdd, timeout, err); |
382 | } else { |
383 | wdd->timeout = timeout; |
384 | /* Disable pretimeout if it doesn't fit the new timeout */ |
385 | if (wdd->pretimeout >= wdd->timeout) |
386 | wdd->pretimeout = 0; |
387 | } |
388 | |
389 | watchdog_update_worker(wdd); |
390 | |
391 | return err; |
392 | } |
393 | |
394 | /* |
395 | * watchdog_set_pretimeout - set the watchdog timer pretimeout |
396 | * @wdd: The watchdog device to set the timeout for |
397 | * @timeout: pretimeout to set in seconds |
398 | * |
399 | * Return: 0 if successful, error otherwise. |
400 | */ |
401 | static int watchdog_set_pretimeout(struct watchdog_device *wdd, |
402 | unsigned int timeout) |
403 | { |
404 | int err = 0; |
405 | |
406 | if (!watchdog_have_pretimeout(wdd)) |
407 | return -EOPNOTSUPP; |
408 | |
409 | if (watchdog_pretimeout_invalid(wdd, t: timeout)) |
410 | return -EINVAL; |
411 | |
412 | if (wdd->ops->set_pretimeout && (wdd->info->options & WDIOF_PRETIMEOUT)) |
413 | err = wdd->ops->set_pretimeout(wdd, timeout); |
414 | else |
415 | wdd->pretimeout = timeout; |
416 | |
417 | return err; |
418 | } |
419 | |
420 | /* |
421 | * watchdog_get_timeleft - wrapper to get the time left before a reboot |
422 | * @wdd: The watchdog device to get the remaining time from |
423 | * @timeleft: The time that's left |
424 | * |
425 | * Get the time before a watchdog will reboot (if not pinged). |
426 | * The caller must hold wd_data->lock. |
427 | * |
428 | * Return: 0 if successful, error otherwise. |
429 | */ |
430 | static int watchdog_get_timeleft(struct watchdog_device *wdd, |
431 | unsigned int *timeleft) |
432 | { |
433 | *timeleft = 0; |
434 | |
435 | if (!wdd->ops->get_timeleft) |
436 | return -EOPNOTSUPP; |
437 | |
438 | *timeleft = wdd->ops->get_timeleft(wdd); |
439 | |
440 | return 0; |
441 | } |
442 | |
443 | #ifdef CONFIG_WATCHDOG_SYSFS |
444 | static ssize_t nowayout_show(struct device *dev, struct device_attribute *attr, |
445 | char *buf) |
446 | { |
447 | struct watchdog_device *wdd = dev_get_drvdata(dev); |
448 | |
449 | return sysfs_emit(buf, fmt: "%d\n" , !!test_bit(WDOG_NO_WAY_OUT, |
450 | &wdd->status)); |
451 | } |
452 | |
453 | static ssize_t nowayout_store(struct device *dev, struct device_attribute *attr, |
454 | const char *buf, size_t len) |
455 | { |
456 | struct watchdog_device *wdd = dev_get_drvdata(dev); |
457 | unsigned int value; |
458 | int ret; |
459 | |
460 | ret = kstrtouint(s: buf, base: 0, res: &value); |
461 | if (ret) |
462 | return ret; |
463 | if (value > 1) |
464 | return -EINVAL; |
465 | /* nowayout cannot be disabled once set */ |
466 | if (test_bit(WDOG_NO_WAY_OUT, &wdd->status) && !value) |
467 | return -EPERM; |
468 | watchdog_set_nowayout(wdd, nowayout: value); |
469 | return len; |
470 | } |
471 | static DEVICE_ATTR_RW(nowayout); |
472 | |
473 | static ssize_t status_show(struct device *dev, struct device_attribute *attr, |
474 | char *buf) |
475 | { |
476 | struct watchdog_device *wdd = dev_get_drvdata(dev); |
477 | struct watchdog_core_data *wd_data = wdd->wd_data; |
478 | unsigned int status; |
479 | |
480 | mutex_lock(&wd_data->lock); |
481 | status = watchdog_get_status(wdd); |
482 | mutex_unlock(lock: &wd_data->lock); |
483 | |
484 | return sysfs_emit(buf, fmt: "0x%x\n" , status); |
485 | } |
486 | static DEVICE_ATTR_RO(status); |
487 | |
488 | static ssize_t bootstatus_show(struct device *dev, |
489 | struct device_attribute *attr, char *buf) |
490 | { |
491 | struct watchdog_device *wdd = dev_get_drvdata(dev); |
492 | |
493 | return sysfs_emit(buf, fmt: "%u\n" , wdd->bootstatus); |
494 | } |
495 | static DEVICE_ATTR_RO(bootstatus); |
496 | |
497 | static ssize_t timeleft_show(struct device *dev, struct device_attribute *attr, |
498 | char *buf) |
499 | { |
500 | struct watchdog_device *wdd = dev_get_drvdata(dev); |
501 | struct watchdog_core_data *wd_data = wdd->wd_data; |
502 | ssize_t status; |
503 | unsigned int val; |
504 | |
505 | mutex_lock(&wd_data->lock); |
506 | status = watchdog_get_timeleft(wdd, timeleft: &val); |
507 | mutex_unlock(lock: &wd_data->lock); |
508 | if (!status) |
509 | status = sysfs_emit(buf, fmt: "%u\n" , val); |
510 | |
511 | return status; |
512 | } |
513 | static DEVICE_ATTR_RO(timeleft); |
514 | |
515 | static ssize_t timeout_show(struct device *dev, struct device_attribute *attr, |
516 | char *buf) |
517 | { |
518 | struct watchdog_device *wdd = dev_get_drvdata(dev); |
519 | |
520 | return sysfs_emit(buf, fmt: "%u\n" , wdd->timeout); |
521 | } |
522 | static DEVICE_ATTR_RO(timeout); |
523 | |
524 | static ssize_t min_timeout_show(struct device *dev, |
525 | struct device_attribute *attr, char *buf) |
526 | { |
527 | struct watchdog_device *wdd = dev_get_drvdata(dev); |
528 | |
529 | return sysfs_emit(buf, fmt: "%u\n" , wdd->min_timeout); |
530 | } |
531 | static DEVICE_ATTR_RO(min_timeout); |
532 | |
533 | static ssize_t max_timeout_show(struct device *dev, |
534 | struct device_attribute *attr, char *buf) |
535 | { |
536 | struct watchdog_device *wdd = dev_get_drvdata(dev); |
537 | |
538 | return sysfs_emit(buf, fmt: "%u\n" , wdd->max_timeout); |
539 | } |
540 | static DEVICE_ATTR_RO(max_timeout); |
541 | |
542 | static ssize_t pretimeout_show(struct device *dev, |
543 | struct device_attribute *attr, char *buf) |
544 | { |
545 | struct watchdog_device *wdd = dev_get_drvdata(dev); |
546 | |
547 | return sysfs_emit(buf, fmt: "%u\n" , wdd->pretimeout); |
548 | } |
549 | static DEVICE_ATTR_RO(pretimeout); |
550 | |
551 | static ssize_t options_show(struct device *dev, struct device_attribute *attr, |
552 | char *buf) |
553 | { |
554 | struct watchdog_device *wdd = dev_get_drvdata(dev); |
555 | |
556 | return sysfs_emit(buf, fmt: "0x%x\n" , wdd->info->options); |
557 | } |
558 | static DEVICE_ATTR_RO(options); |
559 | |
560 | static ssize_t fw_version_show(struct device *dev, struct device_attribute *attr, |
561 | char *buf) |
562 | { |
563 | struct watchdog_device *wdd = dev_get_drvdata(dev); |
564 | |
565 | return sysfs_emit(buf, fmt: "%d\n" , wdd->info->firmware_version); |
566 | } |
567 | static DEVICE_ATTR_RO(fw_version); |
568 | |
569 | static ssize_t identity_show(struct device *dev, struct device_attribute *attr, |
570 | char *buf) |
571 | { |
572 | struct watchdog_device *wdd = dev_get_drvdata(dev); |
573 | |
574 | return sysfs_emit(buf, fmt: "%s\n" , wdd->info->identity); |
575 | } |
576 | static DEVICE_ATTR_RO(identity); |
577 | |
578 | static ssize_t state_show(struct device *dev, struct device_attribute *attr, |
579 | char *buf) |
580 | { |
581 | struct watchdog_device *wdd = dev_get_drvdata(dev); |
582 | |
583 | if (watchdog_active(wdd)) |
584 | return sysfs_emit(buf, fmt: "active\n" ); |
585 | |
586 | return sysfs_emit(buf, fmt: "inactive\n" ); |
587 | } |
588 | static DEVICE_ATTR_RO(state); |
589 | |
590 | static ssize_t pretimeout_available_governors_show(struct device *dev, |
591 | struct device_attribute *attr, char *buf) |
592 | { |
593 | return watchdog_pretimeout_available_governors_get(buf); |
594 | } |
595 | static DEVICE_ATTR_RO(pretimeout_available_governors); |
596 | |
597 | static ssize_t pretimeout_governor_show(struct device *dev, |
598 | struct device_attribute *attr, |
599 | char *buf) |
600 | { |
601 | struct watchdog_device *wdd = dev_get_drvdata(dev); |
602 | |
603 | return watchdog_pretimeout_governor_get(wdd, buf); |
604 | } |
605 | |
606 | static ssize_t pretimeout_governor_store(struct device *dev, |
607 | struct device_attribute *attr, |
608 | const char *buf, size_t count) |
609 | { |
610 | struct watchdog_device *wdd = dev_get_drvdata(dev); |
611 | int ret = watchdog_pretimeout_governor_set(wdd, buf); |
612 | |
613 | if (!ret) |
614 | ret = count; |
615 | |
616 | return ret; |
617 | } |
618 | static DEVICE_ATTR_RW(pretimeout_governor); |
619 | |
620 | static umode_t wdt_is_visible(struct kobject *kobj, struct attribute *attr, |
621 | int n) |
622 | { |
623 | struct device *dev = kobj_to_dev(kobj); |
624 | struct watchdog_device *wdd = dev_get_drvdata(dev); |
625 | umode_t mode = attr->mode; |
626 | |
627 | if (attr == &dev_attr_timeleft.attr && !wdd->ops->get_timeleft) |
628 | mode = 0; |
629 | else if (attr == &dev_attr_pretimeout.attr && !watchdog_have_pretimeout(wdd)) |
630 | mode = 0; |
631 | else if ((attr == &dev_attr_pretimeout_governor.attr || |
632 | attr == &dev_attr_pretimeout_available_governors.attr) && |
633 | (!watchdog_have_pretimeout(wdd) || !IS_ENABLED(CONFIG_WATCHDOG_PRETIMEOUT_GOV))) |
634 | mode = 0; |
635 | |
636 | return mode; |
637 | } |
638 | static struct attribute *wdt_attrs[] = { |
639 | &dev_attr_state.attr, |
640 | &dev_attr_options.attr, |
641 | &dev_attr_fw_version.attr, |
642 | &dev_attr_identity.attr, |
643 | &dev_attr_timeout.attr, |
644 | &dev_attr_min_timeout.attr, |
645 | &dev_attr_max_timeout.attr, |
646 | &dev_attr_pretimeout.attr, |
647 | &dev_attr_timeleft.attr, |
648 | &dev_attr_bootstatus.attr, |
649 | &dev_attr_status.attr, |
650 | &dev_attr_nowayout.attr, |
651 | &dev_attr_pretimeout_governor.attr, |
652 | &dev_attr_pretimeout_available_governors.attr, |
653 | NULL, |
654 | }; |
655 | |
656 | static const struct attribute_group wdt_group = { |
657 | .attrs = wdt_attrs, |
658 | .is_visible = wdt_is_visible, |
659 | }; |
660 | __ATTRIBUTE_GROUPS(wdt); |
661 | #else |
662 | #define wdt_groups NULL |
663 | #endif |
664 | |
665 | /* |
666 | * watchdog_ioctl_op - call the watchdog drivers ioctl op if defined |
667 | * @wdd: The watchdog device to do the ioctl on |
668 | * @cmd: Watchdog command |
669 | * @arg: Argument pointer |
670 | * |
671 | * The caller must hold wd_data->lock. |
672 | * |
673 | * Return: 0 if successful, error otherwise. |
674 | */ |
675 | static int watchdog_ioctl_op(struct watchdog_device *wdd, unsigned int cmd, |
676 | unsigned long arg) |
677 | { |
678 | if (!wdd->ops->ioctl) |
679 | return -ENOIOCTLCMD; |
680 | |
681 | return wdd->ops->ioctl(wdd, cmd, arg); |
682 | } |
683 | |
684 | /* |
685 | * watchdog_write - writes to the watchdog |
686 | * @file: File from VFS |
687 | * @data: User address of data |
688 | * @len: Length of data |
689 | * @ppos: Pointer to the file offset |
690 | * |
691 | * A write to a watchdog device is defined as a keepalive ping. |
692 | * Writing the magic 'V' sequence allows the next close to turn |
693 | * off the watchdog (if 'nowayout' is not set). |
694 | * |
695 | * Return: @len if successful, error otherwise. |
696 | */ |
697 | static ssize_t watchdog_write(struct file *file, const char __user *data, |
698 | size_t len, loff_t *ppos) |
699 | { |
700 | struct watchdog_core_data *wd_data = file->private_data; |
701 | struct watchdog_device *wdd; |
702 | int err; |
703 | size_t i; |
704 | char c; |
705 | |
706 | if (len == 0) |
707 | return 0; |
708 | |
709 | /* |
710 | * Note: just in case someone wrote the magic character |
711 | * five months ago... |
712 | */ |
713 | clear_bit(_WDOG_ALLOW_RELEASE, addr: &wd_data->status); |
714 | |
715 | /* scan to see whether or not we got the magic character */ |
716 | for (i = 0; i != len; i++) { |
717 | if (get_user(c, data + i)) |
718 | return -EFAULT; |
719 | if (c == 'V') |
720 | set_bit(_WDOG_ALLOW_RELEASE, addr: &wd_data->status); |
721 | } |
722 | |
723 | /* someone wrote to us, so we send the watchdog a keepalive ping */ |
724 | |
725 | err = -ENODEV; |
726 | mutex_lock(&wd_data->lock); |
727 | wdd = wd_data->wdd; |
728 | if (wdd) |
729 | err = watchdog_ping(wdd); |
730 | mutex_unlock(lock: &wd_data->lock); |
731 | |
732 | if (err < 0) |
733 | return err; |
734 | |
735 | return len; |
736 | } |
737 | |
738 | /* |
739 | * watchdog_ioctl - handle the different ioctl's for the watchdog device |
740 | * @file: File handle to the device |
741 | * @cmd: Watchdog command |
742 | * @arg: Argument pointer |
743 | * |
744 | * The watchdog API defines a common set of functions for all watchdogs |
745 | * according to their available features. |
746 | * |
747 | * Return: 0 if successful, error otherwise. |
748 | */ |
749 | |
750 | static long watchdog_ioctl(struct file *file, unsigned int cmd, |
751 | unsigned long arg) |
752 | { |
753 | struct watchdog_core_data *wd_data = file->private_data; |
754 | void __user *argp = (void __user *)arg; |
755 | struct watchdog_device *wdd; |
756 | int __user *p = argp; |
757 | unsigned int val; |
758 | int err; |
759 | |
760 | mutex_lock(&wd_data->lock); |
761 | |
762 | wdd = wd_data->wdd; |
763 | if (!wdd) { |
764 | err = -ENODEV; |
765 | goto out_ioctl; |
766 | } |
767 | |
768 | err = watchdog_ioctl_op(wdd, cmd, arg); |
769 | if (err != -ENOIOCTLCMD) |
770 | goto out_ioctl; |
771 | |
772 | switch (cmd) { |
773 | case WDIOC_GETSUPPORT: |
774 | err = copy_to_user(to: argp, from: wdd->info, |
775 | n: sizeof(struct watchdog_info)) ? -EFAULT : 0; |
776 | break; |
777 | case WDIOC_GETSTATUS: |
778 | val = watchdog_get_status(wdd); |
779 | err = put_user(val, p); |
780 | break; |
781 | case WDIOC_GETBOOTSTATUS: |
782 | err = put_user(wdd->bootstatus, p); |
783 | break; |
784 | case WDIOC_SETOPTIONS: |
785 | if (get_user(val, p)) { |
786 | err = -EFAULT; |
787 | break; |
788 | } |
789 | if (val & WDIOS_DISABLECARD) { |
790 | err = watchdog_stop(wdd); |
791 | if (err < 0) |
792 | break; |
793 | } |
794 | if (val & WDIOS_ENABLECARD) |
795 | err = watchdog_start(wdd); |
796 | break; |
797 | case WDIOC_KEEPALIVE: |
798 | if (!(wdd->info->options & WDIOF_KEEPALIVEPING)) { |
799 | err = -EOPNOTSUPP; |
800 | break; |
801 | } |
802 | err = watchdog_ping(wdd); |
803 | break; |
804 | case WDIOC_SETTIMEOUT: |
805 | if (get_user(val, p)) { |
806 | err = -EFAULT; |
807 | break; |
808 | } |
809 | err = watchdog_set_timeout(wdd, timeout: val); |
810 | if (err < 0) |
811 | break; |
812 | /* If the watchdog is active then we send a keepalive ping |
813 | * to make sure that the watchdog keep's running (and if |
814 | * possible that it takes the new timeout) */ |
815 | err = watchdog_ping(wdd); |
816 | if (err < 0) |
817 | break; |
818 | fallthrough; |
819 | case WDIOC_GETTIMEOUT: |
820 | /* timeout == 0 means that we don't know the timeout */ |
821 | if (wdd->timeout == 0) { |
822 | err = -EOPNOTSUPP; |
823 | break; |
824 | } |
825 | err = put_user(wdd->timeout, p); |
826 | break; |
827 | case WDIOC_GETTIMELEFT: |
828 | err = watchdog_get_timeleft(wdd, timeleft: &val); |
829 | if (err < 0) |
830 | break; |
831 | err = put_user(val, p); |
832 | break; |
833 | case WDIOC_SETPRETIMEOUT: |
834 | if (get_user(val, p)) { |
835 | err = -EFAULT; |
836 | break; |
837 | } |
838 | err = watchdog_set_pretimeout(wdd, timeout: val); |
839 | break; |
840 | case WDIOC_GETPRETIMEOUT: |
841 | err = put_user(wdd->pretimeout, p); |
842 | break; |
843 | default: |
844 | err = -ENOTTY; |
845 | break; |
846 | } |
847 | |
848 | out_ioctl: |
849 | mutex_unlock(lock: &wd_data->lock); |
850 | return err; |
851 | } |
852 | |
853 | /* |
854 | * watchdog_open - open the /dev/watchdog* devices |
855 | * @inode: Inode of device |
856 | * @file: File handle to device |
857 | * |
858 | * When the /dev/watchdog* device gets opened, we start the watchdog. |
859 | * Watch out: the /dev/watchdog device is single open, so we make sure |
860 | * it can only be opened once. |
861 | * |
862 | * Return: 0 if successful, error otherwise. |
863 | */ |
864 | static int watchdog_open(struct inode *inode, struct file *file) |
865 | { |
866 | struct watchdog_core_data *wd_data; |
867 | struct watchdog_device *wdd; |
868 | bool hw_running; |
869 | int err; |
870 | |
871 | /* Get the corresponding watchdog device */ |
872 | if (imajor(inode) == MISC_MAJOR) |
873 | wd_data = old_wd_data; |
874 | else |
875 | wd_data = container_of(inode->i_cdev, struct watchdog_core_data, |
876 | cdev); |
877 | |
878 | /* the watchdog is single open! */ |
879 | if (test_and_set_bit(_WDOG_DEV_OPEN, addr: &wd_data->status)) |
880 | return -EBUSY; |
881 | |
882 | wdd = wd_data->wdd; |
883 | |
884 | /* |
885 | * If the /dev/watchdog device is open, we don't want the module |
886 | * to be unloaded. |
887 | */ |
888 | hw_running = watchdog_hw_running(wdd); |
889 | if (!hw_running && !try_module_get(module: wdd->ops->owner)) { |
890 | err = -EBUSY; |
891 | goto out_clear; |
892 | } |
893 | |
894 | err = watchdog_start(wdd); |
895 | if (err < 0) |
896 | goto out_mod; |
897 | |
898 | file->private_data = wd_data; |
899 | |
900 | if (!hw_running) |
901 | get_device(dev: &wd_data->dev); |
902 | |
903 | /* |
904 | * open_timeout only applies for the first open from |
905 | * userspace. Set open_deadline to infinity so that the kernel |
906 | * will take care of an always-running hardware watchdog in |
907 | * case the device gets magic-closed or WDIOS_DISABLECARD is |
908 | * applied. |
909 | */ |
910 | wd_data->open_deadline = KTIME_MAX; |
911 | |
912 | /* dev/watchdog is a virtual (and thus non-seekable) filesystem */ |
913 | return stream_open(inode, filp: file); |
914 | |
915 | out_mod: |
916 | module_put(module: wd_data->wdd->ops->owner); |
917 | out_clear: |
918 | clear_bit(_WDOG_DEV_OPEN, addr: &wd_data->status); |
919 | return err; |
920 | } |
921 | |
922 | static void watchdog_core_data_release(struct device *dev) |
923 | { |
924 | struct watchdog_core_data *wd_data; |
925 | |
926 | wd_data = container_of(dev, struct watchdog_core_data, dev); |
927 | |
928 | kfree(objp: wd_data); |
929 | } |
930 | |
931 | /* |
932 | * watchdog_release - release the watchdog device |
933 | * @inode: Inode of device |
934 | * @file: File handle to device |
935 | * |
936 | * This is the code for when /dev/watchdog gets closed. We will only |
937 | * stop the watchdog when we have received the magic char (and nowayout |
938 | * was not set), else the watchdog will keep running. |
939 | * |
940 | * Always returns 0. |
941 | */ |
942 | static int watchdog_release(struct inode *inode, struct file *file) |
943 | { |
944 | struct watchdog_core_data *wd_data = file->private_data; |
945 | struct watchdog_device *wdd; |
946 | int err = -EBUSY; |
947 | bool running; |
948 | |
949 | mutex_lock(&wd_data->lock); |
950 | |
951 | wdd = wd_data->wdd; |
952 | if (!wdd) |
953 | goto done; |
954 | |
955 | /* |
956 | * We only stop the watchdog if we received the magic character |
957 | * or if WDIOF_MAGICCLOSE is not set. If nowayout was set then |
958 | * watchdog_stop will fail. |
959 | */ |
960 | if (!watchdog_active(wdd)) |
961 | err = 0; |
962 | else if (test_and_clear_bit(_WDOG_ALLOW_RELEASE, addr: &wd_data->status) || |
963 | !(wdd->info->options & WDIOF_MAGICCLOSE)) |
964 | err = watchdog_stop(wdd); |
965 | |
966 | /* If the watchdog was not stopped, send a keepalive ping */ |
967 | if (err < 0) { |
968 | pr_crit("watchdog%d: watchdog did not stop!\n" , wdd->id); |
969 | watchdog_ping(wdd); |
970 | } |
971 | |
972 | watchdog_update_worker(wdd); |
973 | |
974 | /* make sure that /dev/watchdog can be re-opened */ |
975 | clear_bit(_WDOG_DEV_OPEN, addr: &wd_data->status); |
976 | |
977 | done: |
978 | running = wdd && watchdog_hw_running(wdd); |
979 | mutex_unlock(lock: &wd_data->lock); |
980 | /* |
981 | * Allow the owner module to be unloaded again unless the watchdog |
982 | * is still running. If the watchdog is still running, it can not |
983 | * be stopped, and its driver must not be unloaded. |
984 | */ |
985 | if (!running) { |
986 | module_put(module: wd_data->cdev.owner); |
987 | put_device(dev: &wd_data->dev); |
988 | } |
989 | return 0; |
990 | } |
991 | |
992 | static const struct file_operations watchdog_fops = { |
993 | .owner = THIS_MODULE, |
994 | .write = watchdog_write, |
995 | .unlocked_ioctl = watchdog_ioctl, |
996 | .compat_ioctl = compat_ptr_ioctl, |
997 | .open = watchdog_open, |
998 | .release = watchdog_release, |
999 | }; |
1000 | |
1001 | static struct miscdevice watchdog_miscdev = { |
1002 | .minor = WATCHDOG_MINOR, |
1003 | .name = "watchdog" , |
1004 | .fops = &watchdog_fops, |
1005 | }; |
1006 | |
1007 | static struct class watchdog_class = { |
1008 | .name = "watchdog" , |
1009 | .dev_groups = wdt_groups, |
1010 | }; |
1011 | |
1012 | /* |
1013 | * watchdog_cdev_register - register watchdog character device |
1014 | * @wdd: Watchdog device |
1015 | * |
1016 | * Register a watchdog character device including handling the legacy |
1017 | * /dev/watchdog node. /dev/watchdog is actually a miscdevice and |
1018 | * thus we set it up like that. |
1019 | * |
1020 | * Return: 0 if successful, error otherwise. |
1021 | */ |
1022 | static int watchdog_cdev_register(struct watchdog_device *wdd) |
1023 | { |
1024 | struct watchdog_core_data *wd_data; |
1025 | int err; |
1026 | |
1027 | wd_data = kzalloc(size: sizeof(struct watchdog_core_data), GFP_KERNEL); |
1028 | if (!wd_data) |
1029 | return -ENOMEM; |
1030 | mutex_init(&wd_data->lock); |
1031 | |
1032 | wd_data->wdd = wdd; |
1033 | wdd->wd_data = wd_data; |
1034 | |
1035 | if (IS_ERR_OR_NULL(ptr: watchdog_kworker)) { |
1036 | kfree(objp: wd_data); |
1037 | return -ENODEV; |
1038 | } |
1039 | |
1040 | device_initialize(dev: &wd_data->dev); |
1041 | wd_data->dev.devt = MKDEV(MAJOR(watchdog_devt), wdd->id); |
1042 | wd_data->dev.class = &watchdog_class; |
1043 | wd_data->dev.parent = wdd->parent; |
1044 | wd_data->dev.groups = wdd->groups; |
1045 | wd_data->dev.release = watchdog_core_data_release; |
1046 | dev_set_drvdata(dev: &wd_data->dev, data: wdd); |
1047 | err = dev_set_name(dev: &wd_data->dev, name: "watchdog%d" , wdd->id); |
1048 | if (err) { |
1049 | put_device(dev: &wd_data->dev); |
1050 | return err; |
1051 | } |
1052 | |
1053 | kthread_init_work(&wd_data->work, watchdog_ping_work); |
1054 | hrtimer_init(timer: &wd_data->timer, CLOCK_MONOTONIC, mode: HRTIMER_MODE_REL_HARD); |
1055 | wd_data->timer.function = watchdog_timer_expired; |
1056 | watchdog_hrtimer_pretimeout_init(wdd); |
1057 | |
1058 | if (wdd->id == 0) { |
1059 | old_wd_data = wd_data; |
1060 | watchdog_miscdev.parent = wdd->parent; |
1061 | err = misc_register(misc: &watchdog_miscdev); |
1062 | if (err != 0) { |
1063 | pr_err("%s: cannot register miscdev on minor=%d (err=%d).\n" , |
1064 | wdd->info->identity, WATCHDOG_MINOR, err); |
1065 | if (err == -EBUSY) |
1066 | pr_err("%s: a legacy watchdog module is probably present.\n" , |
1067 | wdd->info->identity); |
1068 | old_wd_data = NULL; |
1069 | put_device(dev: &wd_data->dev); |
1070 | return err; |
1071 | } |
1072 | } |
1073 | |
1074 | /* Fill in the data structures */ |
1075 | cdev_init(&wd_data->cdev, &watchdog_fops); |
1076 | |
1077 | /* Add the device */ |
1078 | err = cdev_device_add(cdev: &wd_data->cdev, dev: &wd_data->dev); |
1079 | if (err) { |
1080 | pr_err("watchdog%d unable to add device %d:%d\n" , |
1081 | wdd->id, MAJOR(watchdog_devt), wdd->id); |
1082 | if (wdd->id == 0) { |
1083 | misc_deregister(misc: &watchdog_miscdev); |
1084 | old_wd_data = NULL; |
1085 | } |
1086 | put_device(dev: &wd_data->dev); |
1087 | return err; |
1088 | } |
1089 | |
1090 | wd_data->cdev.owner = wdd->ops->owner; |
1091 | |
1092 | /* Record time of most recent heartbeat as 'just before now'. */ |
1093 | wd_data->last_hw_keepalive = ktime_sub(ktime_get(), 1); |
1094 | watchdog_set_open_deadline(data: wd_data); |
1095 | |
1096 | /* |
1097 | * If the watchdog is running, prevent its driver from being unloaded, |
1098 | * and schedule an immediate ping. |
1099 | */ |
1100 | if (watchdog_hw_running(wdd)) { |
1101 | __module_get(module: wdd->ops->owner); |
1102 | get_device(dev: &wd_data->dev); |
1103 | if (handle_boot_enabled) |
1104 | hrtimer_start(timer: &wd_data->timer, tim: 0, |
1105 | mode: HRTIMER_MODE_REL_HARD); |
1106 | else |
1107 | pr_info("watchdog%d running and kernel based pre-userspace handler disabled\n" , |
1108 | wdd->id); |
1109 | } |
1110 | |
1111 | return 0; |
1112 | } |
1113 | |
1114 | /* |
1115 | * watchdog_cdev_unregister - unregister watchdog character device |
1116 | * @wdd: Watchdog device |
1117 | * |
1118 | * Unregister watchdog character device and if needed the legacy |
1119 | * /dev/watchdog device. |
1120 | */ |
1121 | static void watchdog_cdev_unregister(struct watchdog_device *wdd) |
1122 | { |
1123 | struct watchdog_core_data *wd_data = wdd->wd_data; |
1124 | |
1125 | cdev_device_del(cdev: &wd_data->cdev, dev: &wd_data->dev); |
1126 | if (wdd->id == 0) { |
1127 | misc_deregister(misc: &watchdog_miscdev); |
1128 | old_wd_data = NULL; |
1129 | } |
1130 | |
1131 | if (watchdog_active(wdd) && |
1132 | test_bit(WDOG_STOP_ON_UNREGISTER, &wdd->status)) { |
1133 | watchdog_stop(wdd); |
1134 | } |
1135 | |
1136 | watchdog_hrtimer_pretimeout_stop(wdd); |
1137 | |
1138 | mutex_lock(&wd_data->lock); |
1139 | wd_data->wdd = NULL; |
1140 | wdd->wd_data = NULL; |
1141 | mutex_unlock(lock: &wd_data->lock); |
1142 | |
1143 | hrtimer_cancel(timer: &wd_data->timer); |
1144 | kthread_cancel_work_sync(work: &wd_data->work); |
1145 | |
1146 | put_device(dev: &wd_data->dev); |
1147 | } |
1148 | |
1149 | /** |
1150 | * watchdog_dev_register - register a watchdog device |
1151 | * @wdd: Watchdog device |
1152 | * |
1153 | * Register a watchdog device including handling the legacy |
1154 | * /dev/watchdog node. /dev/watchdog is actually a miscdevice and |
1155 | * thus we set it up like that. |
1156 | * |
1157 | * Return: 0 if successful, error otherwise. |
1158 | */ |
1159 | int watchdog_dev_register(struct watchdog_device *wdd) |
1160 | { |
1161 | int ret; |
1162 | |
1163 | ret = watchdog_cdev_register(wdd); |
1164 | if (ret) |
1165 | return ret; |
1166 | |
1167 | ret = watchdog_register_pretimeout(wdd); |
1168 | if (ret) |
1169 | watchdog_cdev_unregister(wdd); |
1170 | |
1171 | return ret; |
1172 | } |
1173 | |
1174 | /** |
1175 | * watchdog_dev_unregister - unregister a watchdog device |
1176 | * @wdd: watchdog device |
1177 | * |
1178 | * Unregister watchdog device and if needed the legacy |
1179 | * /dev/watchdog device. |
1180 | */ |
1181 | void watchdog_dev_unregister(struct watchdog_device *wdd) |
1182 | { |
1183 | watchdog_unregister_pretimeout(wdd); |
1184 | watchdog_cdev_unregister(wdd); |
1185 | } |
1186 | |
1187 | /** |
1188 | * watchdog_set_last_hw_keepalive - set last HW keepalive time for watchdog |
1189 | * @wdd: Watchdog device |
1190 | * @last_ping_ms: Time since last HW heartbeat |
1191 | * |
1192 | * Adjusts the last known HW keepalive time for a watchdog timer. |
1193 | * This is needed if the watchdog is already running when the probe |
1194 | * function is called, and it can't be pinged immediately. This |
1195 | * function must be called immediately after watchdog registration, |
1196 | * and min_hw_heartbeat_ms must be set for this to be useful. |
1197 | * |
1198 | * Return: 0 if successful, error otherwise. |
1199 | */ |
1200 | int watchdog_set_last_hw_keepalive(struct watchdog_device *wdd, |
1201 | unsigned int last_ping_ms) |
1202 | { |
1203 | struct watchdog_core_data *wd_data; |
1204 | ktime_t now; |
1205 | |
1206 | if (!wdd) |
1207 | return -EINVAL; |
1208 | |
1209 | wd_data = wdd->wd_data; |
1210 | |
1211 | now = ktime_get(); |
1212 | |
1213 | wd_data->last_hw_keepalive = ktime_sub(now, ms_to_ktime(last_ping_ms)); |
1214 | |
1215 | if (watchdog_hw_running(wdd) && handle_boot_enabled) |
1216 | return __watchdog_ping(wdd); |
1217 | |
1218 | return 0; |
1219 | } |
1220 | EXPORT_SYMBOL_GPL(watchdog_set_last_hw_keepalive); |
1221 | |
1222 | /** |
1223 | * watchdog_dev_init - init dev part of watchdog core |
1224 | * |
1225 | * Allocate a range of chardev nodes to use for watchdog devices. |
1226 | * |
1227 | * Return: 0 if successful, error otherwise. |
1228 | */ |
1229 | int __init watchdog_dev_init(void) |
1230 | { |
1231 | int err; |
1232 | |
1233 | watchdog_kworker = kthread_create_worker(flags: 0, namefmt: "watchdogd" ); |
1234 | if (IS_ERR(ptr: watchdog_kworker)) { |
1235 | pr_err("Failed to create watchdog kworker\n" ); |
1236 | return PTR_ERR(ptr: watchdog_kworker); |
1237 | } |
1238 | sched_set_fifo(p: watchdog_kworker->task); |
1239 | |
1240 | err = class_register(class: &watchdog_class); |
1241 | if (err < 0) { |
1242 | pr_err("couldn't register class\n" ); |
1243 | goto err_register; |
1244 | } |
1245 | |
1246 | err = alloc_chrdev_region(&watchdog_devt, 0, MAX_DOGS, "watchdog" ); |
1247 | if (err < 0) { |
1248 | pr_err("watchdog: unable to allocate char dev region\n" ); |
1249 | goto err_alloc; |
1250 | } |
1251 | |
1252 | return 0; |
1253 | |
1254 | err_alloc: |
1255 | class_unregister(class: &watchdog_class); |
1256 | err_register: |
1257 | kthread_destroy_worker(worker: watchdog_kworker); |
1258 | return err; |
1259 | } |
1260 | |
1261 | /** |
1262 | * watchdog_dev_exit - exit dev part of watchdog core |
1263 | * |
1264 | * Release the range of chardev nodes used for watchdog devices. |
1265 | */ |
1266 | void __exit watchdog_dev_exit(void) |
1267 | { |
1268 | unregister_chrdev_region(watchdog_devt, MAX_DOGS); |
1269 | class_unregister(class: &watchdog_class); |
1270 | kthread_destroy_worker(worker: watchdog_kworker); |
1271 | } |
1272 | |
1273 | int watchdog_dev_suspend(struct watchdog_device *wdd) |
1274 | { |
1275 | struct watchdog_core_data *wd_data = wdd->wd_data; |
1276 | int ret = 0; |
1277 | |
1278 | if (!wdd->wd_data) |
1279 | return -ENODEV; |
1280 | |
1281 | /* ping for the last time before suspend */ |
1282 | mutex_lock(&wd_data->lock); |
1283 | if (watchdog_worker_should_ping(wd_data)) |
1284 | ret = __watchdog_ping(wdd: wd_data->wdd); |
1285 | mutex_unlock(lock: &wd_data->lock); |
1286 | |
1287 | if (ret) |
1288 | return ret; |
1289 | |
1290 | /* |
1291 | * make sure that watchdog worker will not kick in when the wdog is |
1292 | * suspended |
1293 | */ |
1294 | hrtimer_cancel(timer: &wd_data->timer); |
1295 | kthread_cancel_work_sync(work: &wd_data->work); |
1296 | |
1297 | return 0; |
1298 | } |
1299 | |
1300 | int watchdog_dev_resume(struct watchdog_device *wdd) |
1301 | { |
1302 | struct watchdog_core_data *wd_data = wdd->wd_data; |
1303 | int ret = 0; |
1304 | |
1305 | if (!wdd->wd_data) |
1306 | return -ENODEV; |
1307 | |
1308 | /* |
1309 | * __watchdog_ping will also retrigger hrtimer and therefore restore the |
1310 | * ping worker if needed. |
1311 | */ |
1312 | mutex_lock(&wd_data->lock); |
1313 | if (watchdog_worker_should_ping(wd_data)) |
1314 | ret = __watchdog_ping(wdd: wd_data->wdd); |
1315 | mutex_unlock(lock: &wd_data->lock); |
1316 | |
1317 | return ret; |
1318 | } |
1319 | |
1320 | module_param(handle_boot_enabled, bool, 0444); |
1321 | MODULE_PARM_DESC(handle_boot_enabled, |
1322 | "Watchdog core auto-updates boot enabled watchdogs before userspace takes over (default=" |
1323 | __MODULE_STRING(IS_ENABLED(CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED)) ")" ); |
1324 | |
1325 | module_param(open_timeout, uint, 0644); |
1326 | MODULE_PARM_DESC(open_timeout, |
1327 | "Maximum time (in seconds, 0 means infinity) for userspace to take over a running watchdog (default=" |
1328 | __MODULE_STRING(CONFIG_WATCHDOG_OPEN_TIMEOUT) ")" ); |
1329 | |