1d0173278SGuenter Roeck /* SPDX-License-Identifier: GPL-2.0+ */
26cfb5aa8SWim Van Sebroeck /*
36cfb5aa8SWim Van Sebroeck  *	watchdog_core.h
46cfb5aa8SWim Van Sebroeck  *
56cfb5aa8SWim Van Sebroeck  *	(c) Copyright 2008-2011 Alan Cox <alan@lxorguk.ukuu.org.uk>,
66cfb5aa8SWim Van Sebroeck  *						All Rights Reserved.
76cfb5aa8SWim Van Sebroeck  *
86cfb5aa8SWim Van Sebroeck  *	(c) Copyright 2008-2011 Wim Van Sebroeck <wim@iguana.be>.
96cfb5aa8SWim Van Sebroeck  *
10*7b7d2fdcSCurtis Klein  *	(c) Copyright 2021 Hewlett Packard Enterprise Development LP.
11*7b7d2fdcSCurtis Klein  *
126cfb5aa8SWim Van Sebroeck  *	This source code is part of the generic code that can be used
136cfb5aa8SWim Van Sebroeck  *	by all the watchdog timer drivers.
146cfb5aa8SWim Van Sebroeck  *
156cfb5aa8SWim Van Sebroeck  *	Based on source code of the following authors:
166cfb5aa8SWim Van Sebroeck  *	  Matt Domsch <Matt_Domsch@dell.com>,
176cfb5aa8SWim Van Sebroeck  *	  Rob Radez <rob@osinvestor.com>,
186cfb5aa8SWim Van Sebroeck  *	  Rusty Lynch <rusty@linux.co.intel.com>
196cfb5aa8SWim Van Sebroeck  *	  Satyam Sharma <satyam@infradead.org>
206cfb5aa8SWim Van Sebroeck  *	  Randy Dunlap <randy.dunlap@oracle.com>
216cfb5aa8SWim Van Sebroeck  *
226cfb5aa8SWim Van Sebroeck  *	Neither Alan Cox, CymruNet Ltd., Wim Van Sebroeck nor Iguana vzw.
236cfb5aa8SWim Van Sebroeck  *	admit liability nor provide warranty for any of this software.
246cfb5aa8SWim Van Sebroeck  *	This material is provided "AS-IS" and at no charge.
256cfb5aa8SWim Van Sebroeck  */
266cfb5aa8SWim Van Sebroeck 
27*7b7d2fdcSCurtis Klein #include <linux/hrtimer.h>
28*7b7d2fdcSCurtis Klein #include <linux/kthread.h>
29*7b7d2fdcSCurtis Klein 
3045f5fed3SAlan Cox #define MAX_DOGS	32	/* Maximum number of watchdog devices */
3145f5fed3SAlan Cox 
326cfb5aa8SWim Van Sebroeck /*
33*7b7d2fdcSCurtis Klein  * struct watchdog_core_data - watchdog core internal data
34*7b7d2fdcSCurtis Klein  * @dev:	The watchdog's internal device
35*7b7d2fdcSCurtis Klein  * @cdev:	The watchdog's Character device.
36*7b7d2fdcSCurtis Klein  * @wdd:	Pointer to watchdog device.
37*7b7d2fdcSCurtis Klein  * @lock:	Lock for watchdog core.
38*7b7d2fdcSCurtis Klein  * @status:	Watchdog core internal status bits.
39*7b7d2fdcSCurtis Klein  */
40*7b7d2fdcSCurtis Klein struct watchdog_core_data {
41*7b7d2fdcSCurtis Klein 	struct device dev;
42*7b7d2fdcSCurtis Klein 	struct cdev cdev;
43*7b7d2fdcSCurtis Klein 	struct watchdog_device *wdd;
44*7b7d2fdcSCurtis Klein 	struct mutex lock;
45*7b7d2fdcSCurtis Klein 	ktime_t last_keepalive;
46*7b7d2fdcSCurtis Klein 	ktime_t last_hw_keepalive;
47*7b7d2fdcSCurtis Klein 	ktime_t open_deadline;
48*7b7d2fdcSCurtis Klein 	struct hrtimer timer;
49*7b7d2fdcSCurtis Klein 	struct kthread_work work;
50*7b7d2fdcSCurtis Klein #if IS_ENABLED(CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT)
51*7b7d2fdcSCurtis Klein 	struct hrtimer pretimeout_timer;
52*7b7d2fdcSCurtis Klein #endif
53*7b7d2fdcSCurtis Klein 	unsigned long status;		/* Internal status bits */
54*7b7d2fdcSCurtis Klein #define _WDOG_DEV_OPEN		0	/* Opened ? */
55*7b7d2fdcSCurtis Klein #define _WDOG_ALLOW_RELEASE	1	/* Did we receive the magic char ? */
56*7b7d2fdcSCurtis Klein #define _WDOG_KEEPALIVE		2	/* Did we receive a keepalive ? */
57*7b7d2fdcSCurtis Klein };
58*7b7d2fdcSCurtis Klein 
59*7b7d2fdcSCurtis Klein /*
606cfb5aa8SWim Van Sebroeck  *	Functions/procedures to be called by the core
616cfb5aa8SWim Van Sebroeck  */
62fb5f6658SWim Van Sebroeck extern int watchdog_dev_register(struct watchdog_device *);
6332ecc639SGuenter Roeck extern void watchdog_dev_unregister(struct watchdog_device *);
6432ecc639SGuenter Roeck extern int __init watchdog_dev_init(void);
6545f5fed3SAlan Cox extern void __exit watchdog_dev_exit(void);
66*7b7d2fdcSCurtis Klein 
watchdog_have_pretimeout(struct watchdog_device * wdd)67*7b7d2fdcSCurtis Klein static inline bool watchdog_have_pretimeout(struct watchdog_device *wdd)
68*7b7d2fdcSCurtis Klein {
69*7b7d2fdcSCurtis Klein 	return wdd->info->options & WDIOF_PRETIMEOUT ||
70*7b7d2fdcSCurtis Klein 	       IS_ENABLED(CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT);
71*7b7d2fdcSCurtis Klein }
72*7b7d2fdcSCurtis Klein 
73*7b7d2fdcSCurtis Klein #if IS_ENABLED(CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT)
74*7b7d2fdcSCurtis Klein void watchdog_hrtimer_pretimeout_init(struct watchdog_device *wdd);
75*7b7d2fdcSCurtis Klein void watchdog_hrtimer_pretimeout_start(struct watchdog_device *wdd);
76*7b7d2fdcSCurtis Klein void watchdog_hrtimer_pretimeout_stop(struct watchdog_device *wdd);
77*7b7d2fdcSCurtis Klein #else
watchdog_hrtimer_pretimeout_init(struct watchdog_device * wdd)78*7b7d2fdcSCurtis Klein static inline void watchdog_hrtimer_pretimeout_init(struct watchdog_device *wdd) {}
watchdog_hrtimer_pretimeout_start(struct watchdog_device * wdd)79*7b7d2fdcSCurtis Klein static inline void watchdog_hrtimer_pretimeout_start(struct watchdog_device *wdd) {}
watchdog_hrtimer_pretimeout_stop(struct watchdog_device * wdd)80*7b7d2fdcSCurtis Klein static inline void watchdog_hrtimer_pretimeout_stop(struct watchdog_device *wdd) {}
81*7b7d2fdcSCurtis Klein #endif
82