25 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
27 #include <linux/compiler.h>
28 #include <linux/module.h>
29 #include <linux/kernel.h>
31 #include <linux/types.h>
33 #include <linux/watchdog.h>
36 #include <linux/reboot.h>
40 #include <linux/slab.h>
44 #include <linux/sched.h>
45 #include <linux/signal.h>
59 #define IPC_SET_WATCHDOG_TIMER 0xF8
64 "Watchdog timer margin"
65 "Time between interrupt and resetting the system"
66 "The range is from 1 to 160"
67 "This is the time for all keep alives to arrive");
72 "Default Watchdog timer setting"
74 "The range is from 1 to 170"
75 "This is the time for all keep alives to arrive");
81 static int force_boot;
84 "A value of 1 means that the driver will reboot"
85 "the system immediately if the /dev/watchdog device is closed"
86 "A value of 0 means that when /dev/watchdog device is closed"
87 "the watchdog timer will be refreshed for one more interval"
88 "of length: timer_set. At the end of this interval, the"
89 "watchdog timer will reset the system."
98 static void watchdog_fire(
void)
101 pr_crit(
"Initiating system reboot\n");
103 pr_crit(
"Reboot didn't ?????\n");
107 pr_crit(
"Immediate Reboot Disabled\n");
108 pr_crit(
"System will reset when watchdog timer times out!\n");
112 static int check_timer_margin(
int new_margin)
116 pr_debug(
"value of new_margin %d is out of the range %d to %d\n",
132 ipc_wbuf = (
u32 *)&cbuf;
145 pr_err(
"Error setting SCU watchdog timer: %x\n", ipc_ret);
160 pr_debug(
"irq, int_status: %x\n", int_status);
167 pr_debug(
"spurious interrupt received\n");
184 static int intel_scu_keepalive(
void)
203 static int intel_scu_stop(
void)
209 static int intel_scu_set_heartbeat(
u32 t)
224 pr_debug(
"set_heartbeat: timer freq is %d\n",
226 pr_debug(
"set_heartbeat: timer_set is %x (hex)\n",
228 pr_debug(
"set_hearbeat: timer_margin is %x (hex)\n", timer_margin);
229 pr_debug(
"set_heartbeat: threshold is %x (hex)\n",
231 pr_debug(
"set_heartbeat: soft_threshold is %x (hex)\n",
267 pr_err(
"Unable to set timer\n");
277 hw_pre_value = hw_pre_value & 0xFFFF0000;
284 hw_value = hw_value & 0xFFFF0000;
287 }
while (soft_value != hw_value);
312 static int intel_scu_release(
struct inode *inode,
struct file *file)
324 pr_debug(
"intel_scu_release, without open\n");
330 pr_debug(
"closed, without starting timer\n");
334 pr_crit(
"Unexpected close of /dev/watchdog!\n");
340 intel_scu_keepalive();
349 static ssize_t intel_scu_write(
struct file *file,
357 intel_scu_keepalive();
365 static long intel_scu_ioctl(
struct file *file,
377 .firmware_version = 0,
379 .identity =
"Intel_SCU IOH Watchdog"
386 sizeof(ident)) ? -
EFAULT : 0;
391 intel_scu_keepalive();
398 if (check_timer_margin(new_margin))
401 if (intel_scu_set_heartbeat(new_margin))
417 void *another_unused)
431 .write = intel_scu_write,
432 .unlocked_ioctl = intel_scu_ioctl,
433 .open = intel_scu_open,
434 .release = intel_scu_release,
437 static int __init intel_scu_watchdog_init(
void)
456 pr_err(
"value of timer_set %x (hex) is out of range from %x to %x (hex)\n",
462 if (check_timer_margin(timer_margin))
468 pr_debug(
"timer is not available\n");
473 pr_debug(
"timer %d does not have valid physical memory\n",
486 if (tmp_addr ==
NULL) {
487 pr_debug(
"timer unable to ioremap\n");
508 intel_scu_notify_sys;
512 pr_err(
"cannot register notifier %d)\n", ret);
513 goto register_reboot_error;
522 pr_err(
"cannot register miscdev %d err =%d\n",
524 goto misc_register_error;
528 watchdog_timer_interrupt,
532 pr_err(
"error requesting irq %d\n", ret);
533 goto request_irq_error;
545 register_reboot_error:
551 static void __exit intel_scu_watchdog_exit(
void)