20 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
24 #include <linux/kernel.h>
28 #include <linux/module.h>
29 #include <linux/watchdog.h>
37 #define SWCRR_SWTC 0xFFFF0000
38 #define SWCRR_SWEN 0x00000004
39 #define SWCRR_SWRI 0x00000002
40 #define SWCRR_SWPR 0x00000001
53 static int mpc8xxx_wdt_init_late(
void);
58 "Watchdog timeout in ticks. (0<timeout<65536, default=65535)");
60 static bool reset = 1;
63 "Watchdog Interrupt/Reset Mode. 0 = interrupt, 1 = reset");
75 static unsigned int timeout_sec;
77 static unsigned long wdt_is_open;
80 static void mpc8xxx_wdt_keepalive(
void)
83 spin_lock(&wdt_spinlock);
86 spin_unlock(&wdt_spinlock);
89 static void mpc8xxx_wdt_timer_ping(
unsigned long arg);
90 static DEFINE_TIMER(wdt_timer, mpc8xxx_wdt_timer_ping, 0, 0);
92 static void mpc8xxx_wdt_timer_ping(
unsigned long arg)
94 mpc8xxx_wdt_keepalive();
96 mod_timer(&wdt_timer, jiffies +
HZ * timeout_sec / 2);
99 static void mpc8xxx_wdt_pr_warn(
const char *
msg)
101 pr_crit(
"%s, expect the %s soon!\n", msg,
102 reset ?
"reset" :
"machine check exception");
106 size_t count, loff_t *ppos)
109 mpc8xxx_wdt_keepalive();
113 static int mpc8xxx_wdt_open(
struct inode *
inode,
struct file *file)
138 static int mpc8xxx_wdt_release(
struct inode *inode,
struct file *file)
141 mpc8xxx_wdt_timer_ping(0);
143 mpc8xxx_wdt_pr_warn(
"watchdog closed");
148 static long mpc8xxx_wdt_ioctl(
struct file *file,
unsigned int cmd,
155 .firmware_version = 1,
156 .identity =
"MPC8xxx",
166 mpc8xxx_wdt_keepalive();
178 .write = mpc8xxx_wdt_write,
179 .unlocked_ioctl = mpc8xxx_wdt_ioctl,
180 .open = mpc8xxx_wdt_open,
181 .release = mpc8xxx_wdt_release,
184 static struct miscdevice mpc8xxx_wdt_miscdev = {
187 .fops = &mpc8xxx_wdt_fops,
203 wdt_type = match->
data;
205 if (!freq || freq == -1)
214 pr_info(
"could not be enabled in software\n");
226 ret = mpc8xxx_wdt_init_late();
231 pr_info(
"WDT driver for MPC8xxx initialized. mode:%s timeout=%d (%d seconds)\n",
232 reset ?
"reset" :
"interrupt", timeout, timeout_sec);
240 mpc8xxx_wdt_timer_ping(0);
250 mpc8xxx_wdt_pr_warn(
"watchdog removed");
258 static const struct of_device_id mpc8xxx_wdt_match[] = {
260 .compatible =
"mpc83xx_wdt",
262 .prescaler = 0x10000,
266 .compatible =
"fsl,mpc8610-wdt",
268 .prescaler = 0x10000,
273 .compatible =
"fsl,mpc823-wdt",
283 .probe = mpc8xxx_wdt_probe,
286 .name =
"mpc8xxx_wdt",
288 .of_match_table = mpc8xxx_wdt_match,
297 static int mpc8xxx_wdt_init_late(
void)
306 pr_err(
"cannot register miscdev on minor=%d (err=%d)\n",
316 static int __init mpc8xxx_wdt_init(
void)
322 static void __exit mpc8xxx_wdt_exit(
void)