22 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
24 #include <linux/module.h>
25 #include <linux/types.h>
26 #include <linux/kernel.h>
31 #include <linux/watchdog.h>
39 #define XWT_TWCSR0_OFFSET 0x0
40 #define XWT_TWCSR1_OFFSET 0x4
41 #define XWT_TBR_OFFSET 0x8
44 #define XWT_CSR0_WRS_MASK 0x00000008
45 #define XWT_CSR0_WDS_MASK 0x00000004
46 #define XWT_CSR0_EWDT1_MASK 0x00000002
49 #define XWT_CSRX_EWDT2_MASK 0x00000001
52 #define XWT_MAX_SELFTEST_LOOP_COUNT 0x00010000
53 #define XWT_TIMER_FAILED 0xFFFFFFFF
55 #define WATCHDOG_NAME "Xilinx Watchdog"
56 #define PFX WATCHDOG_NAME ": "
69 static u32 control_status_reg;
72 static unsigned long driver_open;
76 static void xwdt_start(
void)
92 static void xwdt_stop(
void)
107 static void xwdt_keepalive(
void)
118 static void xwdt_get_status(
int *
status)
125 new_status = ((control_status_reg &
134 static u32 xwdt_selftest(
void)
147 (timer_value2 == timer_value1)); i++) {
153 if (timer_value2 != timer_value1)
175 static int xwdt_release(
struct inode *inode,
struct file *file)
177 if (expect_close == 42) {
180 pr_crit(
"Unexpected close, not stopping watchdog!\n");
199 static ssize_t xwdt_write(
struct file *file,
const char __user *
buf,
200 size_t len, loff_t *ppos)
203 if (!xdev.nowayout) {
209 for (i = 0; i != len; i++) {
226 .firmware_version = 1,
239 static long xwdt_ioctl(
struct file *file,
unsigned int cmd,
unsigned long arg)
248 uarg.i = (
int __user *)arg;
253 sizeof(ident)) ? -
EFAULT : 0;
256 return put_user(xdev.boot_status, uarg.i);
259 xwdt_get_status(&status);
282 .release = xwdt_release,
283 .unlocked_ioctl = xwdt_ioctl,
301 "clock-frequency",
NULL);
304 pr_warn(
"The watchdog clock frequency cannot be obtained!\n");
315 "xlnx,wdt-interval",
NULL);
317 pr_warn(
"Parameter \"xlnx,wdt-interval\" not found in device tree!\n");
320 xdev.wdt_interval = *tmptr;
324 "xlnx,wdt-enable-once",
NULL);
326 pr_warn(
"Parameter \"xlnx,wdt-enable-once\" not found in device tree!\n");
335 timeout = 2 * ((1<<xdev.wdt_interval) / *pfreq);
340 pr_err(
"memory request failure!\n");
344 xdev.base =
ioremap(xdev.res.start, xdev.res.end - xdev.res.start + 1);
345 if (xdev.base ==
NULL) {
347 pr_err(
"ioremap failure!\n");
351 rc = xwdt_selftest();
353 pr_err(
"SelfTest routine error!\n");
357 xwdt_get_status(&xdev.boot_status);
361 pr_err(
"cannot register miscdev on minor=%d (err=%d)\n",
362 xwdt_miscdev.
minor, rc);
367 pr_info(
"driver loaded (timeout=? sec, nowayout=%d)\n",
370 pr_info(
"driver loaded (timeout=%d sec, nowayout=%d)\n",
371 timeout, xdev.nowayout);
397 { .compatible =
"xlnx,xps-timebase-wdt-1.01.a", },
408 .of_match_table = xwdt_of_match,