13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15 #include <linux/bitops.h>
16 #include <linux/errno.h>
19 #include <linux/kernel.h>
21 #include <linux/module.h>
23 #include <linux/reboot.h>
24 #include <linux/types.h>
26 #include <linux/watchdog.h>
32 #define DRV_NAME "bcm47xx_wdt"
34 #define WDT_DEFAULT_TIME 30
35 #define WDT_MAX_TIME 255
44 #ifdef CONFIG_WATCHDOG_NOWAYOUT
47 "Watchdog cannot be stopped once started (default="
51 static unsigned long bcm47xx_wdt_busy;
52 static char expect_release;
56 static inline void bcm47xx_wdt_hw_start(
void)
60 #ifdef CONFIG_BCM47XX_SSB
61 case BCM47XX_BUS_TYPE_SSB:
65 #ifdef CONFIG_BCM47XX_BCMA
66 case BCM47XX_BUS_TYPE_BCMA:
74 static inline int bcm47xx_wdt_hw_stop(
void)
77 #ifdef CONFIG_BCM47XX_SSB
78 case BCM47XX_BUS_TYPE_SSB:
81 #ifdef CONFIG_BCM47XX_BCMA
82 case BCM47XX_BUS_TYPE_BCMA:
90 static void bcm47xx_timer_tick(
unsigned long unused)
93 bcm47xx_wdt_hw_start();
96 pr_crit(
"Watchdog will fire soon!!!\n");
100 static inline void bcm47xx_wdt_pet(
void)
105 static void bcm47xx_wdt_start(
void)
108 bcm47xx_timer_tick(0);
111 static void bcm47xx_wdt_pause(
void)
114 bcm47xx_wdt_hw_stop();
117 static void bcm47xx_wdt_stop(
void)
122 static int bcm47xx_wdt_settimeout(
int new_time)
140 static int bcm47xx_wdt_release(
struct inode *inode,
struct file *file)
142 if (expect_release == 42) {
145 pr_crit(
"Unexpected close, not stopping watchdog!\n");
154 static ssize_t bcm47xx_wdt_write(
struct file *file,
const char __user *
data,
155 size_t len, loff_t *ppos)
163 for (i = 0; i != len; i++) {
183 static long bcm47xx_wdt_ioctl(
struct file *file,
184 unsigned int cmd,
unsigned long arg)
193 sizeof(bcm47xx_wdt_info)) ? -
EFAULT : 0;
223 if (bcm47xx_wdt_settimeout(new_value))
237 unsigned long code,
void *unused)
247 .unlocked_ioctl = bcm47xx_wdt_ioctl,
248 .open = bcm47xx_wdt_open,
249 .release = bcm47xx_wdt_release,
250 .write = bcm47xx_wdt_write,
253 static struct miscdevice bcm47xx_wdt_miscdev = {
256 .fops = &bcm47xx_wdt_fops,
260 .notifier_call = bcm47xx_wdt_notify_sys,
263 static int __init bcm47xx_wdt_init(
void)
267 if (bcm47xx_wdt_hw_stop() < 0)
272 if (bcm47xx_wdt_settimeout(wdt_time)) {
274 pr_info(
"wdt_time value must be 0 < wdt_time < %d, using %d\n",
288 pr_info(
"BCM47xx Watchdog Timer enabled (%d seconds%s)\n",
289 wdt_time, nowayout ?
", nowayout" :
"");
293 static void __exit bcm47xx_wdt_exit(
void)