1 /* 2 * intel TCO Watchdog Driver 3 * 4 * (c) Copyright 2006-2009 Wim Van Sebroeck <wim@iguana.be>. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 * 11 * Neither Wim Van Sebroeck nor Iguana vzw. admit liability nor 12 * provide warranty for any of this software. This material is 13 * provided "AS-IS" and at no charge. 14 * 15 * The TCO watchdog is implemented in the following I/O controller hubs: 16 * (See the intel documentation on http://developer.intel.com.) 17 * document number 290655-003, 290677-014: 82801AA (ICH), 82801AB (ICHO) 18 * document number 290687-002, 298242-027: 82801BA (ICH2) 19 * document number 290733-003, 290739-013: 82801CA (ICH3-S) 20 * document number 290716-001, 290718-007: 82801CAM (ICH3-M) 21 * document number 290744-001, 290745-025: 82801DB (ICH4) 22 * document number 252337-001, 252663-008: 82801DBM (ICH4-M) 23 * document number 273599-001, 273645-002: 82801E (C-ICH) 24 * document number 252516-001, 252517-028: 82801EB (ICH5), 82801ER (ICH5R) 25 * document number 300641-004, 300884-013: 6300ESB 26 * document number 301473-002, 301474-026: 82801F (ICH6) 27 * document number 313082-001, 313075-006: 631xESB, 632xESB 28 * document number 307013-003, 307014-024: 82801G (ICH7) 29 * document number 313056-003, 313057-017: 82801H (ICH8) 30 * document number 316972-004, 316973-012: 82801I (ICH9) 31 * document number 319973-002, 319974-002: 82801J (ICH10) 32 * document number 322169-001, 322170-001: 5 Series, 3400 Series (PCH) 33 * document number 320066-003, 320257-008: EP80597 (IICH) 34 */ 35 36 /* 37 * Includes, defines, variables, module parameters, ... 38 */ 39 40 /* Module and version information */ 41 #define DRV_NAME "iTCO_wdt" 42 #define DRV_VERSION "1.05" 43 #define PFX DRV_NAME ": " 44 45 /* Includes */ 46 #include <linux/module.h> /* For module specific items */ 47 #include <linux/moduleparam.h> /* For new moduleparam's */ 48 #include <linux/types.h> /* For standard types (like size_t) */ 49 #include <linux/errno.h> /* For the -ENODEV/... values */ 50 #include <linux/kernel.h> /* For printk/panic/... */ 51 #include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV 52 (WATCHDOG_MINOR) */ 53 #include <linux/watchdog.h> /* For the watchdog specific items */ 54 #include <linux/init.h> /* For __init/__exit/... */ 55 #include <linux/fs.h> /* For file operations */ 56 #include <linux/platform_device.h> /* For platform_driver framework */ 57 #include <linux/pci.h> /* For pci functions */ 58 #include <linux/ioport.h> /* For io-port access */ 59 #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ 60 #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ 61 #include <linux/io.h> /* For inb/outb/... */ 62 63 #include "iTCO_vendor.h" 64 65 /* TCO related info */ 66 enum iTCO_chipsets { 67 TCO_ICH = 0, /* ICH */ 68 TCO_ICH0, /* ICH0 */ 69 TCO_ICH2, /* ICH2 */ 70 TCO_ICH2M, /* ICH2-M */ 71 TCO_ICH3, /* ICH3-S */ 72 TCO_ICH3M, /* ICH3-M */ 73 TCO_ICH4, /* ICH4 */ 74 TCO_ICH4M, /* ICH4-M */ 75 TCO_CICH, /* C-ICH */ 76 TCO_ICH5, /* ICH5 & ICH5R */ 77 TCO_6300ESB, /* 6300ESB */ 78 TCO_ICH6, /* ICH6 & ICH6R */ 79 TCO_ICH6M, /* ICH6-M */ 80 TCO_ICH6W, /* ICH6W & ICH6RW */ 81 TCO_631XESB, /* 631xESB/632xESB */ 82 TCO_ICH7, /* ICH7 & ICH7R */ 83 TCO_ICH7DH, /* ICH7DH */ 84 TCO_ICH7M, /* ICH7-M & ICH7-U */ 85 TCO_ICH7MDH, /* ICH7-M DH */ 86 TCO_ICH8, /* ICH8 & ICH8R */ 87 TCO_ICH8DH, /* ICH8DH */ 88 TCO_ICH8DO, /* ICH8DO */ 89 TCO_ICH8M, /* ICH8M */ 90 TCO_ICH8ME, /* ICH8M-E */ 91 TCO_ICH9, /* ICH9 */ 92 TCO_ICH9R, /* ICH9R */ 93 TCO_ICH9DH, /* ICH9DH */ 94 TCO_ICH9DO, /* ICH9DO */ 95 TCO_ICH9M, /* ICH9M */ 96 TCO_ICH9ME, /* ICH9M-E */ 97 TCO_ICH10, /* ICH10 */ 98 TCO_ICH10R, /* ICH10R */ 99 TCO_ICH10D, /* ICH10D */ 100 TCO_ICH10DO, /* ICH10DO */ 101 TCO_PCH, /* PCH Desktop Full Featured */ 102 TCO_PCHM, /* PCH Mobile Full Featured */ 103 TCO_PCHMSFF, /* PCH Mobile SFF Full Featured */ 104 TCO_EP80579, /* EP80579 */ 105 }; 106 107 static struct { 108 char *name; 109 unsigned int iTCO_version; 110 } iTCO_chipset_info[] __devinitdata = { 111 {"ICH", 1}, 112 {"ICH0", 1}, 113 {"ICH2", 1}, 114 {"ICH2-M", 1}, 115 {"ICH3-S", 1}, 116 {"ICH3-M", 1}, 117 {"ICH4", 1}, 118 {"ICH4-M", 1}, 119 {"C-ICH", 1}, 120 {"ICH5 or ICH5R", 1}, 121 {"6300ESB", 1}, 122 {"ICH6 or ICH6R", 2}, 123 {"ICH6-M", 2}, 124 {"ICH6W or ICH6RW", 2}, 125 {"631xESB/632xESB", 2}, 126 {"ICH7 or ICH7R", 2}, 127 {"ICH7DH", 2}, 128 {"ICH7-M or ICH7-U", 2}, 129 {"ICH7-M DH", 2}, 130 {"ICH8 or ICH8R", 2}, 131 {"ICH8DH", 2}, 132 {"ICH8DO", 2}, 133 {"ICH8M", 2}, 134 {"ICH8M-E", 2}, 135 {"ICH9", 2}, 136 {"ICH9R", 2}, 137 {"ICH9DH", 2}, 138 {"ICH9DO", 2}, 139 {"ICH9M", 2}, 140 {"ICH9M-E", 2}, 141 {"ICH10", 2}, 142 {"ICH10R", 2}, 143 {"ICH10D", 2}, 144 {"ICH10DO", 2}, 145 {"PCH Desktop Full Featured", 2}, 146 {"PCH Mobile Full Featured", 2}, 147 {"PCH Mobile SFF Full Featured", 2}, 148 {"EP80579", 2}, 149 {NULL, 0} 150 }; 151 152 #define ITCO_PCI_DEVICE(dev, data) \ 153 .vendor = PCI_VENDOR_ID_INTEL, \ 154 .device = dev, \ 155 .subvendor = PCI_ANY_ID, \ 156 .subdevice = PCI_ANY_ID, \ 157 .class = 0, \ 158 .class_mask = 0, \ 159 .driver_data = data 160 161 /* 162 * This data only exists for exporting the supported PCI ids 163 * via MODULE_DEVICE_TABLE. We do not actually register a 164 * pci_driver, because the I/O Controller Hub has also other 165 * functions that probably will be registered by other drivers. 166 */ 167 static struct pci_device_id iTCO_wdt_pci_tbl[] = { 168 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801AA_0, TCO_ICH)}, 169 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801AB_0, TCO_ICH0)}, 170 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801BA_0, TCO_ICH2)}, 171 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801BA_10, TCO_ICH2M)}, 172 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801CA_0, TCO_ICH3)}, 173 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801CA_12, TCO_ICH3M)}, 174 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801DB_0, TCO_ICH4)}, 175 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801DB_12, TCO_ICH4M)}, 176 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801E_0, TCO_CICH)}, 177 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801EB_0, TCO_ICH5)}, 178 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ESB_1, TCO_6300ESB)}, 179 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_0, TCO_ICH6)}, 180 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_1, TCO_ICH6M)}, 181 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_2, TCO_ICH6W)}, 182 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ESB2_0, TCO_631XESB)}, 183 { ITCO_PCI_DEVICE(0x2671, TCO_631XESB)}, 184 { ITCO_PCI_DEVICE(0x2672, TCO_631XESB)}, 185 { ITCO_PCI_DEVICE(0x2673, TCO_631XESB)}, 186 { ITCO_PCI_DEVICE(0x2674, TCO_631XESB)}, 187 { ITCO_PCI_DEVICE(0x2675, TCO_631XESB)}, 188 { ITCO_PCI_DEVICE(0x2676, TCO_631XESB)}, 189 { ITCO_PCI_DEVICE(0x2677, TCO_631XESB)}, 190 { ITCO_PCI_DEVICE(0x2678, TCO_631XESB)}, 191 { ITCO_PCI_DEVICE(0x2679, TCO_631XESB)}, 192 { ITCO_PCI_DEVICE(0x267a, TCO_631XESB)}, 193 { ITCO_PCI_DEVICE(0x267b, TCO_631XESB)}, 194 { ITCO_PCI_DEVICE(0x267c, TCO_631XESB)}, 195 { ITCO_PCI_DEVICE(0x267d, TCO_631XESB)}, 196 { ITCO_PCI_DEVICE(0x267e, TCO_631XESB)}, 197 { ITCO_PCI_DEVICE(0x267f, TCO_631XESB)}, 198 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_0, TCO_ICH7)}, 199 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_30, TCO_ICH7DH)}, 200 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_1, TCO_ICH7M)}, 201 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_31, TCO_ICH7MDH)}, 202 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_0, TCO_ICH8)}, 203 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_2, TCO_ICH8DH)}, 204 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_3, TCO_ICH8DO)}, 205 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_4, TCO_ICH8M)}, 206 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_1, TCO_ICH8ME)}, 207 { ITCO_PCI_DEVICE(0x2918, TCO_ICH9)}, 208 { ITCO_PCI_DEVICE(0x2916, TCO_ICH9R)}, 209 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_2, TCO_ICH9DH)}, 210 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_4, TCO_ICH9DO)}, 211 { ITCO_PCI_DEVICE(0x2919, TCO_ICH9M)}, 212 { ITCO_PCI_DEVICE(0x2917, TCO_ICH9ME)}, 213 { ITCO_PCI_DEVICE(0x3a18, TCO_ICH10)}, 214 { ITCO_PCI_DEVICE(0x3a16, TCO_ICH10R)}, 215 { ITCO_PCI_DEVICE(0x3a1a, TCO_ICH10D)}, 216 { ITCO_PCI_DEVICE(0x3a14, TCO_ICH10DO)}, 217 { ITCO_PCI_DEVICE(0x3b00, TCO_PCH)}, 218 { ITCO_PCI_DEVICE(0x3b01, TCO_PCHM)}, 219 { ITCO_PCI_DEVICE(0x3b0d, TCO_PCHMSFF)}, 220 { ITCO_PCI_DEVICE(0x5031, TCO_EP80579)}, 221 { 0, }, /* End of list */ 222 }; 223 MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); 224 225 /* Address definitions for the TCO */ 226 /* TCO base address */ 227 #define TCOBASE (iTCO_wdt_private.ACPIBASE + 0x60) 228 /* SMI Control and Enable Register */ 229 #define SMI_EN (iTCO_wdt_private.ACPIBASE + 0x30) 230 231 #define TCO_RLD (TCOBASE + 0x00) /* TCO Timer Reload and Curr. Value */ 232 #define TCOv1_TMR (TCOBASE + 0x01) /* TCOv1 Timer Initial Value */ 233 #define TCO_DAT_IN (TCOBASE + 0x02) /* TCO Data In Register */ 234 #define TCO_DAT_OUT (TCOBASE + 0x03) /* TCO Data Out Register */ 235 #define TCO1_STS (TCOBASE + 0x04) /* TCO1 Status Register */ 236 #define TCO2_STS (TCOBASE + 0x06) /* TCO2 Status Register */ 237 #define TCO1_CNT (TCOBASE + 0x08) /* TCO1 Control Register */ 238 #define TCO2_CNT (TCOBASE + 0x0a) /* TCO2 Control Register */ 239 #define TCOv2_TMR (TCOBASE + 0x12) /* TCOv2 Timer Initial Value */ 240 241 /* internal variables */ 242 static unsigned long is_active; 243 static char expect_release; 244 static struct { /* this is private data for the iTCO_wdt device */ 245 /* TCO version/generation */ 246 unsigned int iTCO_version; 247 /* The cards ACPIBASE address (TCOBASE = ACPIBASE+0x60) */ 248 unsigned long ACPIBASE; 249 /* NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2)*/ 250 unsigned long __iomem *gcs; 251 /* the lock for io operations */ 252 spinlock_t io_lock; 253 /* the PCI-device */ 254 struct pci_dev *pdev; 255 } iTCO_wdt_private; 256 257 /* the watchdog platform device */ 258 static struct platform_device *iTCO_wdt_platform_device; 259 260 /* module parameters */ 261 #define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ 262 static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ 263 module_param(heartbeat, int, 0); 264 MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. " 265 "(2<heartbeat<39 (TCO v1) or 613 (TCO v2), default=" 266 __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); 267 268 static int nowayout = WATCHDOG_NOWAYOUT; 269 module_param(nowayout, int, 0); 270 MODULE_PARM_DESC(nowayout, 271 "Watchdog cannot be stopped once started (default=" 272 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 273 274 /* 275 * Some TCO specific functions 276 */ 277 278 static inline unsigned int seconds_to_ticks(int seconds) 279 { 280 /* the internal timer is stored as ticks which decrement 281 * every 0.6 seconds */ 282 return (seconds * 10) / 6; 283 } 284 285 static void iTCO_wdt_set_NO_REBOOT_bit(void) 286 { 287 u32 val32; 288 289 /* Set the NO_REBOOT bit: this disables reboots */ 290 if (iTCO_wdt_private.iTCO_version == 2) { 291 val32 = readl(iTCO_wdt_private.gcs); 292 val32 |= 0x00000020; 293 writel(val32, iTCO_wdt_private.gcs); 294 } else if (iTCO_wdt_private.iTCO_version == 1) { 295 pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32); 296 val32 |= 0x00000002; 297 pci_write_config_dword(iTCO_wdt_private.pdev, 0xd4, val32); 298 } 299 } 300 301 static int iTCO_wdt_unset_NO_REBOOT_bit(void) 302 { 303 int ret = 0; 304 u32 val32; 305 306 /* Unset the NO_REBOOT bit: this enables reboots */ 307 if (iTCO_wdt_private.iTCO_version == 2) { 308 val32 = readl(iTCO_wdt_private.gcs); 309 val32 &= 0xffffffdf; 310 writel(val32, iTCO_wdt_private.gcs); 311 312 val32 = readl(iTCO_wdt_private.gcs); 313 if (val32 & 0x00000020) 314 ret = -EIO; 315 } else if (iTCO_wdt_private.iTCO_version == 1) { 316 pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32); 317 val32 &= 0xfffffffd; 318 pci_write_config_dword(iTCO_wdt_private.pdev, 0xd4, val32); 319 320 pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32); 321 if (val32 & 0x00000002) 322 ret = -EIO; 323 } 324 325 return ret; /* returns: 0 = OK, -EIO = Error */ 326 } 327 328 static int iTCO_wdt_start(void) 329 { 330 unsigned int val; 331 332 spin_lock(&iTCO_wdt_private.io_lock); 333 334 iTCO_vendor_pre_start(iTCO_wdt_private.ACPIBASE, heartbeat); 335 336 /* disable chipset's NO_REBOOT bit */ 337 if (iTCO_wdt_unset_NO_REBOOT_bit()) { 338 spin_unlock(&iTCO_wdt_private.io_lock); 339 printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, " 340 "reboot disabled by hardware\n"); 341 return -EIO; 342 } 343 344 /* Force the timer to its reload value by writing to the TCO_RLD 345 register */ 346 if (iTCO_wdt_private.iTCO_version == 2) 347 outw(0x01, TCO_RLD); 348 else if (iTCO_wdt_private.iTCO_version == 1) 349 outb(0x01, TCO_RLD); 350 351 /* Bit 11: TCO Timer Halt -> 0 = The TCO timer is enabled to count */ 352 val = inw(TCO1_CNT); 353 val &= 0xf7ff; 354 outw(val, TCO1_CNT); 355 val = inw(TCO1_CNT); 356 spin_unlock(&iTCO_wdt_private.io_lock); 357 358 if (val & 0x0800) 359 return -1; 360 return 0; 361 } 362 363 static int iTCO_wdt_stop(void) 364 { 365 unsigned int val; 366 367 spin_lock(&iTCO_wdt_private.io_lock); 368 369 iTCO_vendor_pre_stop(iTCO_wdt_private.ACPIBASE); 370 371 /* Bit 11: TCO Timer Halt -> 1 = The TCO timer is disabled */ 372 val = inw(TCO1_CNT); 373 val |= 0x0800; 374 outw(val, TCO1_CNT); 375 val = inw(TCO1_CNT); 376 377 /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ 378 iTCO_wdt_set_NO_REBOOT_bit(); 379 380 spin_unlock(&iTCO_wdt_private.io_lock); 381 382 if ((val & 0x0800) == 0) 383 return -1; 384 return 0; 385 } 386 387 static int iTCO_wdt_keepalive(void) 388 { 389 spin_lock(&iTCO_wdt_private.io_lock); 390 391 iTCO_vendor_pre_keepalive(iTCO_wdt_private.ACPIBASE, heartbeat); 392 393 /* Reload the timer by writing to the TCO Timer Counter register */ 394 if (iTCO_wdt_private.iTCO_version == 2) 395 outw(0x01, TCO_RLD); 396 else if (iTCO_wdt_private.iTCO_version == 1) 397 outb(0x01, TCO_RLD); 398 399 spin_unlock(&iTCO_wdt_private.io_lock); 400 return 0; 401 } 402 403 static int iTCO_wdt_set_heartbeat(int t) 404 { 405 unsigned int val16; 406 unsigned char val8; 407 unsigned int tmrval; 408 409 tmrval = seconds_to_ticks(t); 410 /* from the specs: */ 411 /* "Values of 0h-3h are ignored and should not be attempted" */ 412 if (tmrval < 0x04) 413 return -EINVAL; 414 if (((iTCO_wdt_private.iTCO_version == 2) && (tmrval > 0x3ff)) || 415 ((iTCO_wdt_private.iTCO_version == 1) && (tmrval > 0x03f))) 416 return -EINVAL; 417 418 iTCO_vendor_pre_set_heartbeat(tmrval); 419 420 /* Write new heartbeat to watchdog */ 421 if (iTCO_wdt_private.iTCO_version == 2) { 422 spin_lock(&iTCO_wdt_private.io_lock); 423 val16 = inw(TCOv2_TMR); 424 val16 &= 0xfc00; 425 val16 |= tmrval; 426 outw(val16, TCOv2_TMR); 427 val16 = inw(TCOv2_TMR); 428 spin_unlock(&iTCO_wdt_private.io_lock); 429 430 if ((val16 & 0x3ff) != tmrval) 431 return -EINVAL; 432 } else if (iTCO_wdt_private.iTCO_version == 1) { 433 spin_lock(&iTCO_wdt_private.io_lock); 434 val8 = inb(TCOv1_TMR); 435 val8 &= 0xc0; 436 val8 |= (tmrval & 0xff); 437 outb(val8, TCOv1_TMR); 438 val8 = inb(TCOv1_TMR); 439 spin_unlock(&iTCO_wdt_private.io_lock); 440 441 if ((val8 & 0x3f) != tmrval) 442 return -EINVAL; 443 } 444 445 heartbeat = t; 446 return 0; 447 } 448 449 static int iTCO_wdt_get_timeleft(int *time_left) 450 { 451 unsigned int val16; 452 unsigned char val8; 453 454 /* read the TCO Timer */ 455 if (iTCO_wdt_private.iTCO_version == 2) { 456 spin_lock(&iTCO_wdt_private.io_lock); 457 val16 = inw(TCO_RLD); 458 val16 &= 0x3ff; 459 spin_unlock(&iTCO_wdt_private.io_lock); 460 461 *time_left = (val16 * 6) / 10; 462 } else if (iTCO_wdt_private.iTCO_version == 1) { 463 spin_lock(&iTCO_wdt_private.io_lock); 464 val8 = inb(TCO_RLD); 465 val8 &= 0x3f; 466 spin_unlock(&iTCO_wdt_private.io_lock); 467 468 *time_left = (val8 * 6) / 10; 469 } else 470 return -EINVAL; 471 return 0; 472 } 473 474 /* 475 * /dev/watchdog handling 476 */ 477 478 static int iTCO_wdt_open(struct inode *inode, struct file *file) 479 { 480 /* /dev/watchdog can only be opened once */ 481 if (test_and_set_bit(0, &is_active)) 482 return -EBUSY; 483 484 /* 485 * Reload and activate timer 486 */ 487 iTCO_wdt_start(); 488 return nonseekable_open(inode, file); 489 } 490 491 static int iTCO_wdt_release(struct inode *inode, struct file *file) 492 { 493 /* 494 * Shut off the timer. 495 */ 496 if (expect_release == 42) { 497 iTCO_wdt_stop(); 498 } else { 499 printk(KERN_CRIT PFX 500 "Unexpected close, not stopping watchdog!\n"); 501 iTCO_wdt_keepalive(); 502 } 503 clear_bit(0, &is_active); 504 expect_release = 0; 505 return 0; 506 } 507 508 static ssize_t iTCO_wdt_write(struct file *file, const char __user *data, 509 size_t len, loff_t *ppos) 510 { 511 /* See if we got the magic character 'V' and reload the timer */ 512 if (len) { 513 if (!nowayout) { 514 size_t i; 515 516 /* note: just in case someone wrote the magic 517 character five months ago... */ 518 expect_release = 0; 519 520 /* scan to see whether or not we got the 521 magic character */ 522 for (i = 0; i != len; i++) { 523 char c; 524 if (get_user(c, data + i)) 525 return -EFAULT; 526 if (c == 'V') 527 expect_release = 42; 528 } 529 } 530 531 /* someone wrote to us, we should reload the timer */ 532 iTCO_wdt_keepalive(); 533 } 534 return len; 535 } 536 537 static long iTCO_wdt_ioctl(struct file *file, unsigned int cmd, 538 unsigned long arg) 539 { 540 int new_options, retval = -EINVAL; 541 int new_heartbeat; 542 void __user *argp = (void __user *)arg; 543 int __user *p = argp; 544 static struct watchdog_info ident = { 545 .options = WDIOF_SETTIMEOUT | 546 WDIOF_KEEPALIVEPING | 547 WDIOF_MAGICCLOSE, 548 .firmware_version = 0, 549 .identity = DRV_NAME, 550 }; 551 552 switch (cmd) { 553 case WDIOC_GETSUPPORT: 554 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; 555 case WDIOC_GETSTATUS: 556 case WDIOC_GETBOOTSTATUS: 557 return put_user(0, p); 558 559 case WDIOC_SETOPTIONS: 560 { 561 if (get_user(new_options, p)) 562 return -EFAULT; 563 564 if (new_options & WDIOS_DISABLECARD) { 565 iTCO_wdt_stop(); 566 retval = 0; 567 } 568 if (new_options & WDIOS_ENABLECARD) { 569 iTCO_wdt_keepalive(); 570 iTCO_wdt_start(); 571 retval = 0; 572 } 573 return retval; 574 } 575 case WDIOC_KEEPALIVE: 576 iTCO_wdt_keepalive(); 577 return 0; 578 579 case WDIOC_SETTIMEOUT: 580 { 581 if (get_user(new_heartbeat, p)) 582 return -EFAULT; 583 if (iTCO_wdt_set_heartbeat(new_heartbeat)) 584 return -EINVAL; 585 iTCO_wdt_keepalive(); 586 /* Fall */ 587 } 588 case WDIOC_GETTIMEOUT: 589 return put_user(heartbeat, p); 590 case WDIOC_GETTIMELEFT: 591 { 592 int time_left; 593 if (iTCO_wdt_get_timeleft(&time_left)) 594 return -EINVAL; 595 return put_user(time_left, p); 596 } 597 default: 598 return -ENOTTY; 599 } 600 } 601 602 /* 603 * Kernel Interfaces 604 */ 605 606 static const struct file_operations iTCO_wdt_fops = { 607 .owner = THIS_MODULE, 608 .llseek = no_llseek, 609 .write = iTCO_wdt_write, 610 .unlocked_ioctl = iTCO_wdt_ioctl, 611 .open = iTCO_wdt_open, 612 .release = iTCO_wdt_release, 613 }; 614 615 static struct miscdevice iTCO_wdt_miscdev = { 616 .minor = WATCHDOG_MINOR, 617 .name = "watchdog", 618 .fops = &iTCO_wdt_fops, 619 }; 620 621 /* 622 * Init & exit routines 623 */ 624 625 static int __devinit iTCO_wdt_init(struct pci_dev *pdev, 626 const struct pci_device_id *ent, struct platform_device *dev) 627 { 628 int ret; 629 u32 base_address; 630 unsigned long RCBA; 631 unsigned long val32; 632 633 /* 634 * Find the ACPI/PM base I/O address which is the base 635 * for the TCO registers (TCOBASE=ACPIBASE + 0x60) 636 * ACPIBASE is bits [15:7] from 0x40-0x43 637 */ 638 pci_read_config_dword(pdev, 0x40, &base_address); 639 base_address &= 0x0000ff80; 640 if (base_address == 0x00000000) { 641 /* Something's wrong here, ACPIBASE has to be set */ 642 printk(KERN_ERR PFX "failed to get TCOBASE address\n"); 643 pci_dev_put(pdev); 644 return -ENODEV; 645 } 646 iTCO_wdt_private.iTCO_version = 647 iTCO_chipset_info[ent->driver_data].iTCO_version; 648 iTCO_wdt_private.ACPIBASE = base_address; 649 iTCO_wdt_private.pdev = pdev; 650 651 /* Get the Memory-Mapped GCS register, we need it for the 652 NO_REBOOT flag (TCO v2). To get access to it you have to 653 read RCBA from PCI Config space 0xf0 and use it as base. 654 GCS = RCBA + ICH6_GCS(0x3410). */ 655 if (iTCO_wdt_private.iTCO_version == 2) { 656 pci_read_config_dword(pdev, 0xf0, &base_address); 657 if ((base_address & 1) == 0) { 658 printk(KERN_ERR PFX "RCBA is disabled by harddware\n"); 659 ret = -ENODEV; 660 goto out; 661 } 662 RCBA = base_address & 0xffffc000; 663 iTCO_wdt_private.gcs = ioremap((RCBA + 0x3410), 4); 664 } 665 666 /* Check chipset's NO_REBOOT bit */ 667 if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) { 668 printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, " 669 "reboot disabled by hardware\n"); 670 ret = -ENODEV; /* Cannot reset NO_REBOOT bit */ 671 goto out_unmap; 672 } 673 674 /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ 675 iTCO_wdt_set_NO_REBOOT_bit(); 676 677 /* The TCO logic uses the TCO_EN bit in the SMI_EN register */ 678 if (!request_region(SMI_EN, 4, "iTCO_wdt")) { 679 printk(KERN_ERR PFX 680 "I/O address 0x%04lx already in use\n", SMI_EN); 681 ret = -EIO; 682 goto out_unmap; 683 } 684 /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ 685 val32 = inl(SMI_EN); 686 val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ 687 outl(val32, SMI_EN); 688 689 /* The TCO I/O registers reside in a 32-byte range pointed to 690 by the TCOBASE value */ 691 if (!request_region(TCOBASE, 0x20, "iTCO_wdt")) { 692 printk(KERN_ERR PFX "I/O address 0x%04lx already in use\n", 693 TCOBASE); 694 ret = -EIO; 695 goto unreg_smi_en; 696 } 697 698 printk(KERN_INFO PFX 699 "Found a %s TCO device (Version=%d, TCOBASE=0x%04lx)\n", 700 iTCO_chipset_info[ent->driver_data].name, 701 iTCO_chipset_info[ent->driver_data].iTCO_version, 702 TCOBASE); 703 704 /* Clear out the (probably old) status */ 705 outb(8, TCO1_STS); /* Clear the Time Out Status bit */ 706 outb(2, TCO2_STS); /* Clear SECOND_TO_STS bit */ 707 outb(4, TCO2_STS); /* Clear BOOT_STS bit */ 708 709 /* Make sure the watchdog is not running */ 710 iTCO_wdt_stop(); 711 712 /* Check that the heartbeat value is within it's range; 713 if not reset to the default */ 714 if (iTCO_wdt_set_heartbeat(heartbeat)) { 715 iTCO_wdt_set_heartbeat(WATCHDOG_HEARTBEAT); 716 printk(KERN_INFO PFX 717 "heartbeat value must be 2 < heartbeat < 39 (TCO v1) " 718 "or 613 (TCO v2), using %d\n", heartbeat); 719 } 720 721 ret = misc_register(&iTCO_wdt_miscdev); 722 if (ret != 0) { 723 printk(KERN_ERR PFX 724 "cannot register miscdev on minor=%d (err=%d)\n", 725 WATCHDOG_MINOR, ret); 726 goto unreg_region; 727 } 728 729 printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n", 730 heartbeat, nowayout); 731 732 return 0; 733 734 unreg_region: 735 release_region(TCOBASE, 0x20); 736 unreg_smi_en: 737 release_region(SMI_EN, 4); 738 out_unmap: 739 if (iTCO_wdt_private.iTCO_version == 2) 740 iounmap(iTCO_wdt_private.gcs); 741 out: 742 pci_dev_put(iTCO_wdt_private.pdev); 743 iTCO_wdt_private.ACPIBASE = 0; 744 return ret; 745 } 746 747 static void __devexit iTCO_wdt_cleanup(void) 748 { 749 /* Stop the timer before we leave */ 750 if (!nowayout) 751 iTCO_wdt_stop(); 752 753 /* Deregister */ 754 misc_deregister(&iTCO_wdt_miscdev); 755 release_region(TCOBASE, 0x20); 756 release_region(SMI_EN, 4); 757 if (iTCO_wdt_private.iTCO_version == 2) 758 iounmap(iTCO_wdt_private.gcs); 759 pci_dev_put(iTCO_wdt_private.pdev); 760 iTCO_wdt_private.ACPIBASE = 0; 761 } 762 763 static int __devinit iTCO_wdt_probe(struct platform_device *dev) 764 { 765 int found = 0; 766 struct pci_dev *pdev = NULL; 767 const struct pci_device_id *ent; 768 769 spin_lock_init(&iTCO_wdt_private.io_lock); 770 771 for_each_pci_dev(pdev) { 772 ent = pci_match_id(iTCO_wdt_pci_tbl, pdev); 773 if (ent) { 774 if (!(iTCO_wdt_init(pdev, ent, dev))) { 775 found++; 776 break; 777 } 778 } 779 } 780 781 if (!found) { 782 printk(KERN_INFO PFX "No card detected\n"); 783 return -ENODEV; 784 } 785 786 return 0; 787 } 788 789 static int __devexit iTCO_wdt_remove(struct platform_device *dev) 790 { 791 if (iTCO_wdt_private.ACPIBASE) 792 iTCO_wdt_cleanup(); 793 794 return 0; 795 } 796 797 static void iTCO_wdt_shutdown(struct platform_device *dev) 798 { 799 iTCO_wdt_stop(); 800 } 801 802 #define iTCO_wdt_suspend NULL 803 #define iTCO_wdt_resume NULL 804 805 static struct platform_driver iTCO_wdt_driver = { 806 .probe = iTCO_wdt_probe, 807 .remove = __devexit_p(iTCO_wdt_remove), 808 .shutdown = iTCO_wdt_shutdown, 809 .suspend = iTCO_wdt_suspend, 810 .resume = iTCO_wdt_resume, 811 .driver = { 812 .owner = THIS_MODULE, 813 .name = DRV_NAME, 814 }, 815 }; 816 817 static int __init iTCO_wdt_init_module(void) 818 { 819 int err; 820 821 printk(KERN_INFO PFX "Intel TCO WatchDog Timer Driver v%s\n", 822 DRV_VERSION); 823 824 err = platform_driver_register(&iTCO_wdt_driver); 825 if (err) 826 return err; 827 828 iTCO_wdt_platform_device = platform_device_register_simple(DRV_NAME, 829 -1, NULL, 0); 830 if (IS_ERR(iTCO_wdt_platform_device)) { 831 err = PTR_ERR(iTCO_wdt_platform_device); 832 goto unreg_platform_driver; 833 } 834 835 return 0; 836 837 unreg_platform_driver: 838 platform_driver_unregister(&iTCO_wdt_driver); 839 return err; 840 } 841 842 static void __exit iTCO_wdt_cleanup_module(void) 843 { 844 platform_device_unregister(iTCO_wdt_platform_device); 845 platform_driver_unregister(&iTCO_wdt_driver); 846 printk(KERN_INFO PFX "Watchdog Module Unloaded.\n"); 847 } 848 849 module_init(iTCO_wdt_init_module); 850 module_exit(iTCO_wdt_cleanup_module); 851 852 MODULE_AUTHOR("Wim Van Sebroeck <wim@iguana.be>"); 853 MODULE_DESCRIPTION("Intel TCO WatchDog Timer Driver"); 854 MODULE_VERSION(DRV_VERSION); 855 MODULE_LICENSE("GPL"); 856 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 857