26 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
28 #include <linux/module.h>
30 #include <linux/errno.h>
34 #include <linux/watchdog.h>
41 #include <asm/addrspace.h>
44 #define LONGNAME "TI AR7 Watchdog Timer"
51 static int margin = 60;
59 #define READ_REG(x) readl((void __iomem *)&(x))
60 #define WRITE_REG(x, v) writel((v), (void __iomem *)&(x))
73 static unsigned long wdt_is_open;
74 static unsigned expect_close;
78 #define prescale_value 0xffff
81 static struct resource *ar7_regs_wdt;
85 static struct clk *vbus_clk;
97 pr_err(
"failed to unlock WDT kick reg\n");
100 static void ar7_wdt_prescale(
u32 value)
110 pr_err(
"failed to unlock WDT prescale reg\n");
113 static void ar7_wdt_change(
u32 value)
123 pr_err(
"failed to unlock WDT change reg\n");
126 static void ar7_wdt_disable(
u32 value)
139 pr_err(
"failed to unlock WDT disable reg\n");
142 static void ar7_wdt_update_margin(
int new_margin)
153 ar7_wdt_change(change);
155 pr_info(
"timer margin %d seconds (prescale %d, change %d, freq %d)\n",
159 static void ar7_wdt_enable_wdt(
void)
161 pr_debug(
"enabling watchdog timer\n");
166 static void ar7_wdt_disable_wdt(
void)
168 pr_debug(
"disabling watchdog timer\n");
177 ar7_wdt_enable_wdt();
183 static int ar7_wdt_release(
struct inode *inode,
struct file *file)
186 pr_warn(
"watchdog device closed unexpectedly, will not disable the watchdog timer\n");
188 ar7_wdt_disable_wdt();
193 static ssize_t ar7_wdt_write(
struct file *file,
const char *
data,
194 size_t len, loff_t *ppos)
200 spin_lock(&wdt_lock);
202 spin_unlock(&wdt_lock);
205 for (i = 0; i < len; ++
i) {
217 static long ar7_wdt_ioctl(
struct file *file,
218 unsigned int cmd,
unsigned long arg)
222 .firmware_version = 1,
243 if (
get_user(new_margin, (
int *)arg))
248 spin_lock(&wdt_lock);
249 ar7_wdt_update_margin(new_margin);
251 spin_unlock(&wdt_lock);
264 .write = ar7_wdt_write,
265 .unlocked_ioctl = ar7_wdt_ioctl,
266 .open = ar7_wdt_open,
267 .release = ar7_wdt_release,
274 .fops = &ar7_wdt_fops,
284 pr_err(
"could not get registers resource\n");
290 pr_err(
"could not ioremap registers\n");
295 if (IS_ERR(vbus_clk)) {
296 pr_err(
"could not get vbus clock\n");
297 return PTR_ERR(vbus_clk);
300 ar7_wdt_disable_wdt();
302 ar7_wdt_update_margin(margin);
306 pr_err(
"unable to register misc device\n");
328 ar7_wdt_disable_wdt();
332 .probe = ar7_wdt_probe,
334 .shutdown = ar7_wdt_shutdown,