18 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/watchdog.h>
31 #define MV64x60_WDT_WDC_OFFSET 0
44 #define MV64x60_WDC_ENABLE_SHIFT 24
45 #define MV64x60_WDC_SERVICE_SHIFT 26
46 #define MV64x60_WDC_ENABLED_SHIFT 31
48 #define MV64x60_WDC_ENABLED_TRUE 1
49 #define MV64x60_WDC_ENABLED_FALSE 0
52 #define MV64x60_WDOG_FLAG_OPENED 0
54 static unsigned long wdt_flags;
55 static int wdt_status;
56 static void __iomem *mv64x60_wdt_regs;
57 static int mv64x60_wdt_timeout;
58 static int mv64x60_wdt_count;
59 static unsigned int bus_clk;
66 "Watchdog cannot be stopped once started (default="
69 static int mv64x60_wdt_toggle_wdc(
int enabled_predicate,
int field_shift)
75 spin_lock(&mv64x60_wdt_spinlock);
80 if ((enabled ^ enabled_predicate) == 0) {
82 data = (1 << field_shift) | mv64x60_wdt_count;
85 data = (2 << field_shift) | mv64x60_wdt_count;
89 spin_unlock(&mv64x60_wdt_spinlock);
94 static void mv64x60_wdt_service(
void)
100 static void mv64x60_wdt_handler_enable(
void)
104 mv64x60_wdt_service();
109 static void mv64x60_wdt_handler_disable(
void)
116 static void mv64x60_wdt_set_timeout(
unsigned int timeout)
119 if (timeout > 0xFFFFFFFF / bus_clk)
120 timeout = 0xFFFFFFFF / bus_clk;
122 mv64x60_wdt_count = timeout * bus_clk >> 8;
123 mv64x60_wdt_timeout = timeout;
134 mv64x60_wdt_handler_enable();
139 static int mv64x60_wdt_release(
struct inode *inode,
struct file *file)
141 if (expect_close == 42)
142 mv64x60_wdt_handler_disable();
144 pr_crit(
"unexpected close, not stopping timer!\n");
145 mv64x60_wdt_service();
154 static ssize_t mv64x60_wdt_write(
struct file *file,
const char __user *data,
155 size_t len, loff_t *ppos)
163 for (i = 0; i != len; i++) {
171 mv64x60_wdt_service();
177 static long mv64x60_wdt_ioctl(
struct file *file,
178 unsigned int cmd,
unsigned long arg)
187 .firmware_version = 0,
188 .identity =
"MV64x60 watchdog",
199 if (
put_user(wdt_status, (
int __user *)argp))
208 if (
get_user(options, (
int __user *)argp))
212 mv64x60_wdt_handler_disable();
215 mv64x60_wdt_handler_enable();
219 mv64x60_wdt_service();
224 if (
get_user(timeout, (
int __user *)argp))
226 mv64x60_wdt_set_timeout(timeout);
230 if (
put_user(mv64x60_wdt_timeout, (
int __user *)argp))
244 .write = mv64x60_wdt_write,
245 .unlocked_ioctl = mv64x60_wdt_ioctl,
246 .open = mv64x60_wdt_open,
247 .release = mv64x60_wdt_release,
250 static struct miscdevice mv64x60_wdt_miscdev = {
253 .fops = &mv64x60_wdt_fops,
280 if (mv64x60_wdt_regs ==
NULL)
283 mv64x60_wdt_set_timeout(timeout);
285 mv64x60_wdt_handler_disable();
294 mv64x60_wdt_handler_disable();
302 .probe = mv64x60_wdt_probe,
310 static int __init mv64x60_wdt_init(
void)
312 pr_info(
"MV64x60 watchdog driver\n");
317 static void __exit mv64x60_wdt_exit(
void)