diff options
| -rw-r--r-- | drivers/watchdog/i6300esb.c | 90 |
1 files changed, 57 insertions, 33 deletions
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c index 97ac6bf42224..fbe852853248 100644 --- a/drivers/watchdog/i6300esb.c +++ b/drivers/watchdog/i6300esb.c | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | * | 13 | * |
| 14 | * The timer is implemented in the following I/O controller hubs: | 14 | * The timer is implemented in the following I/O controller hubs: |
| 15 | * (See the intel documentation on http://developer.intel.com.) | 15 | * (See the intel documentation on http://developer.intel.com.) |
| 16 | * 6300ESB chip : document number 300641-003 | 16 | * 6300ESB chip : document number 300641-004 |
| 17 | * | 17 | * |
| 18 | * 2004YYZZ Ross Biro | 18 | * 2004YYZZ Ross Biro |
| 19 | * Initial version 0.01 | 19 | * Initial version 0.01 |
| @@ -34,7 +34,7 @@ | |||
| 34 | #include <linux/mm.h> | 34 | #include <linux/mm.h> |
| 35 | #include <linux/miscdevice.h> | 35 | #include <linux/miscdevice.h> |
| 36 | #include <linux/watchdog.h> | 36 | #include <linux/watchdog.h> |
| 37 | #include <linux/reboot.h> | 37 | #include <linux/platform_device.h> |
| 38 | #include <linux/init.h> | 38 | #include <linux/init.h> |
| 39 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
| 40 | #include <linux/ioport.h> | 40 | #include <linux/ioport.h> |
| @@ -42,7 +42,7 @@ | |||
| 42 | #include <linux/io.h> | 42 | #include <linux/io.h> |
| 43 | 43 | ||
| 44 | /* Module and version information */ | 44 | /* Module and version information */ |
| 45 | #define ESB_VERSION "0.03" | 45 | #define ESB_VERSION "0.04" |
| 46 | #define ESB_MODULE_NAME "i6300ESB timer" | 46 | #define ESB_MODULE_NAME "i6300ESB timer" |
| 47 | #define ESB_DRIVER_NAME ESB_MODULE_NAME ", v" ESB_VERSION | 47 | #define ESB_DRIVER_NAME ESB_MODULE_NAME ", v" ESB_VERSION |
| 48 | #define PFX ESB_MODULE_NAME ": " | 48 | #define PFX ESB_MODULE_NAME ": " |
| @@ -81,6 +81,8 @@ static unsigned long timer_alive; | |||
| 81 | static struct pci_dev *esb_pci; | 81 | static struct pci_dev *esb_pci; |
| 82 | static unsigned short triggered; /* The status of the watchdog upon boot */ | 82 | static unsigned short triggered; /* The status of the watchdog upon boot */ |
| 83 | static char esb_expect_close; | 83 | static char esb_expect_close; |
| 84 | static struct platform_device *esb_platform_device; | ||
| 85 | |||
| 84 | 86 | ||
| 85 | /* module parameters */ | 87 | /* module parameters */ |
| 86 | /* 30 sec default heartbeat (1 < heartbeat < 2*1023) */ | 88 | /* 30 sec default heartbeat (1 < heartbeat < 2*1023) */ |
| @@ -320,19 +322,6 @@ static long esb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 320 | } | 322 | } |
| 321 | 323 | ||
| 322 | /* | 324 | /* |
| 323 | * Notify system | ||
| 324 | */ | ||
| 325 | |||
| 326 | static int esb_notify_sys(struct notifier_block *this, | ||
| 327 | unsigned long code, void *unused) | ||
| 328 | { | ||
| 329 | if (code == SYS_DOWN || code == SYS_HALT) | ||
| 330 | esb_timer_stop(); /* Turn the WDT off */ | ||
| 331 | |||
| 332 | return NOTIFY_DONE; | ||
| 333 | } | ||
| 334 | |||
| 335 | /* | ||
| 336 | * Kernel Interfaces | 325 | * Kernel Interfaces |
| 337 | */ | 326 | */ |
| 338 | 327 | ||
| @@ -351,10 +340,6 @@ static struct miscdevice esb_miscdev = { | |||
| 351 | .fops = &esb_fops, | 340 | .fops = &esb_fops, |
| 352 | }; | 341 | }; |
| 353 | 342 | ||
| 354 | static struct notifier_block esb_notifier = { | ||
| 355 | .notifier_call = esb_notify_sys, | ||
| 356 | }; | ||
| 357 | |||
| 358 | /* | 343 | /* |
| 359 | * Data for PCI driver interface | 344 | * Data for PCI driver interface |
| 360 | * | 345 | * |
| @@ -373,7 +358,7 @@ MODULE_DEVICE_TABLE(pci, esb_pci_tbl); | |||
| 373 | * Init & exit routines | 358 | * Init & exit routines |
| 374 | */ | 359 | */ |
| 375 | 360 | ||
| 376 | static unsigned char __init esb_getdevice(void) | 361 | static unsigned char __devinit esb_getdevice(void) |
| 377 | { | 362 | { |
| 378 | u8 val1; | 363 | u8 val1; |
| 379 | unsigned short val2; | 364 | unsigned short val2; |
| @@ -444,7 +429,7 @@ err_devput: | |||
| 444 | return 0; | 429 | return 0; |
| 445 | } | 430 | } |
| 446 | 431 | ||
| 447 | static int __init watchdog_init(void) | 432 | static int __devinit esb_probe(struct platform_device *dev) |
| 448 | { | 433 | { |
| 449 | int ret; | 434 | int ret; |
| 450 | 435 | ||
| @@ -460,19 +445,13 @@ static int __init watchdog_init(void) | |||
| 460 | "heartbeat value must be 1<heartbeat<2046, using %d\n", | 445 | "heartbeat value must be 1<heartbeat<2046, using %d\n", |
| 461 | heartbeat); | 446 | heartbeat); |
| 462 | } | 447 | } |
| 463 | ret = register_reboot_notifier(&esb_notifier); | ||
| 464 | if (ret != 0) { | ||
| 465 | printk(KERN_ERR PFX | ||
| 466 | "cannot register reboot notifier (err=%d)\n", ret); | ||
| 467 | goto err_unmap; | ||
| 468 | } | ||
| 469 | 448 | ||
| 470 | ret = misc_register(&esb_miscdev); | 449 | ret = misc_register(&esb_miscdev); |
| 471 | if (ret != 0) { | 450 | if (ret != 0) { |
| 472 | printk(KERN_ERR PFX | 451 | printk(KERN_ERR PFX |
| 473 | "cannot register miscdev on minor=%d (err=%d)\n", | 452 | "cannot register miscdev on minor=%d (err=%d)\n", |
| 474 | WATCHDOG_MINOR, ret); | 453 | WATCHDOG_MINOR, ret); |
| 475 | goto err_notifier; | 454 | goto err_unmap; |
| 476 | } | 455 | } |
| 477 | esb_timer_stop(); | 456 | esb_timer_stop(); |
| 478 | printk(KERN_INFO PFX | 457 | printk(KERN_INFO PFX |
| @@ -480,8 +459,6 @@ static int __init watchdog_init(void) | |||
| 480 | BASEADDR, heartbeat, nowayout); | 459 | BASEADDR, heartbeat, nowayout); |
| 481 | return 0; | 460 | return 0; |
| 482 | 461 | ||
| 483 | err_notifier: | ||
| 484 | unregister_reboot_notifier(&esb_notifier); | ||
| 485 | err_unmap: | 462 | err_unmap: |
| 486 | iounmap(BASEADDR); | 463 | iounmap(BASEADDR); |
| 487 | /* err_release: */ | 464 | /* err_release: */ |
| @@ -493,7 +470,7 @@ err_unmap: | |||
| 493 | return ret; | 470 | return ret; |
| 494 | } | 471 | } |
| 495 | 472 | ||
| 496 | static void __exit watchdog_cleanup(void) | 473 | static int __devexit esb_remove(struct platform_device *dev) |
| 497 | { | 474 | { |
| 498 | /* Stop the timer before we leave */ | 475 | /* Stop the timer before we leave */ |
| 499 | if (!nowayout) | 476 | if (!nowayout) |
| @@ -501,11 +478,58 @@ static void __exit watchdog_cleanup(void) | |||
| 501 | 478 | ||
| 502 | /* Deregister */ | 479 | /* Deregister */ |
| 503 | misc_deregister(&esb_miscdev); | 480 | misc_deregister(&esb_miscdev); |
| 504 | unregister_reboot_notifier(&esb_notifier); | ||
| 505 | iounmap(BASEADDR); | 481 | iounmap(BASEADDR); |
| 506 | pci_release_region(esb_pci, 0); | 482 | pci_release_region(esb_pci, 0); |
| 507 | pci_disable_device(esb_pci); | 483 | pci_disable_device(esb_pci); |
| 508 | pci_dev_put(esb_pci); | 484 | pci_dev_put(esb_pci); |
| 485 | return 0; | ||
| 486 | } | ||
| 487 | |||
| 488 | static void esb_shutdown(struct platform_device *dev) | ||
| 489 | { | ||
| 490 | esb_timer_stop(); | ||
| 491 | } | ||
| 492 | |||
| 493 | static struct platform_driver esb_platform_driver = { | ||
| 494 | .probe = esb_probe, | ||
| 495 | .remove = __devexit_p(esb_remove), | ||
| 496 | .shutdown = esb_shutdown, | ||
| 497 | .driver = { | ||
| 498 | .owner = THIS_MODULE, | ||
| 499 | .name = ESB_MODULE_NAME, | ||
| 500 | }, | ||
| 501 | }; | ||
| 502 | |||
| 503 | static int __init watchdog_init(void) | ||
| 504 | { | ||
| 505 | int err; | ||
| 506 | |||
| 507 | printk(KERN_INFO PFX "Intel 6300ESB WatchDog Timer Driver v%s\n", | ||
| 508 | ESB_VERSION); | ||
| 509 | |||
| 510 | err = platform_driver_register(&esb_platform_driver); | ||
| 511 | if (err) | ||
| 512 | return err; | ||
| 513 | |||
| 514 | esb_platform_device = platform_device_register_simple(ESB_MODULE_NAME, | ||
| 515 | -1, NULL, 0); | ||
| 516 | if (IS_ERR(esb_platform_device)) { | ||
| 517 | err = PTR_ERR(esb_platform_device); | ||
| 518 | goto unreg_platform_driver; | ||
| 519 | } | ||
| 520 | |||
| 521 | return 0; | ||
| 522 | |||
| 523 | unreg_platform_driver: | ||
| 524 | platform_driver_unregister(&esb_platform_driver); | ||
| 525 | return err; | ||
| 526 | } | ||
| 527 | |||
| 528 | static void __exit watchdog_cleanup(void) | ||
| 529 | { | ||
| 530 | platform_device_unregister(esb_platform_device); | ||
| 531 | platform_driver_unregister(&esb_platform_driver); | ||
| 532 | printk(KERN_INFO PFX "Watchdog Module Unloaded.\n"); | ||
| 509 | } | 533 | } |
| 510 | 534 | ||
| 511 | module_init(watchdog_init); | 535 | module_init(watchdog_init); |
