Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

watchdog: bcm47xx_wdt.c: convert to watchdog core api

Convert the bcm47xx_wdt.c driver to the new watchdog core api.

The nowayout parameter is now added unconditionally to the module.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Signed-off-by: Wim Van Sebroeck <wim@iguana.be>

authored by

Hauke Mehrtens and committed by
Wim Van Sebroeck
5434a04d 52e5cc4e

+24 -131
+1
drivers/watchdog/Kconfig
··· 997 997 config BCM47XX_WDT 998 998 tristate "Broadcom BCM47xx Watchdog Timer" 999 999 depends on BCM47XX 1000 + select WATCHDOG_CORE 1000 1001 help 1001 1002 Hardware driver for the Broadcom BCM47xx Watchdog Timer. 1002 1003
+23 -131
drivers/watchdog/bcm47xx_wdt.c
··· 14 14 15 15 #include <linux/bitops.h> 16 16 #include <linux/errno.h> 17 - #include <linux/fs.h> 18 17 #include <linux/init.h> 19 18 #include <linux/kernel.h> 20 - #include <linux/miscdevice.h> 21 19 #include <linux/module.h> 22 20 #include <linux/moduleparam.h> 23 21 #include <linux/reboot.h> 24 22 #include <linux/types.h> 25 - #include <linux/uaccess.h> 26 23 #include <linux/watchdog.h> 27 24 #include <linux/timer.h> 28 25 #include <linux/jiffies.h> ··· 38 41 MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default=" 39 42 __MODULE_STRING(WDT_DEFAULT_TIME) ")"); 40 43 41 - #ifdef CONFIG_WATCHDOG_NOWAYOUT 42 44 module_param(nowayout, bool, 0); 43 45 MODULE_PARM_DESC(nowayout, 44 46 "Watchdog cannot be stopped once started (default=" 45 47 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 46 - #endif 47 48 48 - static unsigned long bcm47xx_wdt_busy; 49 - static char expect_release; 50 49 static struct timer_list wdt_timer; 51 50 static atomic_t ticks; 52 51 ··· 90 97 } 91 98 } 92 99 93 - static inline void bcm47xx_wdt_pet(void) 100 + static int bcm47xx_wdt_keepalive(struct watchdog_device *wdd) 94 101 { 95 102 atomic_set(&ticks, wdt_time); 103 + 104 + return 0; 96 105 } 97 106 98 - static void bcm47xx_wdt_start(void) 107 + static int bcm47xx_wdt_start(struct watchdog_device *wdd) 99 108 { 100 109 bcm47xx_wdt_pet(); 101 110 bcm47xx_timer_tick(0); 111 + 112 + return 0; 102 113 } 103 114 104 - static void bcm47xx_wdt_pause(void) 115 + static int bcm47xx_wdt_stop(struct watchdog_device *wdd) 105 116 { 106 117 del_timer_sync(&wdt_timer); 107 118 bcm47xx_wdt_hw_stop(); 119 + 120 + return 0; 108 121 } 109 122 110 - static void bcm47xx_wdt_stop(void) 111 - { 112 - bcm47xx_wdt_pause(); 113 - } 114 - 115 - static int bcm47xx_wdt_settimeout(int new_time) 123 + static int bcm47xx_wdt_set_timeout(struct watchdog_device *wdd, 124 + unsigned int new_time) 116 125 { 117 126 if ((new_time <= 0) || (new_time > WDT_MAX_TIME)) 118 127 return -EINVAL; 119 128 120 129 wdt_time = new_time; 121 130 return 0; 122 - } 123 - 124 - static int bcm47xx_wdt_open(struct inode *inode, struct file *file) 125 - { 126 - if (test_and_set_bit(0, &bcm47xx_wdt_busy)) 127 - return -EBUSY; 128 - 129 - bcm47xx_wdt_start(); 130 - return nonseekable_open(inode, file); 131 - } 132 - 133 - static int bcm47xx_wdt_release(struct inode *inode, struct file *file) 134 - { 135 - if (expect_release == 42) { 136 - bcm47xx_wdt_stop(); 137 - } else { 138 - pr_crit("Unexpected close, not stopping watchdog!\n"); 139 - bcm47xx_wdt_start(); 140 - } 141 - 142 - clear_bit(0, &bcm47xx_wdt_busy); 143 - expect_release = 0; 144 - return 0; 145 - } 146 - 147 - static ssize_t bcm47xx_wdt_write(struct file *file, const char __user *data, 148 - size_t len, loff_t *ppos) 149 - { 150 - if (len) { 151 - if (!nowayout) { 152 - size_t i; 153 - 154 - expect_release = 0; 155 - 156 - for (i = 0; i != len; i++) { 157 - char c; 158 - if (get_user(c, data + i)) 159 - return -EFAULT; 160 - if (c == 'V') 161 - expect_release = 42; 162 - } 163 - } 164 - bcm47xx_wdt_pet(); 165 - } 166 - return len; 167 131 } 168 132 169 133 static const struct watchdog_info bcm47xx_wdt_info = { ··· 130 180 WDIOF_MAGICCLOSE, 131 181 }; 132 182 133 - static long bcm47xx_wdt_ioctl(struct file *file, 134 - unsigned int cmd, unsigned long arg) 135 - { 136 - void __user *argp = (void __user *)arg; 137 - int __user *p = argp; 138 - int new_value, retval = -EINVAL; 139 - 140 - switch (cmd) { 141 - case WDIOC_GETSUPPORT: 142 - return copy_to_user(argp, &bcm47xx_wdt_info, 143 - sizeof(bcm47xx_wdt_info)) ? -EFAULT : 0; 144 - 145 - case WDIOC_GETSTATUS: 146 - case WDIOC_GETBOOTSTATUS: 147 - return put_user(0, p); 148 - 149 - case WDIOC_SETOPTIONS: 150 - if (get_user(new_value, p)) 151 - return -EFAULT; 152 - 153 - if (new_value & WDIOS_DISABLECARD) { 154 - bcm47xx_wdt_stop(); 155 - retval = 0; 156 - } 157 - 158 - if (new_value & WDIOS_ENABLECARD) { 159 - bcm47xx_wdt_start(); 160 - retval = 0; 161 - } 162 - 163 - return retval; 164 - 165 - case WDIOC_KEEPALIVE: 166 - bcm47xx_wdt_pet(); 167 - return 0; 168 - 169 - case WDIOC_SETTIMEOUT: 170 - if (get_user(new_value, p)) 171 - return -EFAULT; 172 - 173 - if (bcm47xx_wdt_settimeout(new_value)) 174 - return -EINVAL; 175 - 176 - bcm47xx_wdt_pet(); 177 - 178 - case WDIOC_GETTIMEOUT: 179 - return put_user(wdt_time, p); 180 - 181 - default: 182 - return -ENOTTY; 183 - } 184 - } 185 - 186 183 static int bcm47xx_wdt_notify_sys(struct notifier_block *this, 187 - unsigned long code, void *unused) 184 + unsigned long code, void *unused) 188 185 { 189 186 if (code == SYS_DOWN || code == SYS_HALT) 190 187 bcm47xx_wdt_stop(); 191 188 return NOTIFY_DONE; 192 189 } 193 190 194 - static const struct file_operations bcm47xx_wdt_fops = { 191 + static struct watchdog_ops bcm47xx_wdt_ops = { 195 192 .owner = THIS_MODULE, 196 - .llseek = no_llseek, 197 - .unlocked_ioctl = bcm47xx_wdt_ioctl, 198 - .open = bcm47xx_wdt_open, 199 - .release = bcm47xx_wdt_release, 200 - .write = bcm47xx_wdt_write, 193 + .start = bcm47xx_wdt_start, 194 + .stop = bcm47xx_wdt_stop, 195 + .ping = bcm47xx_wdt_keepalive, 196 + .set_timeout = bcm47xx_wdt_set_timeout, 201 197 }; 202 198 203 - static struct miscdevice bcm47xx_wdt_miscdev = { 204 - .minor = WATCHDOG_MINOR, 205 - .name = "watchdog", 206 - .fops = &bcm47xx_wdt_fops, 199 + static struct watchdog_device bcm47xx_wdt_wdd = { 200 + .info = &bcm47xx_wdt_info, 201 + .ops = &bcm47xx_wdt_ops, 207 202 }; 208 203 209 204 static struct notifier_block bcm47xx_wdt_notifier = { ··· 169 274 pr_info("wdt_time value must be 0 < wdt_time < %d, using %d\n", 170 275 (WDT_MAX_TIME + 1), wdt_time); 171 276 } 277 + watchdog_set_nowayout(&bcm47xx_wdt_wdd, nowayout); 172 278 173 279 ret = register_reboot_notifier(&bcm47xx_wdt_notifier); 174 280 if (ret) 175 281 return ret; 176 282 177 - ret = misc_register(&bcm47xx_wdt_miscdev); 283 + ret = watchdog_register_device(&bcm47xx_wdt_wdd); 178 284 if (ret) { 179 285 unregister_reboot_notifier(&bcm47xx_wdt_notifier); 180 286 return ret; ··· 188 292 189 293 static void __exit bcm47xx_wdt_exit(void) 190 294 { 191 - if (!nowayout) 192 - bcm47xx_wdt_stop(); 193 - 194 - misc_deregister(&bcm47xx_wdt_miscdev); 295 + watchdog_unregister_device(&bcm47xx_wdt_wdd); 195 296 196 297 unregister_reboot_notifier(&bcm47xx_wdt_notifier); 197 298 } ··· 199 306 MODULE_AUTHOR("Aleksandar Radovanovic"); 200 307 MODULE_DESCRIPTION("Watchdog driver for Broadcom BCM47xx"); 201 308 MODULE_LICENSE("GPL"); 202 - MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);