diff options
Diffstat (limited to 'drivers/watchdog')
-rw-r--r-- | drivers/watchdog/sp5100_tco.c | 126 | ||||
-rw-r--r-- | drivers/watchdog/sp5100_tco.h | 2 |
2 files changed, 7 insertions, 121 deletions
diff --git a/drivers/watchdog/sp5100_tco.c b/drivers/watchdog/sp5100_tco.c index e3b8f757d2d3..0e9d8c479c35 100644 --- a/drivers/watchdog/sp5100_tco.c +++ b/drivers/watchdog/sp5100_tco.c | |||
@@ -40,13 +40,12 @@ | |||
40 | #include "sp5100_tco.h" | 40 | #include "sp5100_tco.h" |
41 | 41 | ||
42 | /* Module and version information */ | 42 | /* Module and version information */ |
43 | #define TCO_VERSION "0.03" | 43 | #define TCO_VERSION "0.05" |
44 | #define TCO_MODULE_NAME "SP5100 TCO timer" | 44 | #define TCO_MODULE_NAME "SP5100 TCO timer" |
45 | #define TCO_DRIVER_NAME TCO_MODULE_NAME ", v" TCO_VERSION | 45 | #define TCO_DRIVER_NAME TCO_MODULE_NAME ", v" TCO_VERSION |
46 | 46 | ||
47 | /* internal variables */ | 47 | /* internal variables */ |
48 | static u32 tcobase_phys; | 48 | static u32 tcobase_phys; |
49 | static u32 resbase_phys; | ||
50 | static u32 tco_wdt_fired; | 49 | static u32 tco_wdt_fired; |
51 | static void __iomem *tcobase; | 50 | static void __iomem *tcobase; |
52 | static unsigned int pm_iobase; | 51 | static unsigned int pm_iobase; |
@@ -54,10 +53,6 @@ static DEFINE_SPINLOCK(tco_lock); /* Guards the hardware */ | |||
54 | static unsigned long timer_alive; | 53 | static unsigned long timer_alive; |
55 | static char tco_expect_close; | 54 | static char tco_expect_close; |
56 | static struct pci_dev *sp5100_tco_pci; | 55 | static struct pci_dev *sp5100_tco_pci; |
57 | static struct resource wdt_res = { | ||
58 | .name = "Watchdog Timer", | ||
59 | .flags = IORESOURCE_MEM, | ||
60 | }; | ||
61 | 56 | ||
62 | /* the watchdog platform device */ | 57 | /* the watchdog platform device */ |
63 | static struct platform_device *sp5100_tco_platform_device; | 58 | static struct platform_device *sp5100_tco_platform_device; |
@@ -75,12 +70,6 @@ module_param(nowayout, bool, 0); | |||
75 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started." | 70 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started." |
76 | " (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 71 | " (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); |
77 | 72 | ||
78 | static unsigned int force_addr; | ||
79 | module_param(force_addr, uint, 0); | ||
80 | MODULE_PARM_DESC(force_addr, "Force the use of specified MMIO address." | ||
81 | " ONLY USE THIS PARAMETER IF YOU REALLY KNOW" | ||
82 | " WHAT YOU ARE DOING (default=none)"); | ||
83 | |||
84 | /* | 73 | /* |
85 | * Some TCO specific functions | 74 | * Some TCO specific functions |
86 | */ | 75 | */ |
@@ -176,39 +165,6 @@ static void tco_timer_enable(void) | |||
176 | } | 165 | } |
177 | } | 166 | } |
178 | 167 | ||
179 | static void tco_timer_disable(void) | ||
180 | { | ||
181 | int val; | ||
182 | |||
183 | if (sp5100_tco_pci->revision >= 0x40) { | ||
184 | /* For SB800 or later */ | ||
185 | /* Enable watchdog decode bit and Disable watchdog timer */ | ||
186 | outb(SB800_PM_WATCHDOG_CONTROL, SB800_IO_PM_INDEX_REG); | ||
187 | val = inb(SB800_IO_PM_DATA_REG); | ||
188 | val |= SB800_PCI_WATCHDOG_DECODE_EN; | ||
189 | val |= SB800_PM_WATCHDOG_DISABLE; | ||
190 | outb(val, SB800_IO_PM_DATA_REG); | ||
191 | } else { | ||
192 | /* For SP5100 or SB7x0 */ | ||
193 | /* Enable watchdog decode bit */ | ||
194 | pci_read_config_dword(sp5100_tco_pci, | ||
195 | SP5100_PCI_WATCHDOG_MISC_REG, | ||
196 | &val); | ||
197 | |||
198 | val |= SP5100_PCI_WATCHDOG_DECODE_EN; | ||
199 | |||
200 | pci_write_config_dword(sp5100_tco_pci, | ||
201 | SP5100_PCI_WATCHDOG_MISC_REG, | ||
202 | val); | ||
203 | |||
204 | /* Disable Watchdog timer */ | ||
205 | outb(SP5100_PM_WATCHDOG_CONTROL, SP5100_IO_PM_INDEX_REG); | ||
206 | val = inb(SP5100_IO_PM_DATA_REG); | ||
207 | val |= SP5100_PM_WATCHDOG_DISABLE; | ||
208 | outb(val, SP5100_IO_PM_DATA_REG); | ||
209 | } | ||
210 | } | ||
211 | |||
212 | /* | 168 | /* |
213 | * /dev/watchdog handling | 169 | * /dev/watchdog handling |
214 | */ | 170 | */ |
@@ -361,7 +317,7 @@ static unsigned char sp5100_tco_setupdevice(void) | |||
361 | { | 317 | { |
362 | struct pci_dev *dev = NULL; | 318 | struct pci_dev *dev = NULL; |
363 | const char *dev_name = NULL; | 319 | const char *dev_name = NULL; |
364 | u32 val, tmp_val; | 320 | u32 val; |
365 | u32 index_reg, data_reg, base_addr; | 321 | u32 index_reg, data_reg, base_addr; |
366 | 322 | ||
367 | /* Match the PCI device */ | 323 | /* Match the PCI device */ |
@@ -459,63 +415,8 @@ static unsigned char sp5100_tco_setupdevice(void) | |||
459 | } else | 415 | } else |
460 | pr_debug("SBResource_MMIO is disabled(0x%04x)\n", val); | 416 | pr_debug("SBResource_MMIO is disabled(0x%04x)\n", val); |
461 | 417 | ||
462 | /* | 418 | pr_notice("failed to find MMIO address, giving up.\n"); |
463 | * Lastly re-programming the watchdog timer MMIO address, | 419 | goto unreg_region; |
464 | * This method is a last resort... | ||
465 | * | ||
466 | * Before re-programming, to ensure that the watchdog timer | ||
467 | * is disabled, disable the watchdog timer. | ||
468 | */ | ||
469 | tco_timer_disable(); | ||
470 | |||
471 | if (force_addr) { | ||
472 | /* | ||
473 | * Force the use of watchdog timer MMIO address, and aligned to | ||
474 | * 8byte boundary. | ||
475 | */ | ||
476 | force_addr &= ~0x7; | ||
477 | val = force_addr; | ||
478 | |||
479 | pr_info("Force the use of 0x%04x as MMIO address\n", val); | ||
480 | } else { | ||
481 | /* | ||
482 | * Get empty slot into the resource tree for watchdog timer. | ||
483 | */ | ||
484 | if (allocate_resource(&iomem_resource, | ||
485 | &wdt_res, | ||
486 | SP5100_WDT_MEM_MAP_SIZE, | ||
487 | 0xf0000000, | ||
488 | 0xfffffff8, | ||
489 | 0x8, | ||
490 | NULL, | ||
491 | NULL)) { | ||
492 | pr_err("MMIO allocation failed\n"); | ||
493 | goto unreg_region; | ||
494 | } | ||
495 | |||
496 | val = resbase_phys = wdt_res.start; | ||
497 | pr_debug("Got 0x%04x from resource tree\n", val); | ||
498 | } | ||
499 | |||
500 | /* Restore to the low three bits */ | ||
501 | outb(base_addr+0, index_reg); | ||
502 | tmp_val = val | (inb(data_reg) & 0x7); | ||
503 | |||
504 | /* Re-programming the watchdog timer base address */ | ||
505 | outb(base_addr+0, index_reg); | ||
506 | outb((tmp_val >> 0) & 0xff, data_reg); | ||
507 | outb(base_addr+1, index_reg); | ||
508 | outb((tmp_val >> 8) & 0xff, data_reg); | ||
509 | outb(base_addr+2, index_reg); | ||
510 | outb((tmp_val >> 16) & 0xff, data_reg); | ||
511 | outb(base_addr+3, index_reg); | ||
512 | outb((tmp_val >> 24) & 0xff, data_reg); | ||
513 | |||
514 | if (!request_mem_region_exclusive(val, SP5100_WDT_MEM_MAP_SIZE, | ||
515 | dev_name)) { | ||
516 | pr_err("MMIO address 0x%04x already in use\n", val); | ||
517 | goto unreg_resource; | ||
518 | } | ||
519 | 420 | ||
520 | setup_wdt: | 421 | setup_wdt: |
521 | tcobase_phys = val; | 422 | tcobase_phys = val; |
@@ -555,9 +456,6 @@ setup_wdt: | |||
555 | 456 | ||
556 | unreg_mem_region: | 457 | unreg_mem_region: |
557 | release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE); | 458 | release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE); |
558 | unreg_resource: | ||
559 | if (resbase_phys) | ||
560 | release_resource(&wdt_res); | ||
561 | unreg_region: | 459 | unreg_region: |
562 | release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE); | 460 | release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE); |
563 | exit: | 461 | exit: |
@@ -567,7 +465,6 @@ exit: | |||
567 | static int sp5100_tco_init(struct platform_device *dev) | 465 | static int sp5100_tco_init(struct platform_device *dev) |
568 | { | 466 | { |
569 | int ret; | 467 | int ret; |
570 | char addr_str[16]; | ||
571 | 468 | ||
572 | /* | 469 | /* |
573 | * Check whether or not the hardware watchdog is there. If found, then | 470 | * Check whether or not the hardware watchdog is there. If found, then |
@@ -599,23 +496,14 @@ static int sp5100_tco_init(struct platform_device *dev) | |||
599 | clear_bit(0, &timer_alive); | 496 | clear_bit(0, &timer_alive); |
600 | 497 | ||
601 | /* Show module parameters */ | 498 | /* Show module parameters */ |
602 | if (force_addr == tcobase_phys) | 499 | pr_info("initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n", |
603 | /* The force_addr is vaild */ | 500 | tcobase, heartbeat, nowayout); |
604 | sprintf(addr_str, "0x%04x", force_addr); | ||
605 | else | ||
606 | strcpy(addr_str, "none"); | ||
607 | |||
608 | pr_info("initialized (0x%p). heartbeat=%d sec (nowayout=%d, " | ||
609 | "force_addr=%s)\n", | ||
610 | tcobase, heartbeat, nowayout, addr_str); | ||
611 | 501 | ||
612 | return 0; | 502 | return 0; |
613 | 503 | ||
614 | exit: | 504 | exit: |
615 | iounmap(tcobase); | 505 | iounmap(tcobase); |
616 | release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE); | 506 | release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE); |
617 | if (resbase_phys) | ||
618 | release_resource(&wdt_res); | ||
619 | release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE); | 507 | release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE); |
620 | return ret; | 508 | return ret; |
621 | } | 509 | } |
@@ -630,8 +518,6 @@ static void sp5100_tco_cleanup(void) | |||
630 | misc_deregister(&sp5100_tco_miscdev); | 518 | misc_deregister(&sp5100_tco_miscdev); |
631 | iounmap(tcobase); | 519 | iounmap(tcobase); |
632 | release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE); | 520 | release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE); |
633 | if (resbase_phys) | ||
634 | release_resource(&wdt_res); | ||
635 | release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE); | 521 | release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE); |
636 | } | 522 | } |
637 | 523 | ||
diff --git a/drivers/watchdog/sp5100_tco.h b/drivers/watchdog/sp5100_tco.h index 71594a0c14b7..2b28c00da0df 100644 --- a/drivers/watchdog/sp5100_tco.h +++ b/drivers/watchdog/sp5100_tco.h | |||
@@ -57,7 +57,7 @@ | |||
57 | #define SB800_PM_WATCHDOG_DISABLE (1 << 2) | 57 | #define SB800_PM_WATCHDOG_DISABLE (1 << 2) |
58 | #define SB800_PM_WATCHDOG_SECOND_RES (3 << 0) | 58 | #define SB800_PM_WATCHDOG_SECOND_RES (3 << 0) |
59 | #define SB800_ACPI_MMIO_DECODE_EN (1 << 0) | 59 | #define SB800_ACPI_MMIO_DECODE_EN (1 << 0) |
60 | #define SB800_ACPI_MMIO_SEL (1 << 2) | 60 | #define SB800_ACPI_MMIO_SEL (1 << 1) |
61 | 61 | ||
62 | 62 | ||
63 | #define SB800_PM_WDT_MMIO_OFFSET 0xB00 | 63 | #define SB800_PM_WDT_MMIO_OFFSET 0xB00 |