1 /* 2 * drivers/char/watchdog/shwdt.c 3 * 4 * Watchdog driver for integrated watchdog in the SuperH processors. 5 * 6 * Copyright (C) 2001, 2002, 2003 Paul Mundt <lethal@linux-sh.org> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 * 13 * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com> 14 * Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT 15 * 16 * 19-Apr-2002 Rob Radez <rob@osinvestor.com> 17 * Added expect close support, made emulated timeout runtime changeable 18 * general cleanups, add some ioctls 19 */ 20 #include <linux/module.h> 21 #include <linux/moduleparam.h> 22 #include <linux/init.h> 23 #include <linux/types.h> 24 #include <linux/miscdevice.h> 25 #include <linux/watchdog.h> 26 #include <linux/reboot.h> 27 #include <linux/notifier.h> 28 #include <linux/ioport.h> 29 #include <linux/fs.h> 30 #include <linux/mm.h> 31 #include <linux/io.h> 32 #include <linux/uaccess.h> 33 #include <asm/watchdog.h> 34 35 #define PFX "shwdt: " 36 37 /* 38 * Default clock division ratio is 5.25 msecs. For an additional table of 39 * values, consult the asm-sh/watchdog.h. Overload this at module load 40 * time. 41 * 42 * In order for this to work reliably we need to have HZ set to 1000 or 43 * something quite higher than 100 (or we need a proper high-res timer 44 * implementation that will deal with this properly), otherwise the 10ms 45 * resolution of a jiffy is enough to trigger the overflow. For things like 46 * the SH-4 and SH-5, this isn't necessarily that big of a problem, though 47 * for the SH-2 and SH-3, this isn't recommended unless the WDT is absolutely 48 * necssary. 49 * 50 * As a result of this timing problem, the only modes that are particularly 51 * feasible are the 4096 and the 2048 divisors, which yeild 5.25 and 2.62ms 52 * overflow periods respectively. 53 * 54 * Also, since we can't really expect userspace to be responsive enough 55 * before the overflow happens, we maintain two separate timers .. One in 56 * the kernel for clearing out WOVF every 2ms or so (again, this depends on 57 * HZ == 1000), and another for monitoring userspace writes to the WDT device. 58 * 59 * As such, we currently use a configurable heartbeat interval which defaults 60 * to 30s. In this case, the userspace daemon is only responsible for periodic 61 * writes to the device before the next heartbeat is scheduled. If the daemon 62 * misses its deadline, the kernel timer will allow the WDT to overflow. 63 */ 64 static int clock_division_ratio = WTCSR_CKS_4096; 65 66 #define next_ping_period(cks) msecs_to_jiffies(cks - 4) 67 68 static void sh_wdt_ping(unsigned long data); 69 70 static unsigned long shwdt_is_open; 71 static const struct watchdog_info sh_wdt_info; 72 static char shwdt_expect_close; 73 static DEFINE_TIMER(timer, sh_wdt_ping, 0, 0); 74 static unsigned long next_heartbeat; 75 static DEFINE_SPINLOCK(shwdt_lock); 76 77 #define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ 78 static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ 79 80 static int nowayout = WATCHDOG_NOWAYOUT; 81 82 /** 83 * sh_wdt_start - Start the Watchdog 84 * 85 * Starts the watchdog. 86 */ 87 static void sh_wdt_start(void) 88 { 89 __u8 csr; 90 unsigned long flags; 91 92 spin_lock_irqsave(&shwdt_lock, flags); 93 94 next_heartbeat = jiffies + (heartbeat * HZ); 95 mod_timer(&timer, next_ping_period(clock_division_ratio)); 96 97 csr = sh_wdt_read_csr(); 98 csr |= WTCSR_WT | clock_division_ratio; 99 sh_wdt_write_csr(csr); 100 101 sh_wdt_write_cnt(0); 102 103 /* 104 * These processors have a bit of an inconsistent initialization 105 * process.. starting with SH-3, RSTS was moved to WTCSR, and the 106 * RSTCSR register was removed. 107 * 108 * On the SH-2 however, in addition with bits being in different 109 * locations, we must deal with RSTCSR outright.. 110 */ 111 csr = sh_wdt_read_csr(); 112 csr |= WTCSR_TME; 113 csr &= ~WTCSR_RSTS; 114 sh_wdt_write_csr(csr); 115 116 #ifdef CONFIG_CPU_SH2 117 /* 118 * Whoever came up with the RSTCSR semantics must've been smoking 119 * some of the good stuff, since in addition to the WTCSR/WTCNT write 120 * brain-damage, it's managed to fuck things up one step further.. 121 * 122 * If we need to clear the WOVF bit, the upper byte has to be 0xa5.. 123 * but if we want to touch RSTE or RSTS, the upper byte has to be 124 * 0x5a.. 125 */ 126 csr = sh_wdt_read_rstcsr(); 127 csr &= ~RSTCSR_RSTS; 128 sh_wdt_write_rstcsr(csr); 129 #endif 130 spin_unlock_irqrestore(&shwdt_lock, flags); 131 } 132 133 /** 134 * sh_wdt_stop - Stop the Watchdog 135 * Stops the watchdog. 136 */ 137 static void sh_wdt_stop(void) 138 { 139 __u8 csr; 140 unsigned long flags; 141 142 spin_lock_irqsave(&shwdt_lock, flags); 143 144 del_timer(&timer); 145 146 csr = sh_wdt_read_csr(); 147 csr &= ~WTCSR_TME; 148 sh_wdt_write_csr(csr); 149 spin_unlock_irqrestore(&shwdt_lock, flags); 150 } 151 152 /** 153 * sh_wdt_keepalive - Keep the Userspace Watchdog Alive 154 * The Userspace watchdog got a KeepAlive: schedule the next heartbeat. 155 */ 156 static inline void sh_wdt_keepalive(void) 157 { 158 unsigned long flags; 159 160 spin_lock_irqsave(&shwdt_lock, flags); 161 next_heartbeat = jiffies + (heartbeat * HZ); 162 spin_unlock_irqrestore(&shwdt_lock, flags); 163 } 164 165 /** 166 * sh_wdt_set_heartbeat - Set the Userspace Watchdog heartbeat 167 * Set the Userspace Watchdog heartbeat 168 */ 169 static int sh_wdt_set_heartbeat(int t) 170 { 171 unsigned long flags; 172 173 if (unlikely(t < 1 || t > 3600)) /* arbitrary upper limit */ 174 return -EINVAL; 175 176 spin_lock_irqsave(&shwdt_lock, flags); 177 heartbeat = t; 178 spin_unlock_irqrestore(&shwdt_lock, flags); 179 return 0; 180 } 181 182 /** 183 * sh_wdt_ping - Ping the Watchdog 184 * @data: Unused 185 * 186 * Clears overflow bit, resets timer counter. 187 */ 188 static void sh_wdt_ping(unsigned long data) 189 { 190 unsigned long flags; 191 192 spin_lock_irqsave(&shwdt_lock, flags); 193 if (time_before(jiffies, next_heartbeat)) { 194 __u8 csr; 195 196 csr = sh_wdt_read_csr(); 197 csr &= ~WTCSR_IOVF; 198 sh_wdt_write_csr(csr); 199 200 sh_wdt_write_cnt(0); 201 202 mod_timer(&timer, next_ping_period(clock_division_ratio)); 203 } else 204 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping " 205 "the watchdog\n"); 206 spin_unlock_irqrestore(&shwdt_lock, flags); 207 } 208 209 /** 210 * sh_wdt_open - Open the Device 211 * @inode: inode of device 212 * @file: file handle of device 213 * 214 * Watchdog device is opened and started. 215 */ 216 static int sh_wdt_open(struct inode *inode, struct file *file) 217 { 218 if (test_and_set_bit(0, &shwdt_is_open)) 219 return -EBUSY; 220 if (nowayout) 221 __module_get(THIS_MODULE); 222 223 sh_wdt_start(); 224 225 return nonseekable_open(inode, file); 226 } 227 228 /** 229 * sh_wdt_close - Close the Device 230 * @inode: inode of device 231 * @file: file handle of device 232 * 233 * Watchdog device is closed and stopped. 234 */ 235 static int sh_wdt_close(struct inode *inode, struct file *file) 236 { 237 if (shwdt_expect_close == 42) { 238 sh_wdt_stop(); 239 } else { 240 printk(KERN_CRIT PFX "Unexpected close, not " 241 "stopping watchdog!\n"); 242 sh_wdt_keepalive(); 243 } 244 245 clear_bit(0, &shwdt_is_open); 246 shwdt_expect_close = 0; 247 248 return 0; 249 } 250 251 /** 252 * sh_wdt_write - Write to Device 253 * @file: file handle of device 254 * @buf: buffer to write 255 * @count: length of buffer 256 * @ppos: offset 257 * 258 * Pings the watchdog on write. 259 */ 260 static ssize_t sh_wdt_write(struct file *file, const char *buf, 261 size_t count, loff_t *ppos) 262 { 263 if (count) { 264 if (!nowayout) { 265 size_t i; 266 267 shwdt_expect_close = 0; 268 269 for (i = 0; i != count; i++) { 270 char c; 271 if (get_user(c, buf + i)) 272 return -EFAULT; 273 if (c == 'V') 274 shwdt_expect_close = 42; 275 } 276 } 277 sh_wdt_keepalive(); 278 } 279 280 return count; 281 } 282 283 /** 284 * sh_wdt_mmap - map WDT/CPG registers into userspace 285 * @file: file structure for the device 286 * @vma: VMA to map the registers into 287 * 288 * A simple mmap() implementation for the corner cases where the counter 289 * needs to be mapped in userspace directly. Due to the relatively small 290 * size of the area, neighbouring registers not necessarily tied to the 291 * CPG will also be accessible through the register page, so this remains 292 * configurable for users that really know what they're doing. 293 * 294 * Additionaly, the register page maps in the CPG register base relative 295 * to the nearest page-aligned boundary, which requires that userspace do 296 * the appropriate CPU subtype math for calculating the page offset for 297 * the counter value. 298 */ 299 static int sh_wdt_mmap(struct file *file, struct vm_area_struct *vma) 300 { 301 int ret = -ENOSYS; 302 303 #ifdef CONFIG_SH_WDT_MMAP 304 unsigned long addr; 305 306 /* Only support the simple cases where we map in a register page. */ 307 if (((vma->vm_end - vma->vm_start) != PAGE_SIZE) || vma->vm_pgoff) 308 return -EINVAL; 309 310 /* 311 * Pick WTCNT as the start, it's usually the first register after the 312 * FRQCR, and neither one are generally page-aligned out of the box. 313 */ 314 addr = WTCNT & ~(PAGE_SIZE - 1); 315 316 vma->vm_flags |= VM_IO; 317 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 318 319 if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, 320 PAGE_SIZE, vma->vm_page_prot)) { 321 printk(KERN_ERR PFX "%s: io_remap_pfn_range failed\n", 322 __func__); 323 return -EAGAIN; 324 } 325 326 ret = 0; 327 #endif 328 329 return ret; 330 } 331 332 /** 333 * sh_wdt_ioctl - Query Device 334 * @file: file handle of device 335 * @cmd: watchdog command 336 * @arg: argument 337 * 338 * Query basic information from the device or ping it, as outlined by the 339 * watchdog API. 340 */ 341 static long sh_wdt_ioctl(struct file *file, unsigned int cmd, 342 unsigned long arg) 343 { 344 int new_heartbeat; 345 int options, retval = -EINVAL; 346 347 switch (cmd) { 348 case WDIOC_GETSUPPORT: 349 return copy_to_user((struct watchdog_info *)arg, 350 &sh_wdt_info, sizeof(sh_wdt_info)) ? -EFAULT : 0; 351 case WDIOC_GETSTATUS: 352 case WDIOC_GETBOOTSTATUS: 353 return put_user(0, (int *)arg); 354 case WDIOC_SETOPTIONS: 355 if (get_user(options, (int *)arg)) 356 return -EFAULT; 357 358 if (options & WDIOS_DISABLECARD) { 359 sh_wdt_stop(); 360 retval = 0; 361 } 362 363 if (options & WDIOS_ENABLECARD) { 364 sh_wdt_start(); 365 retval = 0; 366 } 367 368 return retval; 369 case WDIOC_KEEPALIVE: 370 sh_wdt_keepalive(); 371 return 0; 372 case WDIOC_SETTIMEOUT: 373 if (get_user(new_heartbeat, (int *)arg)) 374 return -EFAULT; 375 376 if (sh_wdt_set_heartbeat(new_heartbeat)) 377 return -EINVAL; 378 379 sh_wdt_keepalive(); 380 /* Fall */ 381 case WDIOC_GETTIMEOUT: 382 return put_user(heartbeat, (int *)arg); 383 default: 384 return -ENOTTY; 385 } 386 return 0; 387 } 388 389 /** 390 * sh_wdt_notify_sys - Notifier Handler 391 * @this: notifier block 392 * @code: notifier event 393 * @unused: unused 394 * 395 * Handles specific events, such as turning off the watchdog during a 396 * shutdown event. 397 */ 398 static int sh_wdt_notify_sys(struct notifier_block *this, 399 unsigned long code, void *unused) 400 { 401 if (code == SYS_DOWN || code == SYS_HALT) 402 sh_wdt_stop(); 403 404 return NOTIFY_DONE; 405 } 406 407 static const struct file_operations sh_wdt_fops = { 408 .owner = THIS_MODULE, 409 .llseek = no_llseek, 410 .write = sh_wdt_write, 411 .unlocked_ioctl = sh_wdt_ioctl, 412 .open = sh_wdt_open, 413 .release = sh_wdt_close, 414 .mmap = sh_wdt_mmap, 415 }; 416 417 static const struct watchdog_info sh_wdt_info = { 418 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | 419 WDIOF_MAGICCLOSE, 420 .firmware_version = 1, 421 .identity = "SH WDT", 422 }; 423 424 static struct notifier_block sh_wdt_notifier = { 425 .notifier_call = sh_wdt_notify_sys, 426 }; 427 428 static struct miscdevice sh_wdt_miscdev = { 429 .minor = WATCHDOG_MINOR, 430 .name = "watchdog", 431 .fops = &sh_wdt_fops, 432 }; 433 434 /** 435 * sh_wdt_init - Initialize module 436 * Registers the device and notifier handler. Actual device 437 * initialization is handled by sh_wdt_open(). 438 */ 439 static int __init sh_wdt_init(void) 440 { 441 int rc; 442 443 if (clock_division_ratio < 0x5 || clock_division_ratio > 0x7) { 444 clock_division_ratio = WTCSR_CKS_4096; 445 printk(KERN_INFO PFX 446 "clock_division_ratio value must be 0x5<=x<=0x7, using %d\n", 447 clock_division_ratio); 448 } 449 450 rc = sh_wdt_set_heartbeat(heartbeat); 451 if (unlikely(rc)) { 452 heartbeat = WATCHDOG_HEARTBEAT; 453 printk(KERN_INFO PFX 454 "heartbeat value must be 1<=x<=3600, using %d\n", 455 heartbeat); 456 } 457 458 rc = register_reboot_notifier(&sh_wdt_notifier); 459 if (unlikely(rc)) { 460 printk(KERN_ERR PFX 461 "Can't register reboot notifier (err=%d)\n", rc); 462 return rc; 463 } 464 465 rc = misc_register(&sh_wdt_miscdev); 466 if (unlikely(rc)) { 467 printk(KERN_ERR PFX 468 "Can't register miscdev on minor=%d (err=%d)\n", 469 sh_wdt_miscdev.minor, rc); 470 unregister_reboot_notifier(&sh_wdt_notifier); 471 return rc; 472 } 473 474 printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n", 475 heartbeat, nowayout); 476 477 return 0; 478 } 479 480 /** 481 * sh_wdt_exit - Deinitialize module 482 * Unregisters the device and notifier handler. Actual device 483 * deinitialization is handled by sh_wdt_close(). 484 */ 485 static void __exit sh_wdt_exit(void) 486 { 487 misc_deregister(&sh_wdt_miscdev); 488 unregister_reboot_notifier(&sh_wdt_notifier); 489 } 490 491 MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>"); 492 MODULE_DESCRIPTION("SuperH watchdog driver"); 493 MODULE_LICENSE("GPL"); 494 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 495 496 module_param(clock_division_ratio, int, 0); 497 MODULE_PARM_DESC(clock_division_ratio, "Clock division ratio. Valid ranges are from 0x5 (1.31ms) to 0x7 (5.25ms). (default=" __MODULE_STRING(clock_division_ratio) ")"); 498 499 module_param(heartbeat, int, 0); 500 MODULE_PARM_DESC(heartbeat, 501 "Watchdog heartbeat in seconds. (1 <= heartbeat <= 3600, default=" 502 __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); 503 504 module_param(nowayout, int, 0); 505 MODULE_PARM_DESC(nowayout, 506 "Watchdog cannot be stopped once started (default=" 507 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 508 509 module_init(sh_wdt_init); 510 module_exit(sh_wdt_exit); 511