/*
本模块支持三个加载参数:default_margin、nodeamon与nowayout。
三者的含义分别为:
(1)default_margin:指定看门狗产生中断的时间间隔,以second为单位,模块默认的值为60。
该值必须大于或等于0,设为0则采用默认值。
(2)nodeamon:指定在加载模块的时候,是否建立一个守护进程来进行喂狗。为0则产生守护进程,非0值则不产生;
默认的值为0。不管是否建立专门喂狗的守护进程,一旦在由用户创建的程序中打开了看门狗对应的设备文件,
则在用户程序关闭设备文件之前必须由用户程序完成喂狗动作,否则系统在两次时间间隔中断产生之后会复位。
(3)nowayout:设置在用户打开看门狗设备文件并在相关程序退出之后,是否允许模块被卸载。
非0值则不允许卸载,这时一旦在由用户创建的程序中打开了看门狗对应的设备文件之后,
如果没有用户程序完成喂狗操作,则系统在一定时间之后会进行复位;为0则允许卸载,
并且这时如果不再有用户程序打开着看门狗的设备文件,则在开启专门喂狗的守护进程的情况下,
由守护进程完成喂狗的动作。它默认的值为0,可通过调用write向设备文件写入带‘V’的字符串来设为1;
如果写入的字符串不带有‘V’,则为0。
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/timer.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/fs.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <asm/io.h>
//#include <asm/arch/hardware.h>
#include <linux/kthread.h>
//#include <asm/arch/clock.h>
#include <linux/string.h>
#include <linux/sched.h>
#define OSDRV_MODULE_VERSION_STRING "HISI_WDT-MDC030001 @Hi3518v100"
#define HISILICON_SCTL_BASE 0x20050000
/* define watchdog IO */
#define HIWDT_BASE 0x20040000
#define HIWDT_REG(x) (HIWDT_BASE + (x))
#define HIWDT_LOAD 0x000
#define HIWDT_VALUE 0x004
#define HIWDT_CTRL 0x008
#define HIWDT_INTCLR 0x00C
#define HIWDT_RIS 0x010
#define HIWDT_MIS 0x014
#define HIWDT_LOCK 0xC00
#define HIWDT_UNLOCK_VAL 0x1ACCE551
void __iomem *reg_ctl_base_va;
void __iomem *reg_wdt_base_va;
#define IO_WDT_ADDRESS(x) (reg_wdt_base_va + ((x)-(HIWDT_BASE)))
#define hiwdt_readl(x) readl(IO_WDT_ADDRESS(HIWDT_REG(x)))
#define hiwdt_writel(v,x) writel(v, IO_WDT_ADDRESS(HIWDT_REG(x)))
/* debug */
#define HIDOG_PFX "HiDog: "
#define hidog_dbg(params...) printk(KERN_INFO HIDOG_PFX params)
/* module param */
#define HIDOG_TIMER_MARGIN 60
static int default_margin = HIDOG_TIMER_MARGIN; /* in seconds */
#define HIDOG_TIMER_DEMULTIPLY 9
module_param(default_margin, int, 0);
MODULE_PARM_DESC(default_margin, "Watchdog default_margin in seconds. (0<default_margin<80, default=" __MODULE_STRING(HIDOG_TIMER_MARGIN) ")");
static int nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
static int nodeamon = 0;
module_param(nodeamon, int, 0);
MODULE_PARM_DESC(nodeamon, "By default, a kernel deamon feed watchdog when idle, set 'nodeamon=1' to disable this. (default=0)");
/* watchdog info */
st