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/hrtimer.h>
28#include <linux/kthread.h>
29
30#define MAX_DOGS	32	/* Maximum number of watchdog devices */
31
32/*
33 * struct watchdog_core_data - watchdog core internal data
34 * @dev:	The watchdog's internal device
35 * @cdev:	The watchdog's Character device.
36 * @wdd:	Pointer to watchdog device.
37 * @lock:	Lock for watchdog core.
38 * @status:	Watchdog core internal status bits.
39 */
40struct watchdog_core_data {
41	struct device dev;
42	struct cdev cdev;
43	struct watchdog_device *wdd;
44	struct mutex lock;
45	ktime_t last_keepalive;
46	ktime_t last_hw_keepalive;
47	ktime_t open_deadline;
48	struct hrtimer timer;
49	struct kthread_work work;
50#if IS_ENABLED(CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT)
51	struct hrtimer pretimeout_timer;
52#endif
53	unsigned long status;		/* Internal status bits */
54#define _WDOG_DEV_OPEN		0	/* Opened ? */
55#define _WDOG_ALLOW_RELEASE	1	/* Did we receive the magic char ? */
56#define _WDOG_KEEPALIVE		2	/* Did we receive a keepalive ? */
57};
58
59/*
60 *	Functions/procedures to be called by the core
61 */
62extern int watchdog_dev_register(struct watchdog_device *);
63extern void watchdog_dev_unregister(struct watchdog_device *);
64extern int __init watchdog_dev_init(void);
65extern void __exit watchdog_dev_exit(void);
66
67static inline bool watchdog_have_pretimeout(struct watchdog_device *wdd)
68{
69	return wdd->info->options & WDIOF_PRETIMEOUT ||
70	       IS_ENABLED(CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT);
71}
72
73#if IS_ENABLED(CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT)
74void watchdog_hrtimer_pretimeout_init(struct watchdog_device *wdd);
75void watchdog_hrtimer_pretimeout_start(struct watchdog_device *wdd);
76void watchdog_hrtimer_pretimeout_stop(struct watchdog_device *wdd);
77#else
78static inline void watchdog_hrtimer_pretimeout_init(struct watchdog_device *wdd) {}
79static inline void watchdog_hrtimer_pretimeout_start(struct watchdog_device *wdd) {}
80static inline void watchdog_hrtimer_pretimeout_stop(struct watchdog_device *wdd) {}
81#endif
82