aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog/i6300esb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/watchdog/i6300esb.c')
-rw-r--r--drivers/watchdog/i6300esb.c101
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;
82static struct pci_dev *esb_pci; 81static struct pci_dev *esb_pci;
83static unsigned short triggered; /* The status of the watchdog upon boot */ 82static unsigned short triggered; /* The status of the watchdog upon boot */
84static char esb_expect_close; 83static char esb_expect_close;
85static struct platform_device *esb_platform_device; 84
85/* We can only use 1 card due to the /dev/watchdog restriction */
86static 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 */
112static inline void esb_unlock_registers(void) 113static 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
118static int esb_timer_start(void) 119static 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 */
341static struct pci_device_id esb_pci_tbl[] = { 337static 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
351static unsigned char __devinit esb_getdevice(void) 347static 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
383err_release: 370err_release:
384 pci_release_region(esb_pci, 0); 371 pci_release_region(pdev, 0);
385err_disable: 372err_disable:
386 pci_disable_device(esb_pci); 373 pci_disable_device(pdev);
387err_devput: 374err_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
433static int __devinit esb_probe(struct platform_device *dev) 419static 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
474static int __devexit esb_remove(struct platform_device *dev) 471static 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
489static void esb_shutdown(struct platform_device *dev) 485static void esb_shutdown(struct pci_dev *pdev)
490{ 486{
491 esb_timer_stop(); 487 esb_timer_stop();
492} 488}
493 489
494static struct platform_driver esb_platform_driver = { 490static 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
504static int __init watchdog_init(void) 498static 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
524unreg_platform_driver:
525 platform_driver_unregister(&esb_platform_driver);
526 return err;
527} 501}
528 502
529static void __exit watchdog_cleanup(void) 503static 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