20 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22 #include <linux/bitops.h>
23 #include <linux/errno.h>
26 #include <linux/kernel.h>
28 #include <linux/module.h>
31 #include <linux/types.h>
32 #include <linux/watchdog.h>
39 #define DRIVER_NAME "ath79-wdt"
41 #define WDT_TIMEOUT 15
43 #define WDOG_CTRL_LAST_RESET BIT(31)
44 #define WDOG_CTRL_ACTION_MASK 3
45 #define WDOG_CTRL_ACTION_NONE 0
46 #define WDOG_CTRL_ACTION_GPI 1
47 #define WDOG_CTRL_ACTION_NMI 2
48 #define WDOG_CTRL_ACTION_FCR 3
60 static unsigned long wdt_flags;
62 #define WDT_FLAGS_BUSY 0
63 #define WDT_FLAGS_EXPECT_CLOSE 1
65 static struct clk *wdt_clk;
66 static unsigned long wdt_freq;
67 static int boot_status;
68 static int max_timeout;
70 static inline void ath79_wdt_keepalive(
void)
77 static inline void ath79_wdt_enable(
void)
79 ath79_wdt_keepalive();
85 static inline void ath79_wdt_disable(
void)
92 static int ath79_wdt_set_timeout(
int val)
94 if (val < 1 || val > max_timeout)
98 ath79_wdt_keepalive();
114 static int ath79_wdt_release(
struct inode *inode,
struct file *file)
119 pr_crit(
"device closed unexpectedly, watchdog timer will not stop!\n");
120 ath79_wdt_keepalive();
129 static ssize_t ath79_wdt_write(
struct file *file,
const char *
data,
130 size_t len, loff_t *ppos)
138 for (i = 0; i != len; i++) {
150 ath79_wdt_keepalive();
159 .firmware_version = 0,
160 .identity =
"ATH79 watchdog",
163 static long ath79_wdt_ioctl(
struct file *file,
unsigned int cmd,
174 sizeof(ath79_wdt_info)) ? -
EFAULT : 0;
186 ath79_wdt_keepalive();
195 err = ath79_wdt_set_timeout(t);
215 .write = ath79_wdt_write,
216 .unlocked_ioctl = ath79_wdt_ioctl,
217 .open = ath79_wdt_open,
218 .release = ath79_wdt_release,
221 static struct miscdevice ath79_wdt_miscdev = {
224 .fops = &ath79_wdt_fops,
234 return PTR_ERR(wdt_clk);
243 goto err_clk_disable;
246 max_timeout = (0xfffffffful / wdt_freq);
247 if (timeout < 1 || timeout > max_timeout) {
248 timeout = max_timeout;
250 "timeout value must be 0 < timeout < %d, using %d\n",
251 max_timeout, timeout);
260 "unable to register misc device, err=%d\n", err);
261 goto err_clk_disable;
288 .shutdown = ath97_wdt_shutdown,
295 static int __init ath79_wdt_init(
void)
301 static void __exit ath79_wdt_exit(
void)