diff options
Diffstat (limited to 'drivers/watchdog/i6300esb.c')
-rw-r--r-- | drivers/watchdog/i6300esb.c | 101 |
1 files changed, 37 insertions, 64 deletions
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c index 7ba0b11ec525..bb9750a03942 100644 --- a/drivers/watchdog/i6300esb.c +++ b/drivers/watchdog/i6300esb.c | |||
@@ -34,7 +34,6 @@ | |||
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/platform_device.h> | ||
38 | #include <linux/init.h> | 37 | #include <linux/init.h> |
39 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
40 | #include <linux/ioport.h> | 39 | #include <linux/ioport.h> |
@@ -42,7 +41,7 @@ | |||
42 | #include <linux/io.h> | 41 | #include <linux/io.h> |
43 | 42 | ||
44 | /* Module and version information */ | 43 | /* Module and version information */ |
45 | #define ESB_VERSION "0.04" | 44 | #define ESB_VERSION "0.05" |
46 | #define ESB_MODULE_NAME "i6300ESB timer" | 45 | #define ESB_MODULE_NAME "i6300ESB timer" |
47 | #define ESB_DRIVER_NAME ESB_MODULE_NAME ", v" ESB_VERSION | 46 | #define ESB_DRIVER_NAME ESB_MODULE_NAME ", v" ESB_VERSION |
48 | #define PFX ESB_MODULE_NAME ": " | 47 | #define PFX ESB_MODULE_NAME ": " |
@@ -65,7 +64,7 @@ | |||
65 | /* Config register bits */ | 64 | /* Config register bits */ |
66 | #define ESB_WDT_REBOOT (0x01 << 5) /* Enable reboot on timeout */ | 65 | #define ESB_WDT_REBOOT (0x01 << 5) /* Enable reboot on timeout */ |
67 | #define ESB_WDT_FREQ (0x01 << 2) /* Decrement frequency */ | 66 | #define ESB_WDT_FREQ (0x01 << 2) /* Decrement frequency */ |
68 | #define ESB_WDT_INTTYPE (0x11 << 0) /* Interrupt type on timer1 timeout */ | 67 | #define ESB_WDT_INTTYPE (0x03 << 0) /* Interrupt type on timer1 timeout */ |
69 | 68 | ||
70 | /* Reload register bits */ | 69 | /* Reload register bits */ |
71 | #define ESB_WDT_TIMEOUT (0x01 << 9) /* Watchdog timed out */ | 70 | #define ESB_WDT_TIMEOUT (0x01 << 9) /* Watchdog timed out */ |
@@ -82,7 +81,9 @@ static unsigned long timer_alive; | |||
82 | static struct pci_dev *esb_pci; | 81 | static struct pci_dev *esb_pci; |
83 | static unsigned short triggered; /* The status of the watchdog upon boot */ | 82 | static unsigned short triggered; /* The status of the watchdog upon boot */ |
84 | static char esb_expect_close; | 83 | static char esb_expect_close; |
85 | static struct platform_device *esb_platform_device; | 84 | |
85 | /* We can only use 1 card due to the /dev/watchdog restriction */ | ||
86 | static int cards_found; | ||
86 | 87 | ||
87 | /* module parameters */ | 88 | /* module parameters */ |
88 | /* 30 sec default heartbeat (1 < heartbeat < 2*1023) */ | 89 | /* 30 sec default heartbeat (1 < heartbeat < 2*1023) */ |
@@ -111,8 +112,8 @@ MODULE_PARM_DESC(nowayout, | |||
111 | */ | 112 | */ |
112 | static inline void esb_unlock_registers(void) | 113 | static inline void esb_unlock_registers(void) |
113 | { | 114 | { |
114 | writeb(ESB_UNLOCK1, ESB_RELOAD_REG); | 115 | writew(ESB_UNLOCK1, ESB_RELOAD_REG); |
115 | writeb(ESB_UNLOCK2, ESB_RELOAD_REG); | 116 | writew(ESB_UNLOCK2, ESB_RELOAD_REG); |
116 | } | 117 | } |
117 | 118 | ||
118 | static int esb_timer_start(void) | 119 | static int esb_timer_start(void) |
@@ -256,7 +257,7 @@ static long esb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
256 | int new_heartbeat; | 257 | int new_heartbeat; |
257 | void __user *argp = (void __user *)arg; | 258 | void __user *argp = (void __user *)arg; |
258 | int __user *p = argp; | 259 | int __user *p = argp; |
259 | static struct watchdog_info ident = { | 260 | static const struct watchdog_info ident = { |
260 | .options = WDIOF_SETTIMEOUT | | 261 | .options = WDIOF_SETTIMEOUT | |
261 | WDIOF_KEEPALIVEPING | | 262 | WDIOF_KEEPALIVEPING | |
262 | WDIOF_MAGICCLOSE, | 263 | WDIOF_MAGICCLOSE, |
@@ -332,11 +333,6 @@ static struct miscdevice esb_miscdev = { | |||
332 | 333 | ||
333 | /* | 334 | /* |
334 | * Data for PCI driver interface | 335 | * 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 | */ | 336 | */ |
341 | static struct pci_device_id esb_pci_tbl[] = { | 337 | static struct pci_device_id esb_pci_tbl[] = { |
342 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), }, | 338 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), }, |
@@ -348,29 +344,19 @@ MODULE_DEVICE_TABLE(pci, esb_pci_tbl); | |||
348 | * Init & exit routines | 344 | * Init & exit routines |
349 | */ | 345 | */ |
350 | 346 | ||
351 | static unsigned char __devinit esb_getdevice(void) | 347 | static unsigned char __devinit esb_getdevice(struct pci_dev *pdev) |
352 | { | 348 | { |
353 | /* | 349 | if (pci_enable_device(pdev)) { |
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"); | 350 | printk(KERN_ERR PFX "failed to enable device\n"); |
365 | goto err_devput; | 351 | goto err_devput; |
366 | } | 352 | } |
367 | 353 | ||
368 | if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) { | 354 | if (pci_request_region(pdev, 0, ESB_MODULE_NAME)) { |
369 | printk(KERN_ERR PFX "failed to request region\n"); | 355 | printk(KERN_ERR PFX "failed to request region\n"); |
370 | goto err_disable; | 356 | goto err_disable; |
371 | } | 357 | } |
372 | 358 | ||
373 | BASEADDR = pci_ioremap_bar(esb_pci, 0); | 359 | BASEADDR = pci_ioremap_bar(pdev, 0); |
374 | if (BASEADDR == NULL) { | 360 | if (BASEADDR == NULL) { |
375 | /* Something's wrong here, BASEADDR has to be set */ | 361 | /* Something's wrong here, BASEADDR has to be set */ |
376 | printk(KERN_ERR PFX "failed to get BASEADDR\n"); | 362 | printk(KERN_ERR PFX "failed to get BASEADDR\n"); |
@@ -378,14 +364,14 @@ static unsigned char __devinit esb_getdevice(void) | |||
378 | } | 364 | } |
379 | 365 | ||
380 | /* Done */ | 366 | /* Done */ |
367 | esb_pci = pdev; | ||
381 | return 1; | 368 | return 1; |
382 | 369 | ||
383 | err_release: | 370 | err_release: |
384 | pci_release_region(esb_pci, 0); | 371 | pci_release_region(pdev, 0); |
385 | err_disable: | 372 | err_disable: |
386 | pci_disable_device(esb_pci); | 373 | pci_disable_device(pdev); |
387 | err_devput: | 374 | err_devput: |
388 | pci_dev_put(esb_pci); | ||
389 | return 0; | 375 | return 0; |
390 | } | 376 | } |
391 | 377 | ||
@@ -430,12 +416,23 @@ static void __devinit esb_initdevice(void) | |||
430 | esb_timer_set_heartbeat(heartbeat); | 416 | esb_timer_set_heartbeat(heartbeat); |
431 | } | 417 | } |
432 | 418 | ||
433 | static int __devinit esb_probe(struct platform_device *dev) | 419 | static int __devinit esb_probe(struct pci_dev *pdev, |
420 | const struct pci_device_id *ent) | ||
434 | { | 421 | { |
435 | int ret; | 422 | int ret; |
436 | 423 | ||
424 | cards_found++; | ||
425 | if (cards_found == 1) | ||
426 | printk(KERN_INFO PFX "Intel 6300ESB WatchDog Timer Driver v%s\n", | ||
427 | ESB_VERSION); | ||
428 | |||
429 | if (cards_found > 1) { | ||
430 | printk(KERN_ERR PFX "This driver only supports 1 device\n"); | ||
431 | return -ENODEV; | ||
432 | } | ||
433 | |||
437 | /* Check whether or not the hardware watchdog is there */ | 434 | /* Check whether or not the hardware watchdog is there */ |
438 | if (!esb_getdevice() || esb_pci == NULL) | 435 | if (!esb_getdevice(pdev) || esb_pci == NULL) |
439 | return -ENODEV; | 436 | return -ENODEV; |
440 | 437 | ||
441 | /* Check that the heartbeat value is within it's range; | 438 | /* Check that the heartbeat value is within it's range; |
@@ -467,11 +464,11 @@ err_unmap: | |||
467 | iounmap(BASEADDR); | 464 | iounmap(BASEADDR); |
468 | pci_release_region(esb_pci, 0); | 465 | pci_release_region(esb_pci, 0); |
469 | pci_disable_device(esb_pci); | 466 | pci_disable_device(esb_pci); |
470 | pci_dev_put(esb_pci); | 467 | esb_pci = NULL; |
471 | return ret; | 468 | return ret; |
472 | } | 469 | } |
473 | 470 | ||
474 | static int __devexit esb_remove(struct platform_device *dev) | 471 | static void __devexit esb_remove(struct pci_dev *pdev) |
475 | { | 472 | { |
476 | /* Stop the timer before we leave */ | 473 | /* Stop the timer before we leave */ |
477 | if (!nowayout) | 474 | if (!nowayout) |
@@ -482,54 +479,30 @@ static int __devexit esb_remove(struct platform_device *dev) | |||
482 | iounmap(BASEADDR); | 479 | iounmap(BASEADDR); |
483 | pci_release_region(esb_pci, 0); | 480 | pci_release_region(esb_pci, 0); |
484 | pci_disable_device(esb_pci); | 481 | pci_disable_device(esb_pci); |
485 | pci_dev_put(esb_pci); | 482 | esb_pci = NULL; |
486 | return 0; | ||
487 | } | 483 | } |
488 | 484 | ||
489 | static void esb_shutdown(struct platform_device *dev) | 485 | static void esb_shutdown(struct pci_dev *pdev) |
490 | { | 486 | { |
491 | esb_timer_stop(); | 487 | esb_timer_stop(); |
492 | } | 488 | } |
493 | 489 | ||
494 | static struct platform_driver esb_platform_driver = { | 490 | static struct pci_driver esb_driver = { |
491 | .name = ESB_MODULE_NAME, | ||
492 | .id_table = esb_pci_tbl, | ||
495 | .probe = esb_probe, | 493 | .probe = esb_probe, |
496 | .remove = __devexit_p(esb_remove), | 494 | .remove = __devexit_p(esb_remove), |
497 | .shutdown = esb_shutdown, | 495 | .shutdown = esb_shutdown, |
498 | .driver = { | ||
499 | .owner = THIS_MODULE, | ||
500 | .name = ESB_MODULE_NAME, | ||
501 | }, | ||
502 | }; | 496 | }; |
503 | 497 | ||
504 | static int __init watchdog_init(void) | 498 | static int __init watchdog_init(void) |
505 | { | 499 | { |
506 | int err; | 500 | return pci_register_driver(&esb_driver); |
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 | } | 501 | } |
528 | 502 | ||
529 | static void __exit watchdog_cleanup(void) | 503 | static void __exit watchdog_cleanup(void) |
530 | { | 504 | { |
531 | platform_device_unregister(esb_platform_device); | 505 | pci_unregister_driver(&esb_driver); |
532 | platform_driver_unregister(&esb_platform_driver); | ||
533 | printk(KERN_INFO PFX "Watchdog Module Unloaded.\n"); | 506 | printk(KERN_INFO PFX "Watchdog Module Unloaded.\n"); |
534 | } | 507 | } |
535 | 508 | ||