| 1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
| 2 | /* |
| 3 | * watchdog_core.h |
| 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 | * Based on source code of the following authors: |
| 16 | * Matt Domsch <Matt_Domsch@dell.com>, |
| 17 | * Rob Radez <rob@osinvestor.com>, |
| 18 | * Rusty Lynch <rusty@linux.co.intel.com> |
| 19 | * Satyam Sharma <satyam@infradead.org> |
| 20 | * Randy Dunlap <randy.dunlap@oracle.com> |
| 21 | * |
| 22 | * Neither Alan Cox, CymruNet Ltd., Wim Van Sebroeck nor Iguana vzw. |
| 23 | * admit liability nor provide warranty for any of this software. |
| 24 | * This material is provided "AS-IS" and at no charge. |
| 25 | */ |
| 26 | |
| 27 | #include <linux/cdev.h> |
| 28 | #include <linux/device.h> |
| 29 | #include <linux/hrtimer_types.h> |
| 30 | #include <linux/init.h> |
| 31 | #include <linux/kthread.h> |
| 32 | #include <linux/mutex_types.h> |
| 33 | #include <linux/types.h> |
| 34 | #include <linux/watchdog.h> |
| 35 | |
| 36 | #define MAX_DOGS 32 /* Maximum number of watchdog devices */ |
| 37 | |
| 38 | /* |
| 39 | * struct watchdog_core_data - watchdog core internal data |
| 40 | * @dev: The watchdog's internal device |
| 41 | * @cdev: The watchdog's Character device. |
| 42 | * @wdd: Pointer to watchdog device. |
| 43 | * @lock: Lock for watchdog core. |
| 44 | * @status: Watchdog core internal status bits. |
| 45 | */ |
| 46 | struct watchdog_core_data { |
| 47 | struct device dev; |
| 48 | struct cdev cdev; |
| 49 | struct watchdog_device *wdd; |
| 50 | struct mutex lock; |
| 51 | ktime_t last_keepalive; |
| 52 | ktime_t last_hw_keepalive; |
| 53 | ktime_t open_deadline; |
| 54 | struct hrtimer timer; |
| 55 | struct kthread_work work; |
| 56 | #if IS_ENABLED(CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT) |
| 57 | struct hrtimer pretimeout_timer; |
| 58 | #endif |
| 59 | unsigned long status; /* Internal status bits */ |
| 60 | #define _WDOG_DEV_OPEN 0 /* Opened ? */ |
| 61 | #define _WDOG_ALLOW_RELEASE 1 /* Did we receive the magic char ? */ |
| 62 | #define _WDOG_KEEPALIVE 2 /* Did we receive a keepalive ? */ |
| 63 | }; |
| 64 | |
| 65 | /* |
| 66 | * Functions/procedures to be called by the core |
| 67 | */ |
| 68 | extern int watchdog_dev_register(struct watchdog_device *); |
| 69 | extern void watchdog_dev_unregister(struct watchdog_device *); |
| 70 | extern int __init watchdog_dev_init(void); |
| 71 | extern void __exit watchdog_dev_exit(void); |
| 72 | |
| 73 | static inline bool watchdog_have_pretimeout(struct watchdog_device *wdd) |
| 74 | { |
| 75 | return wdd->info->options & WDIOF_PRETIMEOUT || |
| 76 | IS_ENABLED(CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT); |
| 77 | } |
| 78 | |
| 79 | #if IS_ENABLED(CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT) |
| 80 | void watchdog_hrtimer_pretimeout_init(struct watchdog_device *wdd); |
| 81 | void watchdog_hrtimer_pretimeout_start(struct watchdog_device *wdd); |
| 82 | void watchdog_hrtimer_pretimeout_stop(struct watchdog_device *wdd); |
| 83 | #else |
| 84 | static inline void watchdog_hrtimer_pretimeout_init(struct watchdog_device *wdd) {} |
| 85 | static inline void watchdog_hrtimer_pretimeout_start(struct watchdog_device *wdd) {} |
| 86 | static inline void watchdog_hrtimer_pretimeout_stop(struct watchdog_device *wdd) {} |
| 87 | #endif |
| 88 | |