27 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
29 #include <linux/kernel.h>
30 #include <linux/compiler.h>
32 #include <linux/module.h>
34 #include <linux/watchdog.h>
54 #define GEF_WDC_ENABLE_SHIFT 24
55 #define GEF_WDC_SERVICE_SHIFT 26
56 #define GEF_WDC_ENABLED_SHIFT 31
58 #define GEF_WDC_ENABLED_TRUE 1
59 #define GEF_WDC_ENABLED_FALSE 0
62 #define GEF_WDOG_FLAG_OPENED 0
64 static unsigned long wdt_flags;
65 static int wdt_status;
66 static void __iomem *gef_wdt_regs;
67 static int gef_wdt_timeout;
68 static int gef_wdt_count;
69 static unsigned int bus_clk;
75 MODULE_PARM_DESC(nowayout,
"Watchdog cannot be stopped once started (default="
79 static int gef_wdt_toggle_wdc(
int enabled_predicate,
int field_shift)
85 spin_lock(&gef_wdt_spinlock);
90 if ((enabled ^ enabled_predicate) == 0) {
92 data = (1 << field_shift) | gef_wdt_count;
95 data = (2 << field_shift) | gef_wdt_count;
99 spin_unlock(&gef_wdt_spinlock);
104 static void gef_wdt_service(
void)
110 static void gef_wdt_handler_enable(
void)
119 static void gef_wdt_handler_disable(
void)
126 static void gef_wdt_set_timeout(
unsigned int timeout)
129 if (timeout > 0xFFFFFFFF / bus_clk)
130 timeout = 0xFFFFFFFF / bus_clk;
133 gef_wdt_count = (timeout * bus_clk) >> 8;
134 gef_wdt_timeout = timeout;
138 static ssize_t gef_wdt_write(
struct file *
file,
const char __user *data,
139 size_t len, loff_t *ppos)
147 for (i = 0; i != len; i++) {
161 static long gef_wdt_ioctl(
struct file *file,
unsigned int cmd,
170 .firmware_version = 0,
171 .identity =
"GE watchdog",
182 if (
put_user(wdt_status, (
int __user *)argp))
188 if (
get_user(options, (
int __user *)argp))
192 gef_wdt_handler_disable();
195 gef_wdt_handler_enable();
204 if (
get_user(timeout, (
int __user *)argp))
206 gef_wdt_set_timeout(timeout);
210 if (
put_user(gef_wdt_timeout, (
int __user *)argp))
221 static int gef_wdt_open(
struct inode *
inode,
struct file *file)
229 gef_wdt_handler_enable();
234 static int gef_wdt_release(
struct inode *inode,
struct file *file)
236 if (expect_close == 42)
237 gef_wdt_handler_disable();
239 pr_crit(
"unexpected close, not stopping timer!\n");
252 .write = gef_wdt_write,
253 .unlocked_ioctl = gef_wdt_ioctl,
254 .open = gef_wdt_open,
255 .release = gef_wdt_release,
261 .fops = &gef_wdt_fops,
278 if (gef_wdt_regs ==
NULL)
281 gef_wdt_set_timeout(timeout);
283 gef_wdt_handler_disable();
292 gef_wdt_handler_disable();
301 .compatible =
"gef,fpga-wdt",
310 .of_match_table = gef_wdt_ids,
312 .probe = gef_wdt_probe,
315 static int __init gef_wdt_init(
void)
317 pr_info(
"GE watchdog driver\n");
321 static void __exit gef_wdt_exit(
void)