1 /* 2 * i6300esb: Watchdog timer driver for Intel 6300ESB chipset 3 * 4 * (c) Copyright 2004 Google Inc. 5 * (c) Copyright 2005 David Härdeman <david@2gen.com> 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 10 * 2 of the License, or (at your option) any later version. 11 * 12 * based on i810-tco.c which is in turn based on softdog.c 13 * 14 * The timer is implemented in the following I/O controller hubs: 15 * (See the intel documentation on http://developer.intel.com.) 16 * 6300ESB chip : document number 300641-004 17 * 18 * 2004YYZZ Ross Biro 19 * Initial version 0.01 20 * 2004YYZZ Ross Biro 21 * Version 0.02 22 * 20050210 David Härdeman <david@2gen.com> 23 * Ported driver to kernel 2.6 24 */ 25 26 /* 27 * Includes, defines, variables, module parameters, ... 28 */ 29 30 #include <linux/module.h> 31 #include <linux/types.h> 32 #include <linux/kernel.h> 33 #include <linux/fs.h> 34 #include <linux/mm.h> 35 #include <linux/miscdevice.h> 36 #include <linux/watchdog.h> 37 #include <linux/platform_device.h> 38 #include <linux/init.h> 39 #include <linux/pci.h> 40 #include <linux/ioport.h> 41 #include <linux/uaccess.h> 42 #include <linux/io.h> 43 44 /* Module and version information */ 45 #define ESB_VERSION "0.04" 46 #define ESB_MODULE_NAME "i6300ESB timer" 47 #define ESB_DRIVER_NAME ESB_MODULE_NAME ", v" ESB_VERSION 48 #define PFX ESB_MODULE_NAME ": " 49 50 /* PCI configuration registers */ 51 #define ESB_CONFIG_REG 0x60 /* Config register */ 52 #define ESB_LOCK_REG 0x68 /* WDT lock register */ 53 54 /* Memory mapped registers */ 55 #define ESB_TIMER1_REG (BASEADDR + 0x00)/* Timer1 value after each reset */ 56 #define ESB_TIMER2_REG (BASEADDR + 0x04)/* Timer2 value after each reset */ 57 #define ESB_GINTSR_REG (BASEADDR + 0x08)/* General Interrupt Status Register */ 58 #define ESB_RELOAD_REG (BASEADDR + 0x0c)/* Reload register */ 59 60 /* Lock register bits */ 61 #define ESB_WDT_FUNC (0x01 << 2) /* Watchdog functionality */ 62 #define ESB_WDT_ENABLE (0x01 << 1) /* Enable WDT */ 63 #define ESB_WDT_LOCK (0x01 << 0) /* Lock (nowayout) */ 64 65 /* Config register bits */ 66 #define ESB_WDT_REBOOT (0x01 << 5) /* Enable reboot on timeout */ 67 #define ESB_WDT_FREQ (0x01 << 2) /* Decrement frequency */ 68 #define ESB_WDT_INTTYPE (0x11 << 0) /* Interrupt type on timer1 timeout */ 69 70 /* Reload register bits */ 71 #define ESB_WDT_TIMEOUT (0x01 << 9) /* Watchdog timed out */ 72 #define ESB_WDT_RELOAD (0x01 << 8) /* prevent timeout */ 73 74 /* Magic constants */ 75 #define ESB_UNLOCK1 0x80 /* Step 1 to unlock reset registers */ 76 #define ESB_UNLOCK2 0x86 /* Step 2 to unlock reset registers */ 77 78 /* internal variables */ 79 static void __iomem *BASEADDR; 80 static DEFINE_SPINLOCK(esb_lock); /* Guards the hardware */ 81 static unsigned long timer_alive; 82 static struct pci_dev *esb_pci; 83 static unsigned short triggered; /* The status of the watchdog upon boot */ 84 static char esb_expect_close; 85 static struct platform_device *esb_platform_device; 86 87 /* module parameters */ 88 /* 30 sec default heartbeat (1 < heartbeat < 2*1023) */ 89 #define WATCHDOG_HEARTBEAT 30 90 static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ 91 module_param(heartbeat, int, 0); 92 MODULE_PARM_DESC(heartbeat, 93 "Watchdog heartbeat in seconds. (1<heartbeat<2046, default=" 94 __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); 95 96 static int nowayout = WATCHDOG_NOWAYOUT; 97 module_param(nowayout, int, 0); 98 MODULE_PARM_DESC(nowayout, 99 "Watchdog cannot be stopped once started (default=" 100 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 101 102 /* 103 * Some i6300ESB specific functions 104 */ 105 106 /* 107 * Prepare for reloading the timer by unlocking the proper registers. 108 * This is performed by first writing 0x80 followed by 0x86 to the 109 * reload register. After this the appropriate registers can be written 110 * to once before they need to be unlocked again. 111 */ 112 static inline void esb_unlock_registers(void) 113 { 114 writeb(ESB_UNLOCK1, ESB_RELOAD_REG); 115 writeb(ESB_UNLOCK2, ESB_RELOAD_REG); 116 } 117 118 static int esb_timer_start(void) 119 { 120 u8 val; 121 122 spin_lock(&esb_lock); 123 esb_unlock_registers(); 124 writew(ESB_WDT_RELOAD, ESB_RELOAD_REG); 125 /* Enable or Enable + Lock? */ 126 val = ESB_WDT_ENABLE | (nowayout ? ESB_WDT_LOCK : 0x00); 127 pci_write_config_byte(esb_pci, ESB_LOCK_REG, val); 128 spin_unlock(&esb_lock); 129 return 0; 130 } 131 132 static int esb_timer_stop(void) 133 { 134 u8 val; 135 136 spin_lock(&esb_lock); 137 /* First, reset timers as suggested by the docs */ 138 esb_unlock_registers(); 139 writew(ESB_WDT_RELOAD, ESB_RELOAD_REG); 140 /* Then disable the WDT */ 141 pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x0); 142 pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val); 143 spin_unlock(&esb_lock); 144 145 /* Returns 0 if the timer was disabled, non-zero otherwise */ 146 return val & ESB_WDT_ENABLE; 147 } 148 149 static void esb_timer_keepalive(void) 150 { 151 spin_lock(&esb_lock); 152 esb_unlock_registers(); 153 writew(ESB_WDT_RELOAD, ESB_RELOAD_REG); 154 /* FIXME: Do we need to flush anything here? */ 155 spin_unlock(&esb_lock); 156 } 157 158 static int esb_timer_set_heartbeat(int time) 159 { 160 u32 val; 161 162 if (time < 0x1 || time > (2 * 0x03ff)) 163 return -EINVAL; 164 165 spin_lock(&esb_lock); 166 167 /* We shift by 9, so if we are passed a value of 1 sec, 168 * val will be 1 << 9 = 512, then write that to two 169 * timers => 2 * 512 = 1024 (which is decremented at 1KHz) 170 */ 171 val = time << 9; 172 173 /* Write timer 1 */ 174 esb_unlock_registers(); 175 writel(val, ESB_TIMER1_REG); 176 177 /* Write timer 2 */ 178 esb_unlock_registers(); 179 writel(val, ESB_TIMER2_REG); 180 181 /* Reload */ 182 esb_unlock_registers(); 183 writew(ESB_WDT_RELOAD, ESB_RELOAD_REG); 184 185 /* FIXME: Do we need to flush everything out? */ 186 187 /* Done */ 188 heartbeat = time; 189 spin_unlock(&esb_lock); 190 return 0; 191 } 192 193 /* 194 * /dev/watchdog handling 195 */ 196 197 static int esb_open(struct inode *inode, struct file *file) 198 { 199 /* /dev/watchdog can only be opened once */ 200 if (test_and_set_bit(0, &timer_alive)) 201 return -EBUSY; 202 203 /* Reload and activate timer */ 204 esb_timer_start(); 205 206 return nonseekable_open(inode, file); 207 } 208 209 static int esb_release(struct inode *inode, struct file *file) 210 { 211 /* Shut off the timer. */ 212 if (esb_expect_close == 42) 213 esb_timer_stop(); 214 else { 215 printk(KERN_CRIT PFX 216 "Unexpected close, not stopping watchdog!\n"); 217 esb_timer_keepalive(); 218 } 219 clear_bit(0, &timer_alive); 220 esb_expect_close = 0; 221 return 0; 222 } 223 224 static ssize_t esb_write(struct file *file, const char __user *data, 225 size_t len, loff_t *ppos) 226 { 227 /* See if we got the magic character 'V' and reload the timer */ 228 if (len) { 229 if (!nowayout) { 230 size_t i; 231 232 /* note: just in case someone wrote the magic character 233 * five months ago... */ 234 esb_expect_close = 0; 235 236 /* scan to see whether or not we got the 237 * magic character */ 238 for (i = 0; i != len; i++) { 239 char c; 240 if (get_user(c, data + i)) 241 return -EFAULT; 242 if (c == 'V') 243 esb_expect_close = 42; 244 } 245 } 246 247 /* someone wrote to us, we should reload the timer */ 248 esb_timer_keepalive(); 249 } 250 return len; 251 } 252 253 static long esb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 254 { 255 int new_options, retval = -EINVAL; 256 int new_heartbeat; 257 void __user *argp = (void __user *)arg; 258 int __user *p = argp; 259 static struct watchdog_info ident = { 260 .options = WDIOF_SETTIMEOUT | 261 WDIOF_KEEPALIVEPING | 262 WDIOF_MAGICCLOSE, 263 .firmware_version = 0, 264 .identity = ESB_MODULE_NAME, 265 }; 266 267 switch (cmd) { 268 case WDIOC_GETSUPPORT: 269 return copy_to_user(argp, &ident, 270 sizeof(ident)) ? -EFAULT : 0; 271 272 case WDIOC_GETSTATUS: 273 return put_user(0, p); 274 275 case WDIOC_GETBOOTSTATUS: 276 return put_user(triggered, p); 277 278 case WDIOC_SETOPTIONS: 279 { 280 if (get_user(new_options, p)) 281 return -EFAULT; 282 283 if (new_options & WDIOS_DISABLECARD) { 284 esb_timer_stop(); 285 retval = 0; 286 } 287 288 if (new_options & WDIOS_ENABLECARD) { 289 esb_timer_start(); 290 retval = 0; 291 } 292 return retval; 293 } 294 case WDIOC_KEEPALIVE: 295 esb_timer_keepalive(); 296 return 0; 297 298 case WDIOC_SETTIMEOUT: 299 { 300 if (get_user(new_heartbeat, p)) 301 return -EFAULT; 302 if (esb_timer_set_heartbeat(new_heartbeat)) 303 return -EINVAL; 304 esb_timer_keepalive(); 305 /* Fall */ 306 } 307 case WDIOC_GETTIMEOUT: 308 return put_user(heartbeat, p); 309 default: 310 return -ENOTTY; 311 } 312 } 313 314 /* 315 * Kernel Interfaces 316 */ 317 318 static const struct file_operations esb_fops = { 319 .owner = THIS_MODULE, 320 .llseek = no_llseek, 321 .write = esb_write, 322 .unlocked_ioctl = esb_ioctl, 323 .open = esb_open, 324 .release = esb_release, 325 }; 326 327 static struct miscdevice esb_miscdev = { 328 .minor = WATCHDOG_MINOR, 329 .name = "watchdog", 330 .fops = &esb_fops, 331 }; 332 333 /* 334 * Data for PCI driver interface 335 * 336 * This data only exists for exporting the supported 337 * PCI ids via MODULE_DEVICE_TABLE. We do not actually 338 * register a pci_driver, because someone else might one day 339 * want to register another driver on the same PCI id. 340 */ 341 static struct pci_device_id esb_pci_tbl[] = { 342 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), }, 343 { 0, }, /* End of list */ 344 }; 345 MODULE_DEVICE_TABLE(pci, esb_pci_tbl); 346 347 /* 348 * Init & exit routines 349 */ 350 351 static unsigned char __devinit esb_getdevice(void) 352 { 353 /* 354 * Find the PCI device 355 */ 356 357 esb_pci = pci_get_device(PCI_VENDOR_ID_INTEL, 358 PCI_DEVICE_ID_INTEL_ESB_9, NULL); 359 360 if (!esb_pci) 361 return 0; 362 363 if (pci_enable_device(esb_pci)) { 364 printk(KERN_ERR PFX "failed to enable device\n"); 365 goto err_devput; 366 } 367 368 if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) { 369 printk(KERN_ERR PFX "failed to request region\n"); 370 goto err_disable; 371 } 372 373 BASEADDR = pci_ioremap_bar(esb_pci, 0); 374 if (BASEADDR == NULL) { 375 /* Something's wrong here, BASEADDR has to be set */ 376 printk(KERN_ERR PFX "failed to get BASEADDR\n"); 377 goto err_release; 378 } 379 380 /* Done */ 381 return 1; 382 383 err_release: 384 pci_release_region(esb_pci, 0); 385 err_disable: 386 pci_disable_device(esb_pci); 387 err_devput: 388 pci_dev_put(esb_pci); 389 return 0; 390 } 391 392 static void __devinit esb_initdevice(void) 393 { 394 u8 val1; 395 u16 val2; 396 397 /* 398 * Config register: 399 * Bit 5 : 0 = Enable WDT_OUTPUT 400 * Bit 2 : 0 = set the timer frequency to the PCI clock 401 * divided by 2^15 (approx 1KHz). 402 * Bits 1:0 : 11 = WDT_INT_TYPE Disabled. 403 * The watchdog has two timers, it can be setup so that the 404 * expiry of timer1 results in an interrupt and the expiry of 405 * timer2 results in a reboot. We set it to not generate 406 * any interrupts as there is not much we can do with it 407 * right now. 408 */ 409 pci_write_config_word(esb_pci, ESB_CONFIG_REG, 0x0003); 410 411 /* Check that the WDT isn't already locked */ 412 pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val1); 413 if (val1 & ESB_WDT_LOCK) 414 printk(KERN_WARNING PFX "nowayout already set\n"); 415 416 /* Set the timer to watchdog mode and disable it for now */ 417 pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x00); 418 419 /* Check if the watchdog was previously triggered */ 420 esb_unlock_registers(); 421 val2 = readw(ESB_RELOAD_REG); 422 if (val2 & ESB_WDT_TIMEOUT) 423 triggered = WDIOF_CARDRESET; 424 425 /* Reset WDT_TIMEOUT flag and timers */ 426 esb_unlock_registers(); 427 writew((ESB_WDT_TIMEOUT | ESB_WDT_RELOAD), ESB_RELOAD_REG); 428 429 /* And set the correct timeout value */ 430 esb_timer_set_heartbeat(heartbeat); 431 } 432 433 static int __devinit esb_probe(struct platform_device *dev) 434 { 435 int ret; 436 437 /* Check whether or not the hardware watchdog is there */ 438 if (!esb_getdevice() || esb_pci == NULL) 439 return -ENODEV; 440 441 /* Check that the heartbeat value is within it's range; 442 if not reset to the default */ 443 if (heartbeat < 0x1 || heartbeat > 2 * 0x03ff) { 444 heartbeat = WATCHDOG_HEARTBEAT; 445 printk(KERN_INFO PFX 446 "heartbeat value must be 1<heartbeat<2046, using %d\n", 447 heartbeat); 448 } 449 450 /* Initialize the watchdog and make sure it does not run */ 451 esb_initdevice(); 452 453 /* Register the watchdog so that userspace has access to it */ 454 ret = misc_register(&esb_miscdev); 455 if (ret != 0) { 456 printk(KERN_ERR PFX 457 "cannot register miscdev on minor=%d (err=%d)\n", 458 WATCHDOG_MINOR, ret); 459 goto err_unmap; 460 } 461 printk(KERN_INFO PFX 462 "initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n", 463 BASEADDR, heartbeat, nowayout); 464 return 0; 465 466 err_unmap: 467 iounmap(BASEADDR); 468 pci_release_region(esb_pci, 0); 469 pci_disable_device(esb_pci); 470 pci_dev_put(esb_pci); 471 return ret; 472 } 473 474 static int __devexit esb_remove(struct platform_device *dev) 475 { 476 /* Stop the timer before we leave */ 477 if (!nowayout) 478 esb_timer_stop(); 479 480 /* Deregister */ 481 misc_deregister(&esb_miscdev); 482 iounmap(BASEADDR); 483 pci_release_region(esb_pci, 0); 484 pci_disable_device(esb_pci); 485 pci_dev_put(esb_pci); 486 return 0; 487 } 488 489 static void esb_shutdown(struct platform_device *dev) 490 { 491 esb_timer_stop(); 492 } 493 494 static struct platform_driver esb_platform_driver = { 495 .probe = esb_probe, 496 .remove = __devexit_p(esb_remove), 497 .shutdown = esb_shutdown, 498 .driver = { 499 .owner = THIS_MODULE, 500 .name = ESB_MODULE_NAME, 501 }, 502 }; 503 504 static int __init watchdog_init(void) 505 { 506 int err; 507 508 printk(KERN_INFO PFX "Intel 6300ESB WatchDog Timer Driver v%s\n", 509 ESB_VERSION); 510 511 err = platform_driver_register(&esb_platform_driver); 512 if (err) 513 return err; 514 515 esb_platform_device = platform_device_register_simple(ESB_MODULE_NAME, 516 -1, NULL, 0); 517 if (IS_ERR(esb_platform_device)) { 518 err = PTR_ERR(esb_platform_device); 519 goto unreg_platform_driver; 520 } 521 522 return 0; 523 524 unreg_platform_driver: 525 platform_driver_unregister(&esb_platform_driver); 526 return err; 527 } 528 529 static void __exit watchdog_cleanup(void) 530 { 531 platform_device_unregister(esb_platform_device); 532 platform_driver_unregister(&esb_platform_driver); 533 printk(KERN_INFO PFX "Watchdog Module Unloaded.\n"); 534 } 535 536 module_init(watchdog_init); 537 module_exit(watchdog_cleanup); 538 539 MODULE_AUTHOR("Ross Biro and David Härdeman"); 540 MODULE_DESCRIPTION("Watchdog driver for Intel 6300ESB chipsets"); 541 MODULE_LICENSE("GPL"); 542 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 543