24 #include <linux/kernel.h>
26 #include <linux/module.h>
29 #include <linux/watchdog.h>
36 #include <mach/hardware.h>
38 #define DRIVER_NAME "imx2-wdt"
40 #define IMX2_WDT_WCR 0x00
41 #define IMX2_WDT_WCR_WT (0xFF << 8)
42 #define IMX2_WDT_WCR_WRE (1 << 3)
43 #define IMX2_WDT_WCR_WDE (1 << 2)
45 #define IMX2_WDT_WSR 0x02
46 #define IMX2_WDT_SEQ1 0x5555
47 #define IMX2_WDT_SEQ2 0xAAAA
49 #define IMX2_WDT_WRSR 0x04
50 #define IMX2_WDT_WRSR_TOUT (1 << 1)
52 #define IMX2_WDT_MAX_TIME 128
53 #define IMX2_WDT_DEFAULT_TIME 60
55 #define WDOG_SEC_TO_COUNT(s) ((s * 2 - 1) << 8)
57 #define IMX2_WDT_STATUS_OPEN 0
58 #define IMX2_WDT_STATUS_STARTED 1
59 #define IMX2_WDT_EXPECT_CLOSE 2
73 MODULE_PARM_DESC(nowayout,
"Watchdog cannot be stopped once started (default="
83 .identity =
"imx2+ watchdog",
87 static inline void imx2_wdt_setup(
void)
107 static inline void imx2_wdt_ping(
void)
113 static void imx2_wdt_timer_ping(
unsigned long arg)
117 mod_timer(&imx2_wdt.timer, jiffies + imx2_wdt.timeout *
HZ / 2);
120 static void imx2_wdt_start(
void)
124 clk_prepare_enable(imx2_wdt.clk);
134 static void imx2_wdt_stop(
void)
138 imx2_wdt_timer_ping(0);
141 static void imx2_wdt_set_timeout(
int new_timeout)
160 static int imx2_wdt_close(
struct inode *inode,
struct file *file)
165 dev_crit(imx2_wdt_miscdev.parent,
166 "Unexpected close: Expect reboot!\n");
175 static long imx2_wdt_ioctl(
struct file *file,
unsigned int cmd,
205 imx2_wdt_set_timeout(new_value);
206 imx2_wdt.timeout = new_value;
211 return put_user(imx2_wdt.timeout, p);
218 static ssize_t imx2_wdt_write(
struct file *file,
const char __user *
data,
219 size_t len, loff_t *ppos)
229 for (i = 0; i != len; i++) {
243 .unlocked_ioctl = imx2_wdt_ioctl,
244 .open = imx2_wdt_open,
245 .release = imx2_wdt_close,
246 .write = imx2_wdt_write,
252 .fops = &imx2_wdt_fops,
262 dev_err(&pdev->
dev,
"can't get device resources\n");
267 if (!imx2_wdt.base) {
273 if (IS_ERR(imx2_wdt.clk)) {
274 dev_err(&pdev->
dev,
"can't get Watchdog clock\n");
275 return PTR_ERR(imx2_wdt.clk);
279 if (imx2_wdt.timeout != timeout)
280 dev_warn(&pdev->
dev,
"Initial timeout out of range! "
281 "Clamped from %u to %u\n", timeout, imx2_wdt.timeout);
283 setup_timer(&imx2_wdt.timer, imx2_wdt_timer_ping, 0);
291 "IMX2+ Watchdog Timer enabled. timeout=%ds (nowayout=%d)\n",
292 imx2_wdt.timeout, nowayout);
308 dev_crit(imx2_wdt_miscdev.
parent,
309 "Device removed: Expect reboot!\n");
326 dev_crit(imx2_wdt_miscdev.
parent,
327 "Device shutdown: Expect reboot!\n");
332 { .compatible =
"fsl,imx21-wdt", },
337 .remove =
__exit_p(imx2_wdt_remove),
338 .shutdown = imx2_wdt_shutdown,
342 .of_match_table = imx2_wdt_dt_ids,
346 static int __init imx2_wdt_init(
void)
352 static void __exit imx2_wdt_exit(
void)