1 /* 2 * intel TCO Watchdog Driver 3 * 4 * (c) Copyright 2006-2011 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 322896-001, 322897-001: NM10 30 * document number 313056-003, 313057-017: 82801H (ICH8) 31 * document number 316972-004, 316973-012: 82801I (ICH9) 32 * document number 319973-002, 319974-002: 82801J (ICH10) 33 * document number 322169-001, 322170-003: 5 Series, 3400 Series (PCH) 34 * document number 320066-003, 320257-008: EP80597 (IICH) 35 * document number 324645-001, 324646-001: Cougar Point (CPT) 36 * document number TBD : Patsburg (PBG) 37 * document number TBD : DH89xxCC 38 * document number TBD : Panther Point 39 * document number TBD : Lynx Point 40 * document number TBD : Lynx Point-LP 41 */ 42 43 /* 44 * Includes, defines, variables, module parameters, ... 45 */ 46 47 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 48 49 /* Module and version information */ 50 #define DRV_NAME "iTCO_wdt" 51 #define DRV_VERSION "1.10" 52 53 /* Includes */ 54 #include <linux/module.h> /* For module specific items */ 55 #include <linux/moduleparam.h> /* For new moduleparam's */ 56 #include <linux/types.h> /* For standard types (like size_t) */ 57 #include <linux/errno.h> /* For the -ENODEV/... values */ 58 #include <linux/kernel.h> /* For printk/panic/... */ 59 #include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV 60 (WATCHDOG_MINOR) */ 61 #include <linux/watchdog.h> /* For the watchdog specific items */ 62 #include <linux/init.h> /* For __init/__exit/... */ 63 #include <linux/fs.h> /* For file operations */ 64 #include <linux/platform_device.h> /* For platform_driver framework */ 65 #include <linux/pci.h> /* For pci functions */ 66 #include <linux/ioport.h> /* For io-port access */ 67 #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ 68 #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ 69 #include <linux/io.h> /* For inb/outb/... */ 70 #include <linux/mfd/core.h> 71 #include <linux/mfd/lpc_ich.h> 72 73 #include "iTCO_vendor.h" 74 75 /* Address definitions for the TCO */ 76 /* TCO base address */ 77 #define TCOBASE (iTCO_wdt_private.tco_res->start) 78 /* SMI Control and Enable Register */ 79 #define SMI_EN (iTCO_wdt_private.smi_res->start) 80 81 #define TCO_RLD (TCOBASE + 0x00) /* TCO Timer Reload and Curr. Value */ 82 #define TCOv1_TMR (TCOBASE + 0x01) /* TCOv1 Timer Initial Value */ 83 #define TCO_DAT_IN (TCOBASE + 0x02) /* TCO Data In Register */ 84 #define TCO_DAT_OUT (TCOBASE + 0x03) /* TCO Data Out Register */ 85 #define TCO1_STS (TCOBASE + 0x04) /* TCO1 Status Register */ 86 #define TCO2_STS (TCOBASE + 0x06) /* TCO2 Status Register */ 87 #define TCO1_CNT (TCOBASE + 0x08) /* TCO1 Control Register */ 88 #define TCO2_CNT (TCOBASE + 0x0a) /* TCO2 Control Register */ 89 #define TCOv2_TMR (TCOBASE + 0x12) /* TCOv2 Timer Initial Value */ 90 91 /* internal variables */ 92 static struct { /* this is private data for the iTCO_wdt device */ 93 /* TCO version/generation */ 94 unsigned int iTCO_version; 95 struct resource *tco_res; 96 struct resource *smi_res; 97 struct resource *gcs_res; 98 /* NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2)*/ 99 unsigned long __iomem *gcs; 100 /* the lock for io operations */ 101 spinlock_t io_lock; 102 struct platform_device *dev; 103 /* the PCI-device */ 104 struct pci_dev *pdev; 105 } iTCO_wdt_private; 106 107 /* module parameters */ 108 #define WATCHDOG_TIMEOUT 30 /* 30 sec default heartbeat */ 109 static int heartbeat = WATCHDOG_TIMEOUT; /* in seconds */ 110 module_param(heartbeat, int, 0); 111 MODULE_PARM_DESC(heartbeat, "Watchdog timeout in seconds. " 112 "5..76 (TCO v1) or 3..614 (TCO v2), default=" 113 __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); 114 115 static bool nowayout = WATCHDOG_NOWAYOUT; 116 module_param(nowayout, bool, 0); 117 MODULE_PARM_DESC(nowayout, 118 "Watchdog cannot be stopped once started (default=" 119 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 120 121 static int turn_SMI_watchdog_clear_off = 1; 122 module_param(turn_SMI_watchdog_clear_off, int, 0); 123 MODULE_PARM_DESC(turn_SMI_watchdog_clear_off, 124 "Turn off SMI clearing watchdog (depends on TCO-version)(default=1)"); 125 126 /* 127 * Some TCO specific functions 128 */ 129 130 static inline unsigned int seconds_to_ticks(int seconds) 131 { 132 /* the internal timer is stored as ticks which decrement 133 * every 0.6 seconds */ 134 return (seconds * 10) / 6; 135 } 136 137 static void iTCO_wdt_set_NO_REBOOT_bit(void) 138 { 139 u32 val32; 140 141 /* Set the NO_REBOOT bit: this disables reboots */ 142 if (iTCO_wdt_private.iTCO_version == 2) { 143 val32 = readl(iTCO_wdt_private.gcs); 144 val32 |= 0x00000020; 145 writel(val32, iTCO_wdt_private.gcs); 146 } else if (iTCO_wdt_private.iTCO_version == 1) { 147 pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32); 148 val32 |= 0x00000002; 149 pci_write_config_dword(iTCO_wdt_private.pdev, 0xd4, val32); 150 } 151 } 152 153 static int iTCO_wdt_unset_NO_REBOOT_bit(void) 154 { 155 int ret = 0; 156 u32 val32; 157 158 /* Unset the NO_REBOOT bit: this enables reboots */ 159 if (iTCO_wdt_private.iTCO_version == 2) { 160 val32 = readl(iTCO_wdt_private.gcs); 161 val32 &= 0xffffffdf; 162 writel(val32, iTCO_wdt_private.gcs); 163 164 val32 = readl(iTCO_wdt_private.gcs); 165 if (val32 & 0x00000020) 166 ret = -EIO; 167 } else if (iTCO_wdt_private.iTCO_version == 1) { 168 pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32); 169 val32 &= 0xfffffffd; 170 pci_write_config_dword(iTCO_wdt_private.pdev, 0xd4, val32); 171 172 pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32); 173 if (val32 & 0x00000002) 174 ret = -EIO; 175 } 176 177 return ret; /* returns: 0 = OK, -EIO = Error */ 178 } 179 180 static int iTCO_wdt_start(struct watchdog_device *wd_dev) 181 { 182 unsigned int val; 183 184 spin_lock(&iTCO_wdt_private.io_lock); 185 186 iTCO_vendor_pre_start(iTCO_wdt_private.smi_res, wd_dev->timeout); 187 188 /* disable chipset's NO_REBOOT bit */ 189 if (iTCO_wdt_unset_NO_REBOOT_bit()) { 190 spin_unlock(&iTCO_wdt_private.io_lock); 191 pr_err("failed to reset NO_REBOOT flag, reboot disabled by hardware/BIOS\n"); 192 return -EIO; 193 } 194 195 /* Force the timer to its reload value by writing to the TCO_RLD 196 register */ 197 if (iTCO_wdt_private.iTCO_version == 2) 198 outw(0x01, TCO_RLD); 199 else if (iTCO_wdt_private.iTCO_version == 1) 200 outb(0x01, TCO_RLD); 201 202 /* Bit 11: TCO Timer Halt -> 0 = The TCO timer is enabled to count */ 203 val = inw(TCO1_CNT); 204 val &= 0xf7ff; 205 outw(val, TCO1_CNT); 206 val = inw(TCO1_CNT); 207 spin_unlock(&iTCO_wdt_private.io_lock); 208 209 if (val & 0x0800) 210 return -1; 211 return 0; 212 } 213 214 static int iTCO_wdt_stop(struct watchdog_device *wd_dev) 215 { 216 unsigned int val; 217 218 spin_lock(&iTCO_wdt_private.io_lock); 219 220 iTCO_vendor_pre_stop(iTCO_wdt_private.smi_res); 221 222 /* Bit 11: TCO Timer Halt -> 1 = The TCO timer is disabled */ 223 val = inw(TCO1_CNT); 224 val |= 0x0800; 225 outw(val, TCO1_CNT); 226 val = inw(TCO1_CNT); 227 228 /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ 229 iTCO_wdt_set_NO_REBOOT_bit(); 230 231 spin_unlock(&iTCO_wdt_private.io_lock); 232 233 if ((val & 0x0800) == 0) 234 return -1; 235 return 0; 236 } 237 238 static int iTCO_wdt_ping(struct watchdog_device *wd_dev) 239 { 240 spin_lock(&iTCO_wdt_private.io_lock); 241 242 iTCO_vendor_pre_keepalive(iTCO_wdt_private.smi_res, wd_dev->timeout); 243 244 /* Reload the timer by writing to the TCO Timer Counter register */ 245 if (iTCO_wdt_private.iTCO_version == 2) 246 outw(0x01, TCO_RLD); 247 else if (iTCO_wdt_private.iTCO_version == 1) { 248 /* Reset the timeout status bit so that the timer 249 * needs to count down twice again before rebooting */ 250 outw(0x0008, TCO1_STS); /* write 1 to clear bit */ 251 252 outb(0x01, TCO_RLD); 253 } 254 255 spin_unlock(&iTCO_wdt_private.io_lock); 256 return 0; 257 } 258 259 static int iTCO_wdt_set_timeout(struct watchdog_device *wd_dev, unsigned int t) 260 { 261 unsigned int val16; 262 unsigned char val8; 263 unsigned int tmrval; 264 265 tmrval = seconds_to_ticks(t); 266 267 /* For TCO v1 the timer counts down twice before rebooting */ 268 if (iTCO_wdt_private.iTCO_version == 1) 269 tmrval /= 2; 270 271 /* from the specs: */ 272 /* "Values of 0h-3h are ignored and should not be attempted" */ 273 if (tmrval < 0x04) 274 return -EINVAL; 275 if (((iTCO_wdt_private.iTCO_version == 2) && (tmrval > 0x3ff)) || 276 ((iTCO_wdt_private.iTCO_version == 1) && (tmrval > 0x03f))) 277 return -EINVAL; 278 279 iTCO_vendor_pre_set_heartbeat(tmrval); 280 281 /* Write new heartbeat to watchdog */ 282 if (iTCO_wdt_private.iTCO_version == 2) { 283 spin_lock(&iTCO_wdt_private.io_lock); 284 val16 = inw(TCOv2_TMR); 285 val16 &= 0xfc00; 286 val16 |= tmrval; 287 outw(val16, TCOv2_TMR); 288 val16 = inw(TCOv2_TMR); 289 spin_unlock(&iTCO_wdt_private.io_lock); 290 291 if ((val16 & 0x3ff) != tmrval) 292 return -EINVAL; 293 } else if (iTCO_wdt_private.iTCO_version == 1) { 294 spin_lock(&iTCO_wdt_private.io_lock); 295 val8 = inb(TCOv1_TMR); 296 val8 &= 0xc0; 297 val8 |= (tmrval & 0xff); 298 outb(val8, TCOv1_TMR); 299 val8 = inb(TCOv1_TMR); 300 spin_unlock(&iTCO_wdt_private.io_lock); 301 302 if ((val8 & 0x3f) != tmrval) 303 return -EINVAL; 304 } 305 306 wd_dev->timeout = t; 307 return 0; 308 } 309 310 static unsigned int iTCO_wdt_get_timeleft(struct watchdog_device *wd_dev) 311 { 312 unsigned int val16; 313 unsigned char val8; 314 unsigned int time_left = 0; 315 316 /* read the TCO Timer */ 317 if (iTCO_wdt_private.iTCO_version == 2) { 318 spin_lock(&iTCO_wdt_private.io_lock); 319 val16 = inw(TCO_RLD); 320 val16 &= 0x3ff; 321 spin_unlock(&iTCO_wdt_private.io_lock); 322 323 time_left = (val16 * 6) / 10; 324 } else if (iTCO_wdt_private.iTCO_version == 1) { 325 spin_lock(&iTCO_wdt_private.io_lock); 326 val8 = inb(TCO_RLD); 327 val8 &= 0x3f; 328 if (!(inw(TCO1_STS) & 0x0008)) 329 val8 += (inb(TCOv1_TMR) & 0x3f); 330 spin_unlock(&iTCO_wdt_private.io_lock); 331 332 time_left = (val8 * 6) / 10; 333 } 334 return time_left; 335 } 336 337 /* 338 * Kernel Interfaces 339 */ 340 341 static const struct watchdog_info ident = { 342 .options = WDIOF_SETTIMEOUT | 343 WDIOF_KEEPALIVEPING | 344 WDIOF_MAGICCLOSE, 345 .firmware_version = 0, 346 .identity = DRV_NAME, 347 }; 348 349 static const struct watchdog_ops iTCO_wdt_ops = { 350 .owner = THIS_MODULE, 351 .start = iTCO_wdt_start, 352 .stop = iTCO_wdt_stop, 353 .ping = iTCO_wdt_ping, 354 .set_timeout = iTCO_wdt_set_timeout, 355 .get_timeleft = iTCO_wdt_get_timeleft, 356 }; 357 358 static struct watchdog_device iTCO_wdt_watchdog_dev = { 359 .info = &ident, 360 .ops = &iTCO_wdt_ops, 361 }; 362 363 /* 364 * Init & exit routines 365 */ 366 367 static void iTCO_wdt_cleanup(void) 368 { 369 /* Stop the timer before we leave */ 370 if (!nowayout) 371 iTCO_wdt_stop(&iTCO_wdt_watchdog_dev); 372 373 /* Deregister */ 374 watchdog_unregister_device(&iTCO_wdt_watchdog_dev); 375 376 /* release resources */ 377 release_region(iTCO_wdt_private.tco_res->start, 378 resource_size(iTCO_wdt_private.tco_res)); 379 release_region(iTCO_wdt_private.smi_res->start, 380 resource_size(iTCO_wdt_private.smi_res)); 381 if (iTCO_wdt_private.iTCO_version == 2) { 382 iounmap(iTCO_wdt_private.gcs); 383 release_mem_region(iTCO_wdt_private.gcs_res->start, 384 resource_size(iTCO_wdt_private.gcs_res)); 385 } 386 387 iTCO_wdt_private.tco_res = NULL; 388 iTCO_wdt_private.smi_res = NULL; 389 iTCO_wdt_private.gcs_res = NULL; 390 iTCO_wdt_private.gcs = NULL; 391 } 392 393 static int iTCO_wdt_probe(struct platform_device *dev) 394 { 395 int ret = -ENODEV; 396 unsigned long val32; 397 struct lpc_ich_info *ich_info = dev->dev.platform_data; 398 399 if (!ich_info) 400 goto out; 401 402 spin_lock_init(&iTCO_wdt_private.io_lock); 403 404 iTCO_wdt_private.tco_res = 405 platform_get_resource(dev, IORESOURCE_IO, ICH_RES_IO_TCO); 406 if (!iTCO_wdt_private.tco_res) 407 goto out; 408 409 iTCO_wdt_private.smi_res = 410 platform_get_resource(dev, IORESOURCE_IO, ICH_RES_IO_SMI); 411 if (!iTCO_wdt_private.smi_res) 412 goto out; 413 414 iTCO_wdt_private.iTCO_version = ich_info->iTCO_version; 415 iTCO_wdt_private.dev = dev; 416 iTCO_wdt_private.pdev = to_pci_dev(dev->dev.parent); 417 418 /* 419 * Get the Memory-Mapped GCS register, we need it for the 420 * NO_REBOOT flag (TCO v2). 421 */ 422 if (iTCO_wdt_private.iTCO_version == 2) { 423 iTCO_wdt_private.gcs_res = platform_get_resource(dev, 424 IORESOURCE_MEM, 425 ICH_RES_MEM_GCS); 426 427 if (!iTCO_wdt_private.gcs_res) 428 goto out; 429 430 if (!request_mem_region(iTCO_wdt_private.gcs_res->start, 431 resource_size(iTCO_wdt_private.gcs_res), dev->name)) { 432 ret = -EBUSY; 433 goto out; 434 } 435 iTCO_wdt_private.gcs = ioremap(iTCO_wdt_private.gcs_res->start, 436 resource_size(iTCO_wdt_private.gcs_res)); 437 if (!iTCO_wdt_private.gcs) { 438 ret = -EIO; 439 goto unreg_gcs; 440 } 441 } 442 443 /* Check chipset's NO_REBOOT bit */ 444 if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) { 445 pr_info("unable to reset NO_REBOOT flag, device disabled by hardware/BIOS\n"); 446 ret = -ENODEV; /* Cannot reset NO_REBOOT bit */ 447 goto unmap_gcs; 448 } 449 450 /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ 451 iTCO_wdt_set_NO_REBOOT_bit(); 452 453 /* The TCO logic uses the TCO_EN bit in the SMI_EN register */ 454 if (!request_region(iTCO_wdt_private.smi_res->start, 455 resource_size(iTCO_wdt_private.smi_res), dev->name)) { 456 pr_err("I/O address 0x%04llx already in use, device disabled\n", 457 (u64)SMI_EN); 458 ret = -EBUSY; 459 goto unmap_gcs; 460 } 461 if (turn_SMI_watchdog_clear_off >= iTCO_wdt_private.iTCO_version) { 462 /* 463 * Bit 13: TCO_EN -> 0 464 * Disables TCO logic generating an SMI# 465 */ 466 val32 = inl(SMI_EN); 467 val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ 468 outl(val32, SMI_EN); 469 } 470 471 if (!request_region(iTCO_wdt_private.tco_res->start, 472 resource_size(iTCO_wdt_private.tco_res), dev->name)) { 473 pr_err("I/O address 0x%04llx already in use, device disabled\n", 474 (u64)TCOBASE); 475 ret = -EBUSY; 476 goto unreg_smi; 477 } 478 479 pr_info("Found a %s TCO device (Version=%d, TCOBASE=0x%04llx)\n", 480 ich_info->name, ich_info->iTCO_version, (u64)TCOBASE); 481 482 /* Clear out the (probably old) status */ 483 outw(0x0008, TCO1_STS); /* Clear the Time Out Status bit */ 484 outw(0x0002, TCO2_STS); /* Clear SECOND_TO_STS bit */ 485 outw(0x0004, TCO2_STS); /* Clear BOOT_STS bit */ 486 487 iTCO_wdt_watchdog_dev.bootstatus = 0; 488 iTCO_wdt_watchdog_dev.timeout = WATCHDOG_TIMEOUT; 489 watchdog_set_nowayout(&iTCO_wdt_watchdog_dev, nowayout); 490 iTCO_wdt_watchdog_dev.parent = dev->dev.parent; 491 492 /* Make sure the watchdog is not running */ 493 iTCO_wdt_stop(&iTCO_wdt_watchdog_dev); 494 495 /* Check that the heartbeat value is within it's range; 496 if not reset to the default */ 497 if (iTCO_wdt_set_timeout(&iTCO_wdt_watchdog_dev, heartbeat)) { 498 iTCO_wdt_set_timeout(&iTCO_wdt_watchdog_dev, WATCHDOG_TIMEOUT); 499 pr_info("timeout value out of range, using %d\n", 500 WATCHDOG_TIMEOUT); 501 } 502 503 ret = watchdog_register_device(&iTCO_wdt_watchdog_dev); 504 if (ret != 0) { 505 pr_err("cannot register watchdog device (err=%d)\n", ret); 506 goto unreg_tco; 507 } 508 509 pr_info("initialized. heartbeat=%d sec (nowayout=%d)\n", 510 heartbeat, nowayout); 511 512 return 0; 513 514 unreg_tco: 515 release_region(iTCO_wdt_private.tco_res->start, 516 resource_size(iTCO_wdt_private.tco_res)); 517 unreg_smi: 518 release_region(iTCO_wdt_private.smi_res->start, 519 resource_size(iTCO_wdt_private.smi_res)); 520 unmap_gcs: 521 if (iTCO_wdt_private.iTCO_version == 2) 522 iounmap(iTCO_wdt_private.gcs); 523 unreg_gcs: 524 if (iTCO_wdt_private.iTCO_version == 2) 525 release_mem_region(iTCO_wdt_private.gcs_res->start, 526 resource_size(iTCO_wdt_private.gcs_res)); 527 out: 528 iTCO_wdt_private.tco_res = NULL; 529 iTCO_wdt_private.smi_res = NULL; 530 iTCO_wdt_private.gcs_res = NULL; 531 iTCO_wdt_private.gcs = NULL; 532 533 return ret; 534 } 535 536 static int iTCO_wdt_remove(struct platform_device *dev) 537 { 538 if (iTCO_wdt_private.tco_res || iTCO_wdt_private.smi_res) 539 iTCO_wdt_cleanup(); 540 541 return 0; 542 } 543 544 static void iTCO_wdt_shutdown(struct platform_device *dev) 545 { 546 iTCO_wdt_stop(NULL); 547 } 548 549 static struct platform_driver iTCO_wdt_driver = { 550 .probe = iTCO_wdt_probe, 551 .remove = iTCO_wdt_remove, 552 .shutdown = iTCO_wdt_shutdown, 553 .driver = { 554 .owner = THIS_MODULE, 555 .name = DRV_NAME, 556 }, 557 }; 558 559 static int __init iTCO_wdt_init_module(void) 560 { 561 int err; 562 563 pr_info("Intel TCO WatchDog Timer Driver v%s\n", DRV_VERSION); 564 565 err = platform_driver_register(&iTCO_wdt_driver); 566 if (err) 567 return err; 568 569 return 0; 570 } 571 572 static void __exit iTCO_wdt_cleanup_module(void) 573 { 574 platform_driver_unregister(&iTCO_wdt_driver); 575 pr_info("Watchdog Module Unloaded\n"); 576 } 577 578 module_init(iTCO_wdt_init_module); 579 module_exit(iTCO_wdt_cleanup_module); 580 581 MODULE_AUTHOR("Wim Van Sebroeck <wim@iguana.be>"); 582 MODULE_DESCRIPTION("Intel TCO WatchDog Timer Driver"); 583 MODULE_VERSION(DRV_VERSION); 584 MODULE_LICENSE("GPL"); 585 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 586 MODULE_ALIAS("platform:" DRV_NAME); 587