X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fchar%2Fwatchdog%2Findydog.c;h=6af2c799b57ef2c76352bd608c9e4de7af65e64e;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=42363f353e71c2bac3bb139d55d7dff162378a19;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/char/watchdog/indydog.c b/drivers/char/watchdog/indydog.c index 42363f353..6af2c799b 100644 --- a/drivers/char/watchdog/indydog.c +++ b/drivers/char/watchdog/indydog.c @@ -12,6 +12,7 @@ */ #include +#include #include #include #include @@ -22,16 +23,11 @@ #include #include #include -#include #include -#include +#include #define PFX "indydog: " -#define WATCHDOG_HEARTBEAT 60 - -static unsigned long indydog_alive; -static struct sgimc_misc_ctrl *mcmisc_regs; -static char expect_close; +static int indydog_alive; #ifdef CONFIG_WATCHDOG_NOWAYOUT static int nowayout = 1; @@ -39,96 +35,71 @@ static int nowayout = 1; static int nowayout = 0; #endif +#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ + module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); static void indydog_start(void) { - u32 mc_ctrl0 = mcmisc_regs->cpuctrl0; - - mc_ctrl0 |= SGIMC_CCTRL0_WDOG; - mcmisc_regs->cpuctrl0 = mc_ctrl0; + u32 mc_ctrl0 = sgimc->cpuctrl0; - printk(KERN_INFO PFX "Started watchdog timer.\n"); + mc_ctrl0 = sgimc->cpuctrl0 | SGIMC_CCTRL0_WDOG; + sgimc->cpuctrl0 = mc_ctrl0; } static void indydog_stop(void) { - u32 mc_ctrl0 = mcmisc_regs->cpuctrl0; + u32 mc_ctrl0 = sgimc->cpuctrl0; mc_ctrl0 &= ~SGIMC_CCTRL0_WDOG; - mcmisc_regs->cpuctrl0 = mc_ctrl0; + sgimc->cpuctrl0 = mc_ctrl0; printk(KERN_INFO PFX "Stopped watchdog timer.\n"); } static void indydog_ping(void) { - mcmisc_regs->watchdogt = 0; + sgimc->watchdogt = 0; } /* * Allow only one person to hold it open */ - static int indydog_open(struct inode *inode, struct file *file) { - if( test_and_set_bit(0,&indydog_alive) ) + if (indydog_alive) return -EBUSY; if (nowayout) __module_get(THIS_MODULE); - /* - * Activate timer - */ + /* Activate timer */ indydog_start(); indydog_ping(); - return 0; + indydog_alive = 1; + printk(KERN_INFO "Started watchdog timer.\n"); + + return nonseekable_open(inode, file); } static int indydog_release(struct inode *inode, struct file *file) { - /* - * Shut off the timer. - * Lock it in if it's a module and we set nowayout - */ - - if (expect_close == 42) { - indydog_stop(); - } else { - printk(KERN_CRIT PFX "WDT device closed unexpectedly. WDT will not stop!\n"); - indydog_ping(); - } - clear_bit(0,&indydog_alive); - expect_close = 0; + /* Shut off the timer. + * Lock it in if it's a module and we defined ...NOWAYOUT */ + if (!nowayout) + indydog_stop(); /* Turn the WDT off */ + + indydog_alive = 0; + return 0; } static ssize_t indydog_write(struct file *file, const char *data, size_t len, loff_t *ppos) { - /* Can't seek (pwrite) on this device */ - if (ppos != &file->f_pos) - return -ESPIPE; - /* Refresh the timer. */ if (len) { - if (!nowayout) { - size_t i; - - /* In case it was set long ago */ - expect_close = 0; - - for (i = 0; i != len; i++) { - char c; - - if (get_user(c, data + i)) - return -EFAULT; - if (c == 'V') - expect_close = 42; - } - } indydog_ping(); } return len; @@ -139,17 +110,18 @@ static int indydog_ioctl(struct inode *inode, struct file *file, { int options, retval = -EINVAL; static struct watchdog_info ident = { - .options = WDIOF_KEEPALIVEPING | - WDIOF_MAGICCLOSE, - .firmware_version = 0, - .identity = "Hardware Watchdog for SGI IP22", + .options = WDIOF_KEEPALIVEPING | + WDIOF_MAGICCLOSE, + .firmware_version = 0, + .identity = "Hardware Watchdog for SGI IP22", }; switch (cmd) { default: return -ENOIOCTLCMD; case WDIOC_GETSUPPORT: - if(copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))) + if (copy_to_user((struct watchdog_info *)arg, + &ident, sizeof(ident))) return -EFAULT; return 0; case WDIOC_GETSTATUS: @@ -165,14 +137,12 @@ static int indydog_ioctl(struct inode *inode, struct file *file, if (get_user(options, (int *)arg)) return -EFAULT; - if (options & WDIOS_DISABLECARD) - { + if (options & WDIOS_DISABLECARD) { indydog_stop(); retval = 0; } - if (options & WDIOS_ENABLECARD) - { + if (options & WDIOS_ENABLECARD) { indydog_start(); retval = 0; } @@ -184,40 +154,38 @@ static int indydog_ioctl(struct inode *inode, struct file *file, static int indydog_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { - if (code==SYS_DOWN || code==SYS_HALT) { - /* Turn the WDT off */ - indydog_stop(); - } + if (code == SYS_DOWN || code == SYS_HALT) + indydog_stop(); /* Turn the WDT off */ return NOTIFY_DONE; } static struct file_operations indydog_fops = { - .owner = THIS_MODULE, - .write = indydog_write, - .ioctl = indydog_ioctl, - .open = indydog_open, - .release= indydog_release, + .owner = THIS_MODULE, + .llseek = no_llseek, + .write = indydog_write, + .ioctl = indydog_ioctl, + .open = indydog_open, + .release = indydog_release, }; static struct miscdevice indydog_miscdev = { - .minor = WATCHDOG_MINOR, - .name = "watchdog", - .fops = &indydog_fops, + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &indydog_fops, }; static struct notifier_block indydog_notifier = { .notifier_call = indydog_notify_sys, }; -static char banner[] __initdata = KERN_INFO PFX "Hardware Watchdog Timer for SGI IP22: 0.3\n"; +static char banner[] __initdata = + KERN_INFO PFX "Hardware Watchdog Timer for SGI IP22: 0.3\n"; static int __init watchdog_init(void) { int ret; - mcmisc_regs = (struct sgimc_misc_ctrl *)(KSEG1+0x1fa00000); - ret = register_reboot_notifier(&indydog_notifier); if (ret) { printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",