Loading drivers/watchdog/alim1535_wdt.c +91 −95 Original line number Diff line number Diff line Loading @@ -19,8 +19,8 @@ #include <linux/fs.h> #include <linux/pci.h> #include <asm/uaccess.h> #include <asm/io.h> #include <linux/uaccess.h> #include <linux/io.h> #define WATCHDOG_NAME "ALi_M1535" #define PFX WATCHDOG_NAME ": " Loading @@ -36,11 +36,15 @@ static DEFINE_SPINLOCK(ali_lock); /* Guards the hardware */ /* module parameters */ static int timeout = WATCHDOG_TIMEOUT; module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (0<timeout<18000, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (0 < timeout < 18000, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); /* * ali_start - start watchdog countdown Loading Loading @@ -111,7 +115,8 @@ static int ali_settimer(int t) ali_timeout_bits = (t/60)|(1<<7); else if (t < 18000) ali_timeout_bits = (t/300)|(1<<6)|(1<<7); else return -EINVAL; else return -EINVAL; timeout = t; return 0; Loading Loading @@ -141,11 +146,12 @@ static ssize_t ali_write(struct file *file, const char __user *data, if (!nowayout) { size_t i; /* note: just in case someone wrote the magic character * five months ago... */ /* note: just in case someone wrote the magic character five months ago... */ ali_expect_release = 0; /* scan to see whether or not we got the magic character */ /* scan to see whether or not we got the magic character */ for (i = 0; i != len; i++) { char c; if (get_user(c, data+i)) Loading @@ -163,7 +169,6 @@ static ssize_t ali_write(struct file *file, const char __user *data, /* * ali_ioctl - handle watchdog ioctls * @inode: VFS inode * @file: VFS file pointer * @cmd: ioctl number * @arg: arguments to the ioctl Loading @@ -172,8 +177,7 @@ static ssize_t ali_write(struct file *file, const char __user *data, * we want an extension to enable irq ack monitoring and the like */ static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) static long ali_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = argp; Loading @@ -187,54 +191,42 @@ static int ali_ioctl(struct inode *inode, struct file *file, switch (cmd) { case WDIOC_GETSUPPORT: return copy_to_user(argp, &ident, sizeof (ident)) ? -EFAULT : 0; return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: return put_user(0, p); case WDIOC_KEEPALIVE: ali_keepalive(); return 0; case WDIOC_SETOPTIONS: { int new_options, retval = -EINVAL; if (get_user(new_options, p)) return -EFAULT; if (new_options & WDIOS_DISABLECARD) { ali_stop(); retval = 0; } if (new_options & WDIOS_ENABLECARD) { ali_start(); retval = 0; } return retval; } case WDIOC_SETTIMEOUT: { int new_timeout; if (get_user(new_timeout, p)) return -EFAULT; if (ali_settimer(new_timeout)) return -EINVAL; ali_keepalive(); /* Fall */ } case WDIOC_GETTIMEOUT: return put_user(timeout, p); default: return -ENOTTY; } Loading Loading @@ -274,10 +266,11 @@ static int ali_release(struct inode *inode, struct file *file) /* * Shut off the timer. */ if (ali_expect_release == 42) { if (ali_expect_release == 42) ali_stop(); } else { printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); else { printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); ali_keepalive(); } clear_bit(0, &ali_is_open); Loading @@ -292,13 +285,11 @@ static int ali_release(struct inode *inode, struct file *file) */ static int ali_notify_sys(struct notifier_block *this, unsigned long code, void *unused) static int ali_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { if (code==SYS_DOWN || code==SYS_HALT) { /* Turn the WDT off */ ali_stop(); } if (code == SYS_DOWN || code == SYS_HALT) ali_stop(); /* Turn the WDT off */ return NOTIFY_DONE; } Loading Loading @@ -355,9 +346,12 @@ static int __init ali_find_watchdog(void) */ pci_read_config_dword(pdev, 0xCC, &wdog); wdog &= ~0x3F; /* Timer bits */ wdog &= ~((1<<27)|(1<<26)|(1<<25)|(1<<24)); /* Issued events */ wdog &= ~((1<<16)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)); /* No monitor bits */ /* Timer bits */ wdog &= ~0x3F; /* Issued events */ wdog &= ~((1<<27)|(1<<26)|(1<<25)|(1<<24)); /* No monitor bits */ wdog &= ~((1<<16)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)); pci_write_config_dword(pdev, 0xCC, wdog); Loading @@ -372,7 +366,7 @@ static const struct file_operations ali_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = ali_write, .ioctl = ali_ioctl, .unlocked_ioctl = ali_ioctl, .open = ali_open, .release = ali_release, }; Loading @@ -399,14 +393,15 @@ static int __init watchdog_init(void) int ret; /* Check whether or not the hardware watchdog is there */ if (ali_find_watchdog() != 0) { if (ali_find_watchdog() != 0) return -ENODEV; } /* Check that the timeout value is within it's range ; if not reset to the default */ /* Check that the timeout value is within it's range; if not reset to the default */ if (timeout < 1 || timeout >= 18000) { timeout = WATCHDOG_TIMEOUT; printk(KERN_INFO PFX "timeout value must be 0<timeout<18000, using %d\n", printk(KERN_INFO PFX "timeout value must be 0 < timeout < 18000, using %d\n", timeout); } Loading @@ -415,14 +410,15 @@ static int __init watchdog_init(void) ret = register_reboot_notifier(&ali_notifier); if (ret != 0) { printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret); printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret); goto out; } ret = misc_register(&ali_miscdev); if (ret != 0) { printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", WATCHDOG_MINOR, ret); goto unreg_reboot; } Loading drivers/watchdog/alim7101_wdt.c +118 −106 Original line number Diff line number Diff line Loading @@ -32,8 +32,8 @@ #include <linux/fs.h> #include <linux/pci.h> #include <asm/io.h> #include <asm/uaccess.h> #include <linux/io.h> #include <linux/uaccess.h> #include <asm/system.h> #define OUR_NAME "alim7101_wdt" Loading @@ -60,13 +60,17 @@ */ #define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ static int timeout = WATCHDOG_TIMEOUT; /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ static int timeout = WATCHDOG_TIMEOUT; module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); static int use_gpio = 0; /* Use the pic (for a1d revision alim7101) */ static int use_gpio; /* Use the pic (for a1d revision alim7101) */ module_param(use_gpio, int, 0); MODULE_PARM_DESC(use_gpio, "Use the gpio watchdog. (required by old cobalt boards)"); MODULE_PARM_DESC(use_gpio, "Use the gpio watchdog (required by old cobalt boards)."); static void wdt_timer_ping(unsigned long); static DEFINE_TIMER(timer, wdt_timer_ping, 0, 1); Loading @@ -77,7 +81,8 @@ static struct pci_dev *alim7101_pmu; static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); /* Loading @@ -91,21 +96,24 @@ static void wdt_timer_ping(unsigned long data) */ char tmp; if(time_before(jiffies, next_heartbeat)) { if (time_before(jiffies, next_heartbeat)) { /* Ping the WDT (this is actually a disarm/arm sequence) */ pci_read_config_byte(alim7101_pmu, 0x92, &tmp); pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp & ~ALI_WDT_ARM)); pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp | ALI_WDT_ARM)); pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp & ~ALI_WDT_ARM)); pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp | ALI_WDT_ARM)); if (use_gpio) { pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp); pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp | 0x20); pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp & ~0x20); pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp); pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp | 0x20); pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp & ~0x20); } } else { printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); } /* Re-set the timer interval */ mod_timer(&timer, jiffies + WDT_INTERVAL); Loading @@ -121,17 +129,23 @@ static void wdt_change(int writeval) pci_read_config_byte(alim7101_pmu, ALI_7101_WDT, &tmp); if (writeval == WDT_ENABLE) { pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp | ALI_WDT_ARM)); pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp | ALI_WDT_ARM)); if (use_gpio) { pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp); pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp & ~0x20); pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp); pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp & ~0x20); } } else { pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp & ~ALI_WDT_ARM)); pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp & ~ALI_WDT_ARM)); if (use_gpio) { pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp); pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp | 0x20); pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp); pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp | 0x20); } } } Loading Loading @@ -169,7 +183,8 @@ static void wdt_keepalive(void) * /dev/watchdog handling */ static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos) static ssize_t fop_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { /* See if we got the magic character 'V' and reload the timer */ if (count) { Loading Loading @@ -211,26 +226,26 @@ static int fop_close(struct inode * inode, struct file * file) wdt_turnoff(); else { /* wim: shouldn't there be a: del_timer(&timer); */ printk(KERN_CRIT PFX "device file closed unexpectedly. Will not stop the WDT!\n"); printk(KERN_CRIT PFX "device file closed unexpectedly. Will not stop the WDT!\n"); } clear_bit(0, &wdt_is_open); wdt_expect_close = 0; return 0; } static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = argp; static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .firmware_version = 1, .identity = "ALiM7101", }; switch(cmd) { switch (cmd) { case WDIOC_GETSUPPORT: return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: Loading @@ -245,17 +260,14 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u if (get_user(new_options, p)) return -EFAULT; if (new_options & WDIOS_DISABLECARD) { wdt_turnoff(); retval = 0; } if (new_options & WDIOS_ENABLECARD) { wdt_startup(); retval = 0; } return retval; } case WDIOC_SETTIMEOUT: Loading @@ -264,10 +276,9 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u if (get_user(new_timeout, p)) return -EFAULT; if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */ /* arbitrary upper limit */ if (new_timeout < 1 || new_timeout > 3600) return -EINVAL; timeout = new_timeout; wdt_keepalive(); /* Fall through */ Loading @@ -285,7 +296,7 @@ static const struct file_operations wdt_fops = { .write = fop_write, .open = fop_open, .release = fop_close, .ioctl= fop_ioctl, .unlocked_ioctl = fop_ioctl, }; static struct miscdevice wdt_miscdev = { Loading @@ -298,16 +309,17 @@ static struct miscdevice wdt_miscdev = { * Notifier for system down */ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { if (code == SYS_DOWN || code == SYS_HALT) wdt_turnoff(); if (code == SYS_RESTART) { /* * Cobalt devices have no way of rebooting themselves other than * getting the watchdog to pull reset, so we restart the watchdog on * reboot with no heartbeat * Cobalt devices have no way of rebooting themselves other * than getting the watchdog to pull reset, so we restart the * watchdog on reboot with no heartbeat */ wdt_change(WDT_ENABLE); printk(KERN_INFO PFX "Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second.\n"); Loading @@ -320,8 +332,7 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void * turn the timebomb registers off. */ static struct notifier_block wdt_notifier= { static struct notifier_block wdt_notifier = { .notifier_call = wdt_notify_sys, }; Loading Loading @@ -354,7 +365,8 @@ static int __init alim7101_wdt_init(void) ali1543_south = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); if (!ali1543_south) { printk(KERN_INFO PFX "ALi 1543 South-Bridge not present - WDT not set\n"); printk(KERN_INFO PFX "ALi 1543 South-Bridge not present - WDT not set\n"); goto err_out; } pci_read_config_byte(ali1543_south, 0x5e, &tmp); Loading @@ -370,17 +382,18 @@ static int __init alim7101_wdt_init(void) goto err_out; } if(timeout < 1 || timeout > 3600) /* arbitrary upper limit */ { if (timeout < 1 || timeout > 3600) { /* arbitrary upper limit */ timeout = WATCHDOG_TIMEOUT; printk(KERN_INFO PFX "timeout value must be 1<=x<=3600, using %d\n", printk(KERN_INFO PFX "timeout value must be 1 <= x <= 3600, using %d\n", timeout); } rc = register_reboot_notifier(&wdt_notifier); if (rc) { printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", rc); printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", rc); goto err_out; } Loading @@ -391,9 +404,8 @@ static int __init alim7101_wdt_init(void) goto err_out_reboot; } if (nowayout) { if (nowayout) __module_get(THIS_MODULE); } printk(KERN_INFO PFX "WDT driver for ALi M7101 initialised. timeout=%d sec (nowayout=%d)\n", timeout, nowayout); Loading Loading
drivers/watchdog/alim1535_wdt.c +91 −95 Original line number Diff line number Diff line Loading @@ -19,8 +19,8 @@ #include <linux/fs.h> #include <linux/pci.h> #include <asm/uaccess.h> #include <asm/io.h> #include <linux/uaccess.h> #include <linux/io.h> #define WATCHDOG_NAME "ALi_M1535" #define PFX WATCHDOG_NAME ": " Loading @@ -36,11 +36,15 @@ static DEFINE_SPINLOCK(ali_lock); /* Guards the hardware */ /* module parameters */ static int timeout = WATCHDOG_TIMEOUT; module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (0<timeout<18000, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (0 < timeout < 18000, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); /* * ali_start - start watchdog countdown Loading Loading @@ -111,7 +115,8 @@ static int ali_settimer(int t) ali_timeout_bits = (t/60)|(1<<7); else if (t < 18000) ali_timeout_bits = (t/300)|(1<<6)|(1<<7); else return -EINVAL; else return -EINVAL; timeout = t; return 0; Loading Loading @@ -141,11 +146,12 @@ static ssize_t ali_write(struct file *file, const char __user *data, if (!nowayout) { size_t i; /* note: just in case someone wrote the magic character * five months ago... */ /* note: just in case someone wrote the magic character five months ago... */ ali_expect_release = 0; /* scan to see whether or not we got the magic character */ /* scan to see whether or not we got the magic character */ for (i = 0; i != len; i++) { char c; if (get_user(c, data+i)) Loading @@ -163,7 +169,6 @@ static ssize_t ali_write(struct file *file, const char __user *data, /* * ali_ioctl - handle watchdog ioctls * @inode: VFS inode * @file: VFS file pointer * @cmd: ioctl number * @arg: arguments to the ioctl Loading @@ -172,8 +177,7 @@ static ssize_t ali_write(struct file *file, const char __user *data, * we want an extension to enable irq ack monitoring and the like */ static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) static long ali_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = argp; Loading @@ -187,54 +191,42 @@ static int ali_ioctl(struct inode *inode, struct file *file, switch (cmd) { case WDIOC_GETSUPPORT: return copy_to_user(argp, &ident, sizeof (ident)) ? -EFAULT : 0; return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: return put_user(0, p); case WDIOC_KEEPALIVE: ali_keepalive(); return 0; case WDIOC_SETOPTIONS: { int new_options, retval = -EINVAL; if (get_user(new_options, p)) return -EFAULT; if (new_options & WDIOS_DISABLECARD) { ali_stop(); retval = 0; } if (new_options & WDIOS_ENABLECARD) { ali_start(); retval = 0; } return retval; } case WDIOC_SETTIMEOUT: { int new_timeout; if (get_user(new_timeout, p)) return -EFAULT; if (ali_settimer(new_timeout)) return -EINVAL; ali_keepalive(); /* Fall */ } case WDIOC_GETTIMEOUT: return put_user(timeout, p); default: return -ENOTTY; } Loading Loading @@ -274,10 +266,11 @@ static int ali_release(struct inode *inode, struct file *file) /* * Shut off the timer. */ if (ali_expect_release == 42) { if (ali_expect_release == 42) ali_stop(); } else { printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); else { printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); ali_keepalive(); } clear_bit(0, &ali_is_open); Loading @@ -292,13 +285,11 @@ static int ali_release(struct inode *inode, struct file *file) */ static int ali_notify_sys(struct notifier_block *this, unsigned long code, void *unused) static int ali_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { if (code==SYS_DOWN || code==SYS_HALT) { /* Turn the WDT off */ ali_stop(); } if (code == SYS_DOWN || code == SYS_HALT) ali_stop(); /* Turn the WDT off */ return NOTIFY_DONE; } Loading Loading @@ -355,9 +346,12 @@ static int __init ali_find_watchdog(void) */ pci_read_config_dword(pdev, 0xCC, &wdog); wdog &= ~0x3F; /* Timer bits */ wdog &= ~((1<<27)|(1<<26)|(1<<25)|(1<<24)); /* Issued events */ wdog &= ~((1<<16)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)); /* No monitor bits */ /* Timer bits */ wdog &= ~0x3F; /* Issued events */ wdog &= ~((1<<27)|(1<<26)|(1<<25)|(1<<24)); /* No monitor bits */ wdog &= ~((1<<16)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)); pci_write_config_dword(pdev, 0xCC, wdog); Loading @@ -372,7 +366,7 @@ static const struct file_operations ali_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = ali_write, .ioctl = ali_ioctl, .unlocked_ioctl = ali_ioctl, .open = ali_open, .release = ali_release, }; Loading @@ -399,14 +393,15 @@ static int __init watchdog_init(void) int ret; /* Check whether or not the hardware watchdog is there */ if (ali_find_watchdog() != 0) { if (ali_find_watchdog() != 0) return -ENODEV; } /* Check that the timeout value is within it's range ; if not reset to the default */ /* Check that the timeout value is within it's range; if not reset to the default */ if (timeout < 1 || timeout >= 18000) { timeout = WATCHDOG_TIMEOUT; printk(KERN_INFO PFX "timeout value must be 0<timeout<18000, using %d\n", printk(KERN_INFO PFX "timeout value must be 0 < timeout < 18000, using %d\n", timeout); } Loading @@ -415,14 +410,15 @@ static int __init watchdog_init(void) ret = register_reboot_notifier(&ali_notifier); if (ret != 0) { printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret); printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret); goto out; } ret = misc_register(&ali_miscdev); if (ret != 0) { printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", WATCHDOG_MINOR, ret); goto unreg_reboot; } Loading
drivers/watchdog/alim7101_wdt.c +118 −106 Original line number Diff line number Diff line Loading @@ -32,8 +32,8 @@ #include <linux/fs.h> #include <linux/pci.h> #include <asm/io.h> #include <asm/uaccess.h> #include <linux/io.h> #include <linux/uaccess.h> #include <asm/system.h> #define OUR_NAME "alim7101_wdt" Loading @@ -60,13 +60,17 @@ */ #define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ static int timeout = WATCHDOG_TIMEOUT; /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ static int timeout = WATCHDOG_TIMEOUT; module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); static int use_gpio = 0; /* Use the pic (for a1d revision alim7101) */ static int use_gpio; /* Use the pic (for a1d revision alim7101) */ module_param(use_gpio, int, 0); MODULE_PARM_DESC(use_gpio, "Use the gpio watchdog. (required by old cobalt boards)"); MODULE_PARM_DESC(use_gpio, "Use the gpio watchdog (required by old cobalt boards)."); static void wdt_timer_ping(unsigned long); static DEFINE_TIMER(timer, wdt_timer_ping, 0, 1); Loading @@ -77,7 +81,8 @@ static struct pci_dev *alim7101_pmu; static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); /* Loading @@ -91,21 +96,24 @@ static void wdt_timer_ping(unsigned long data) */ char tmp; if(time_before(jiffies, next_heartbeat)) { if (time_before(jiffies, next_heartbeat)) { /* Ping the WDT (this is actually a disarm/arm sequence) */ pci_read_config_byte(alim7101_pmu, 0x92, &tmp); pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp & ~ALI_WDT_ARM)); pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp | ALI_WDT_ARM)); pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp & ~ALI_WDT_ARM)); pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp | ALI_WDT_ARM)); if (use_gpio) { pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp); pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp | 0x20); pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp & ~0x20); pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp); pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp | 0x20); pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp & ~0x20); } } else { printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); } /* Re-set the timer interval */ mod_timer(&timer, jiffies + WDT_INTERVAL); Loading @@ -121,17 +129,23 @@ static void wdt_change(int writeval) pci_read_config_byte(alim7101_pmu, ALI_7101_WDT, &tmp); if (writeval == WDT_ENABLE) { pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp | ALI_WDT_ARM)); pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp | ALI_WDT_ARM)); if (use_gpio) { pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp); pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp & ~0x20); pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp); pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp & ~0x20); } } else { pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp & ~ALI_WDT_ARM)); pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp & ~ALI_WDT_ARM)); if (use_gpio) { pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp); pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp | 0x20); pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp); pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp | 0x20); } } } Loading Loading @@ -169,7 +183,8 @@ static void wdt_keepalive(void) * /dev/watchdog handling */ static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos) static ssize_t fop_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { /* See if we got the magic character 'V' and reload the timer */ if (count) { Loading Loading @@ -211,26 +226,26 @@ static int fop_close(struct inode * inode, struct file * file) wdt_turnoff(); else { /* wim: shouldn't there be a: del_timer(&timer); */ printk(KERN_CRIT PFX "device file closed unexpectedly. Will not stop the WDT!\n"); printk(KERN_CRIT PFX "device file closed unexpectedly. Will not stop the WDT!\n"); } clear_bit(0, &wdt_is_open); wdt_expect_close = 0; return 0; } static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = argp; static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .firmware_version = 1, .identity = "ALiM7101", }; switch(cmd) { switch (cmd) { case WDIOC_GETSUPPORT: return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: Loading @@ -245,17 +260,14 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u if (get_user(new_options, p)) return -EFAULT; if (new_options & WDIOS_DISABLECARD) { wdt_turnoff(); retval = 0; } if (new_options & WDIOS_ENABLECARD) { wdt_startup(); retval = 0; } return retval; } case WDIOC_SETTIMEOUT: Loading @@ -264,10 +276,9 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u if (get_user(new_timeout, p)) return -EFAULT; if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */ /* arbitrary upper limit */ if (new_timeout < 1 || new_timeout > 3600) return -EINVAL; timeout = new_timeout; wdt_keepalive(); /* Fall through */ Loading @@ -285,7 +296,7 @@ static const struct file_operations wdt_fops = { .write = fop_write, .open = fop_open, .release = fop_close, .ioctl= fop_ioctl, .unlocked_ioctl = fop_ioctl, }; static struct miscdevice wdt_miscdev = { Loading @@ -298,16 +309,17 @@ static struct miscdevice wdt_miscdev = { * Notifier for system down */ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { if (code == SYS_DOWN || code == SYS_HALT) wdt_turnoff(); if (code == SYS_RESTART) { /* * Cobalt devices have no way of rebooting themselves other than * getting the watchdog to pull reset, so we restart the watchdog on * reboot with no heartbeat * Cobalt devices have no way of rebooting themselves other * than getting the watchdog to pull reset, so we restart the * watchdog on reboot with no heartbeat */ wdt_change(WDT_ENABLE); printk(KERN_INFO PFX "Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second.\n"); Loading @@ -320,8 +332,7 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void * turn the timebomb registers off. */ static struct notifier_block wdt_notifier= { static struct notifier_block wdt_notifier = { .notifier_call = wdt_notify_sys, }; Loading Loading @@ -354,7 +365,8 @@ static int __init alim7101_wdt_init(void) ali1543_south = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); if (!ali1543_south) { printk(KERN_INFO PFX "ALi 1543 South-Bridge not present - WDT not set\n"); printk(KERN_INFO PFX "ALi 1543 South-Bridge not present - WDT not set\n"); goto err_out; } pci_read_config_byte(ali1543_south, 0x5e, &tmp); Loading @@ -370,17 +382,18 @@ static int __init alim7101_wdt_init(void) goto err_out; } if(timeout < 1 || timeout > 3600) /* arbitrary upper limit */ { if (timeout < 1 || timeout > 3600) { /* arbitrary upper limit */ timeout = WATCHDOG_TIMEOUT; printk(KERN_INFO PFX "timeout value must be 1<=x<=3600, using %d\n", printk(KERN_INFO PFX "timeout value must be 1 <= x <= 3600, using %d\n", timeout); } rc = register_reboot_notifier(&wdt_notifier); if (rc) { printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", rc); printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", rc); goto err_out; } Loading @@ -391,9 +404,8 @@ static int __init alim7101_wdt_init(void) goto err_out_reboot; } if (nowayout) { if (nowayout) __module_get(THIS_MODULE); } printk(KERN_INFO PFX "WDT driver for ALi M7101 initialised. timeout=%d sec (nowayout=%d)\n", timeout, nowayout); Loading