1 // SPDX-License-Identifier: GPL-2.0+
3 * Watchdog driver for the wm8350
5 * Copyright (C) 2007, 2008 Wolfson Microelectronics <linux@wolfsonmicro.com>
8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10 #include <linux/module.h>
11 #include <linux/moduleparam.h>
12 #include <linux/types.h>
13 #include <linux/kernel.h>
14 #include <linux/platform_device.h>
15 #include <linux/watchdog.h>
16 #include <linux/uaccess.h>
17 #include <linux/mfd/wm8350/core.h>
19 static bool nowayout
= WATCHDOG_NOWAYOUT
;
20 module_param(nowayout
, bool, 0);
21 MODULE_PARM_DESC(nowayout
,
22 "Watchdog cannot be stopped once started (default="
23 __MODULE_STRING(WATCHDOG_NOWAYOUT
) ")");
25 static DEFINE_MUTEX(wdt_mutex
);
28 unsigned int time
; /* Seconds */
29 u16 val
; /* To be set in WM8350_SYSTEM_CONTROL_2 */
30 } wm8350_wdt_cfgs
[] = {
36 static int wm8350_wdt_set_timeout(struct watchdog_device
*wdt_dev
,
39 struct wm8350
*wm8350
= watchdog_get_drvdata(wdt_dev
);
43 for (i
= 0; i
< ARRAY_SIZE(wm8350_wdt_cfgs
); i
++)
44 if (wm8350_wdt_cfgs
[i
].time
== timeout
)
46 if (i
== ARRAY_SIZE(wm8350_wdt_cfgs
))
49 mutex_lock(&wdt_mutex
);
50 wm8350_reg_unlock(wm8350
);
52 reg
= wm8350_reg_read(wm8350
, WM8350_SYSTEM_CONTROL_2
);
53 reg
&= ~WM8350_WDOG_TO_MASK
;
54 reg
|= wm8350_wdt_cfgs
[i
].val
;
55 ret
= wm8350_reg_write(wm8350
, WM8350_SYSTEM_CONTROL_2
, reg
);
57 wm8350_reg_lock(wm8350
);
58 mutex_unlock(&wdt_mutex
);
60 wdt_dev
->timeout
= timeout
;
64 static int wm8350_wdt_start(struct watchdog_device
*wdt_dev
)
66 struct wm8350
*wm8350
= watchdog_get_drvdata(wdt_dev
);
70 mutex_lock(&wdt_mutex
);
71 wm8350_reg_unlock(wm8350
);
73 reg
= wm8350_reg_read(wm8350
, WM8350_SYSTEM_CONTROL_2
);
74 reg
&= ~WM8350_WDOG_MODE_MASK
;
76 ret
= wm8350_reg_write(wm8350
, WM8350_SYSTEM_CONTROL_2
, reg
);
78 wm8350_reg_lock(wm8350
);
79 mutex_unlock(&wdt_mutex
);
84 static int wm8350_wdt_stop(struct watchdog_device
*wdt_dev
)
86 struct wm8350
*wm8350
= watchdog_get_drvdata(wdt_dev
);
90 mutex_lock(&wdt_mutex
);
91 wm8350_reg_unlock(wm8350
);
93 reg
= wm8350_reg_read(wm8350
, WM8350_SYSTEM_CONTROL_2
);
94 reg
&= ~WM8350_WDOG_MODE_MASK
;
95 ret
= wm8350_reg_write(wm8350
, WM8350_SYSTEM_CONTROL_2
, reg
);
97 wm8350_reg_lock(wm8350
);
98 mutex_unlock(&wdt_mutex
);
103 static int wm8350_wdt_ping(struct watchdog_device
*wdt_dev
)
105 struct wm8350
*wm8350
= watchdog_get_drvdata(wdt_dev
);
109 mutex_lock(&wdt_mutex
);
111 reg
= wm8350_reg_read(wm8350
, WM8350_SYSTEM_CONTROL_2
);
112 ret
= wm8350_reg_write(wm8350
, WM8350_SYSTEM_CONTROL_2
, reg
);
114 mutex_unlock(&wdt_mutex
);
119 static const struct watchdog_info wm8350_wdt_info
= {
120 .options
= WDIOF_SETTIMEOUT
| WDIOF_KEEPALIVEPING
| WDIOF_MAGICCLOSE
,
121 .identity
= "WM8350 Watchdog",
124 static const struct watchdog_ops wm8350_wdt_ops
= {
125 .owner
= THIS_MODULE
,
126 .start
= wm8350_wdt_start
,
127 .stop
= wm8350_wdt_stop
,
128 .ping
= wm8350_wdt_ping
,
129 .set_timeout
= wm8350_wdt_set_timeout
,
132 static struct watchdog_device wm8350_wdt
= {
133 .info
= &wm8350_wdt_info
,
134 .ops
= &wm8350_wdt_ops
,
140 static int wm8350_wdt_probe(struct platform_device
*pdev
)
142 struct wm8350
*wm8350
= platform_get_drvdata(pdev
);
145 pr_err("No driver data supplied\n");
149 watchdog_set_nowayout(&wm8350_wdt
, nowayout
);
150 watchdog_set_drvdata(&wm8350_wdt
, wm8350
);
151 wm8350_wdt
.parent
= &pdev
->dev
;
153 /* Default to 4s timeout */
154 wm8350_wdt_set_timeout(&wm8350_wdt
, 4);
156 return watchdog_register_device(&wm8350_wdt
);
159 static int wm8350_wdt_remove(struct platform_device
*pdev
)
161 watchdog_unregister_device(&wm8350_wdt
);
165 static struct platform_driver wm8350_wdt_driver
= {
166 .probe
= wm8350_wdt_probe
,
167 .remove
= wm8350_wdt_remove
,
169 .name
= "wm8350-wdt",
173 module_platform_driver(wm8350_wdt_driver
);
175 MODULE_AUTHOR("Mark Brown");
176 MODULE_DESCRIPTION("WM8350 Watchdog");
177 MODULE_LICENSE("GPL");
178 MODULE_ALIAS("platform:wm8350-wdt");