aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/watchdog/sp5100_tco.c321
-rw-r--r--drivers/watchdog/sp5100_tco.h46
2 files changed, 306 insertions, 61 deletions
diff --git a/drivers/watchdog/sp5100_tco.c b/drivers/watchdog/sp5100_tco.c
index b3876812ff07..2b0e000d4377 100644
--- a/drivers/watchdog/sp5100_tco.c
+++ b/drivers/watchdog/sp5100_tco.c
@@ -13,7 +13,9 @@
13 * as published by the Free Software Foundation; either version 13 * as published by the Free Software Foundation; either version
14 * 2 of the License, or (at your option) any later version. 14 * 2 of the License, or (at your option) any later version.
15 * 15 *
16 * See AMD Publication 43009 "AMD SB700/710/750 Register Reference Guide" 16 * See AMD Publication 43009 "AMD SB700/710/750 Register Reference Guide",
17 * AMD Publication 45482 "AMD SB800-Series Southbridges Register
18 * Reference Guide"
17 */ 19 */
18 20
19/* 21/*
@@ -38,18 +40,24 @@
38#include "sp5100_tco.h" 40#include "sp5100_tco.h"
39 41
40/* Module and version information */ 42/* Module and version information */
41#define TCO_VERSION "0.01" 43#define TCO_VERSION "0.03"
42#define TCO_MODULE_NAME "SP5100 TCO timer" 44#define TCO_MODULE_NAME "SP5100 TCO timer"
43#define TCO_DRIVER_NAME TCO_MODULE_NAME ", v" TCO_VERSION 45#define TCO_DRIVER_NAME TCO_MODULE_NAME ", v" TCO_VERSION
44 46
45/* internal variables */ 47/* internal variables */
46static u32 tcobase_phys; 48static u32 tcobase_phys;
49static u32 resbase_phys;
50static u32 tco_wdt_fired;
47static void __iomem *tcobase; 51static void __iomem *tcobase;
48static unsigned int pm_iobase; 52static unsigned int pm_iobase;
49static DEFINE_SPINLOCK(tco_lock); /* Guards the hardware */ 53static DEFINE_SPINLOCK(tco_lock); /* Guards the hardware */
50static unsigned long timer_alive; 54static unsigned long timer_alive;
51static char tco_expect_close; 55static char tco_expect_close;
52static struct pci_dev *sp5100_tco_pci; 56static struct pci_dev *sp5100_tco_pci;
57static struct resource wdt_res = {
58 .name = "Watchdog Timer",
59 .flags = IORESOURCE_MEM,
60};
53 61
54/* the watchdog platform device */ 62/* the watchdog platform device */
55static struct platform_device *sp5100_tco_platform_device; 63static struct platform_device *sp5100_tco_platform_device;
@@ -64,9 +72,15 @@ MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (default="
64 72
65static bool nowayout = WATCHDOG_NOWAYOUT; 73static bool nowayout = WATCHDOG_NOWAYOUT;
66module_param(nowayout, bool, 0); 74module_param(nowayout, bool, 0);
67MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started" 75MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started."
68 " (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 76 " (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
69 77
78static unsigned int force_addr;
79module_param(force_addr, uint, 0);
80MODULE_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
70/* 84/*
71 * Some TCO specific functions 85 * Some TCO specific functions
72 */ 86 */
@@ -122,6 +136,79 @@ static int tco_timer_set_heartbeat(int t)
122 return 0; 136 return 0;
123} 137}
124 138
139static void tco_timer_enable(void)
140{
141 int val;
142
143 if (sp5100_tco_pci->revision >= 0x40) {
144 /* For SB800 or later */
145 /* Set the Watchdog timer resolution to 1 sec */
146 outb(SB800_PM_WATCHDOG_CONFIG, SB800_IO_PM_INDEX_REG);
147 val = inb(SB800_IO_PM_DATA_REG);
148 val |= SB800_PM_WATCHDOG_SECOND_RES;
149 outb(val, SB800_IO_PM_DATA_REG);
150
151 /* Enable watchdog decode bit and watchdog timer */
152 outb(SB800_PM_WATCHDOG_CONTROL, SB800_IO_PM_INDEX_REG);
153 val = inb(SB800_IO_PM_DATA_REG);
154 val |= SB800_PCI_WATCHDOG_DECODE_EN;
155 val &= ~SB800_PM_WATCHDOG_DISABLE;
156 outb(val, SB800_IO_PM_DATA_REG);
157 } else {
158 /* For SP5100 or SB7x0 */
159 /* Enable watchdog decode bit */
160 pci_read_config_dword(sp5100_tco_pci,
161 SP5100_PCI_WATCHDOG_MISC_REG,
162 &val);
163
164 val |= SP5100_PCI_WATCHDOG_DECODE_EN;
165
166 pci_write_config_dword(sp5100_tco_pci,
167 SP5100_PCI_WATCHDOG_MISC_REG,
168 val);
169
170 /* Enable Watchdog timer and set the resolution to 1 sec */
171 outb(SP5100_PM_WATCHDOG_CONTROL, SP5100_IO_PM_INDEX_REG);
172 val = inb(SP5100_IO_PM_DATA_REG);
173 val |= SP5100_PM_WATCHDOG_SECOND_RES;
174 val &= ~SP5100_PM_WATCHDOG_DISABLE;
175 outb(val, SP5100_IO_PM_DATA_REG);
176 }
177}
178
179static 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
125/* 212/*
126 * /dev/watchdog handling 213 * /dev/watchdog handling
127 */ 214 */
@@ -270,11 +357,12 @@ MODULE_DEVICE_TABLE(pci, sp5100_tco_pci_tbl);
270/* 357/*
271 * Init & exit routines 358 * Init & exit routines
272 */ 359 */
273
274static unsigned char sp5100_tco_setupdevice(void) 360static unsigned char sp5100_tco_setupdevice(void)
275{ 361{
276 struct pci_dev *dev = NULL; 362 struct pci_dev *dev = NULL;
363 const char *dev_name = NULL;
277 u32 val; 364 u32 val;
365 u32 index_reg, data_reg, base_addr;
278 366
279 /* Match the PCI device */ 367 /* Match the PCI device */
280 for_each_pci_dev(dev) { 368 for_each_pci_dev(dev) {
@@ -287,29 +375,160 @@ static unsigned char sp5100_tco_setupdevice(void)
287 if (!sp5100_tco_pci) 375 if (!sp5100_tco_pci)
288 return 0; 376 return 0;
289 377
378 pr_info("PCI Revision ID: 0x%x\n", sp5100_tco_pci->revision);
379
380 /*
381 * Determine type of southbridge chipset.
382 */
383 if (sp5100_tco_pci->revision >= 0x40) {
384 dev_name = SB800_DEVNAME;
385 index_reg = SB800_IO_PM_INDEX_REG;
386 data_reg = SB800_IO_PM_DATA_REG;
387 base_addr = SB800_PM_WATCHDOG_BASE;
388 } else {
389 dev_name = SP5100_DEVNAME;
390 index_reg = SP5100_IO_PM_INDEX_REG;
391 data_reg = SP5100_IO_PM_DATA_REG;
392 base_addr = SP5100_PM_WATCHDOG_BASE;
393 }
394
290 /* Request the IO ports used by this driver */ 395 /* Request the IO ports used by this driver */
291 pm_iobase = SP5100_IO_PM_INDEX_REG; 396 pm_iobase = SP5100_IO_PM_INDEX_REG;
292 if (!request_region(pm_iobase, SP5100_PM_IOPORTS_SIZE, "SP5100 TCO")) { 397 if (!request_region(pm_iobase, SP5100_PM_IOPORTS_SIZE, dev_name)) {
293 pr_err("I/O address 0x%04x already in use\n", pm_iobase); 398 pr_err("I/O address 0x%04x already in use\n", pm_iobase);
294 goto exit; 399 goto exit;
295 } 400 }
296 401
297 /* Find the watchdog base address. */ 402 /*
298 outb(SP5100_PM_WATCHDOG_BASE3, SP5100_IO_PM_INDEX_REG); 403 * First, Find the watchdog timer MMIO address from indirect I/O.
299 val = inb(SP5100_IO_PM_DATA_REG); 404 */
300 outb(SP5100_PM_WATCHDOG_BASE2, SP5100_IO_PM_INDEX_REG); 405 outb(base_addr+3, index_reg);
301 val = val << 8 | inb(SP5100_IO_PM_DATA_REG); 406 val = inb(data_reg);
302 outb(SP5100_PM_WATCHDOG_BASE1, SP5100_IO_PM_INDEX_REG); 407 outb(base_addr+2, index_reg);
303 val = val << 8 | inb(SP5100_IO_PM_DATA_REG); 408 val = val << 8 | inb(data_reg);
304 outb(SP5100_PM_WATCHDOG_BASE0, SP5100_IO_PM_INDEX_REG); 409 outb(base_addr+1, index_reg);
305 /* Low three bits of BASE0 are reserved. */ 410 val = val << 8 | inb(data_reg);
306 val = val << 8 | (inb(SP5100_IO_PM_DATA_REG) & 0xf8); 411 outb(base_addr+0, index_reg);
412 /* Low three bits of BASE are reserved */
413 val = val << 8 | (inb(data_reg) & 0xf8);
414
415 pr_debug("Got 0x%04x from indirect I/O\n", val);
416
417 /* Check MMIO address conflict */
418 if (request_mem_region_exclusive(val, SP5100_WDT_MEM_MAP_SIZE,
419 dev_name))
420 goto setup_wdt;
421 else
422 pr_debug("MMIO address 0x%04x already in use\n", val);
423
424 /*
425 * Secondly, Find the watchdog timer MMIO address
426 * from SBResource_MMIO register.
427 */
428 if (sp5100_tco_pci->revision >= 0x40) {
429 /* Read SBResource_MMIO from AcpiMmioEn(PM_Reg: 24h) */
430 outb(SB800_PM_ACPI_MMIO_EN+3, SB800_IO_PM_INDEX_REG);
431 val = inb(SB800_IO_PM_DATA_REG);
432 outb(SB800_PM_ACPI_MMIO_EN+2, SB800_IO_PM_INDEX_REG);
433 val = val << 8 | inb(SB800_IO_PM_DATA_REG);
434 outb(SB800_PM_ACPI_MMIO_EN+1, SB800_IO_PM_INDEX_REG);
435 val = val << 8 | inb(SB800_IO_PM_DATA_REG);
436 outb(SB800_PM_ACPI_MMIO_EN+0, SB800_IO_PM_INDEX_REG);
437 val = val << 8 | inb(SB800_IO_PM_DATA_REG);
438 } else {
439 /* Read SBResource_MMIO from PCI config(PCI_Reg: 9Ch) */
440 pci_read_config_dword(sp5100_tco_pci,
441 SP5100_SB_RESOURCE_MMIO_BASE, &val);
442 }
443
444 /* The SBResource_MMIO is enabled and mapped memory space? */
445 if ((val & (SB800_ACPI_MMIO_DECODE_EN | SB800_ACPI_MMIO_SEL)) ==
446 SB800_ACPI_MMIO_DECODE_EN) {
447 /* Clear unnecessary the low twelve bits */
448 val &= ~0xFFF;
449 /* Add the Watchdog Timer offset to base address. */
450 val += SB800_PM_WDT_MMIO_OFFSET;
451 /* Check MMIO address conflict */
452 if (request_mem_region_exclusive(val, SP5100_WDT_MEM_MAP_SIZE,
453 dev_name)) {
454 pr_debug("Got 0x%04x from SBResource_MMIO register\n",
455 val);
456 goto setup_wdt;
457 } else
458 pr_debug("MMIO address 0x%04x already in use\n", val);
459 } else
460 pr_debug("SBResource_MMIO is disabled(0x%04x)\n", val);
461
462 /*
463 * Lastly re-programming the watchdog timer MMIO address,
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, if chipset is SB8x0(or later) */
501 if (sp5100_tco_pci->revision >= 0x40) {
502 u8 reserved_bit;
503 reserved_bit = inb(base_addr) & 0x7;
504 val |= (u32)reserved_bit;
505 }
506
507 /* Re-programming the watchdog timer base address */
508 outb(base_addr+0, index_reg);
509 /* Low three bits of BASE are reserved */
510 outb((val >> 0) & 0xf8, data_reg);
511 outb(base_addr+1, index_reg);
512 outb((val >> 8) & 0xff, data_reg);
513 outb(base_addr+2, index_reg);
514 outb((val >> 16) & 0xff, data_reg);
515 outb(base_addr+3, index_reg);
516 outb((val >> 24) & 0xff, data_reg);
517
518 /*
519 * Clear unnecessary the low three bits,
520 * if chipset is SB8x0(or later)
521 */
522 if (sp5100_tco_pci->revision >= 0x40)
523 val &= ~0x7;
307 524
308 if (!request_mem_region_exclusive(val, SP5100_WDT_MEM_MAP_SIZE, 525 if (!request_mem_region_exclusive(val, SP5100_WDT_MEM_MAP_SIZE,
309 "SP5100 TCO")) { 526 dev_name)) {
310 pr_err("mmio address 0x%04x already in use\n", val); 527 pr_err("MMIO address 0x%04x already in use\n", val);
311 goto unreg_region; 528 goto unreg_resource;
312 } 529 }
530
531setup_wdt:
313 tcobase_phys = val; 532 tcobase_phys = val;
314 533
315 tcobase = ioremap(val, SP5100_WDT_MEM_MAP_SIZE); 534 tcobase = ioremap(val, SP5100_WDT_MEM_MAP_SIZE);
@@ -318,26 +537,18 @@ static unsigned char sp5100_tco_setupdevice(void)
318 goto unreg_mem_region; 537 goto unreg_mem_region;
319 } 538 }
320 539
321 /* Enable watchdog decode bit */ 540 pr_info("Using 0x%04x for watchdog MMIO address\n", val);
322 pci_read_config_dword(sp5100_tco_pci,
323 SP5100_PCI_WATCHDOG_MISC_REG,
324 &val);
325
326 val |= SP5100_PCI_WATCHDOG_DECODE_EN;
327 541
328 pci_write_config_dword(sp5100_tco_pci, 542 /* Setup the watchdog timer */
329 SP5100_PCI_WATCHDOG_MISC_REG, 543 tco_timer_enable();
330 val);
331 544
332 /* Enable Watchdog timer and set the resolution to 1 sec. */ 545 /* Check that the watchdog action is set to reset the system */
333 outb(SP5100_PM_WATCHDOG_CONTROL, SP5100_IO_PM_INDEX_REG);
334 val = inb(SP5100_IO_PM_DATA_REG);
335 val |= SP5100_PM_WATCHDOG_SECOND_RES;
336 val &= ~SP5100_PM_WATCHDOG_DISABLE;
337 outb(val, SP5100_IO_PM_DATA_REG);
338
339 /* Check that the watchdog action is set to reset the system. */
340 val = readl(SP5100_WDT_CONTROL(tcobase)); 546 val = readl(SP5100_WDT_CONTROL(tcobase));
547 /*
548 * Save WatchDogFired status, because WatchDogFired flag is
549 * cleared here.
550 */
551 tco_wdt_fired = val & SP5100_PM_WATCHDOG_FIRED;
341 val &= ~SP5100_PM_WATCHDOG_ACTION_RESET; 552 val &= ~SP5100_PM_WATCHDOG_ACTION_RESET;
342 writel(val, SP5100_WDT_CONTROL(tcobase)); 553 writel(val, SP5100_WDT_CONTROL(tcobase));
343 554
@@ -355,6 +566,9 @@ static unsigned char sp5100_tco_setupdevice(void)
355 566
356unreg_mem_region: 567unreg_mem_region:
357 release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE); 568 release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
569unreg_resource:
570 if (resbase_phys)
571 release_resource(&wdt_res);
358unreg_region: 572unreg_region:
359 release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE); 573 release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
360exit: 574exit:
@@ -364,23 +578,18 @@ exit:
364static int sp5100_tco_init(struct platform_device *dev) 578static int sp5100_tco_init(struct platform_device *dev)
365{ 579{
366 int ret; 580 int ret;
367 u32 val; 581 char addr_str[16];
368 582
369 /* Check whether or not the hardware watchdog is there. If found, then 583 /*
584 * Check whether or not the hardware watchdog is there. If found, then
370 * set it up. 585 * set it up.
371 */ 586 */
372 if (!sp5100_tco_setupdevice()) 587 if (!sp5100_tco_setupdevice())
373 return -ENODEV; 588 return -ENODEV;
374 589
375 /* Check to see if last reboot was due to watchdog timeout */ 590 /* Check to see if last reboot was due to watchdog timeout */
376 pr_info("Watchdog reboot %sdetected\n", 591 pr_info("Last reboot was %striggered by watchdog.\n",
377 readl(SP5100_WDT_CONTROL(tcobase)) & SP5100_PM_WATCHDOG_FIRED ? 592 tco_wdt_fired ? "" : "not ");
378 "" : "not ");
379
380 /* Clear out the old status */
381 val = readl(SP5100_WDT_CONTROL(tcobase));
382 val &= ~SP5100_PM_WATCHDOG_FIRED;
383 writel(val, SP5100_WDT_CONTROL(tcobase));
384 593
385 /* 594 /*
386 * Check that the heartbeat value is within it's range. 595 * Check that the heartbeat value is within it's range.
@@ -400,14 +609,24 @@ static int sp5100_tco_init(struct platform_device *dev)
400 609
401 clear_bit(0, &timer_alive); 610 clear_bit(0, &timer_alive);
402 611
403 pr_info("initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n", 612 /* Show module parameters */
404 tcobase, heartbeat, nowayout); 613 if (force_addr == tcobase_phys)
614 /* The force_addr is vaild */
615 sprintf(addr_str, "0x%04x", force_addr);
616 else
617 strcpy(addr_str, "none");
618
619 pr_info("initialized (0x%p). heartbeat=%d sec (nowayout=%d, "
620 "force_addr=%s)\n",
621 tcobase, heartbeat, nowayout, addr_str);
405 622
406 return 0; 623 return 0;
407 624
408exit: 625exit:
409 iounmap(tcobase); 626 iounmap(tcobase);
410 release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE); 627 release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
628 if (resbase_phys)
629 release_resource(&wdt_res);
411 release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE); 630 release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
412 return ret; 631 return ret;
413} 632}
@@ -422,6 +641,8 @@ static void sp5100_tco_cleanup(void)
422 misc_deregister(&sp5100_tco_miscdev); 641 misc_deregister(&sp5100_tco_miscdev);
423 iounmap(tcobase); 642 iounmap(tcobase);
424 release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE); 643 release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
644 if (resbase_phys)
645 release_resource(&wdt_res);
425 release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE); 646 release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
426} 647}
427 648
@@ -451,7 +672,7 @@ static int __init sp5100_tco_init_module(void)
451{ 672{
452 int err; 673 int err;
453 674
454 pr_info("SP5100 TCO WatchDog Timer Driver v%s\n", TCO_VERSION); 675 pr_info("SP5100/SB800 TCO WatchDog Timer Driver v%s\n", TCO_VERSION);
455 676
456 err = platform_driver_register(&sp5100_tco_driver); 677 err = platform_driver_register(&sp5100_tco_driver);
457 if (err) 678 if (err)
@@ -475,13 +696,13 @@ static void __exit sp5100_tco_cleanup_module(void)
475{ 696{
476 platform_device_unregister(sp5100_tco_platform_device); 697 platform_device_unregister(sp5100_tco_platform_device);
477 platform_driver_unregister(&sp5100_tco_driver); 698 platform_driver_unregister(&sp5100_tco_driver);
478 pr_info("SP5100 TCO Watchdog Module Unloaded\n"); 699 pr_info("SP5100/SB800 TCO Watchdog Module Unloaded\n");
479} 700}
480 701
481module_init(sp5100_tco_init_module); 702module_init(sp5100_tco_init_module);
482module_exit(sp5100_tco_cleanup_module); 703module_exit(sp5100_tco_cleanup_module);
483 704
484MODULE_AUTHOR("Priyanka Gupta"); 705MODULE_AUTHOR("Priyanka Gupta");
485MODULE_DESCRIPTION("TCO timer driver for SP5100 chipset"); 706MODULE_DESCRIPTION("TCO timer driver for SP5100/SB800 chipset");
486MODULE_LICENSE("GPL"); 707MODULE_LICENSE("GPL");
487MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 708MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/watchdog/sp5100_tco.h b/drivers/watchdog/sp5100_tco.h
index a5a16cc90a34..71594a0c14b7 100644
--- a/drivers/watchdog/sp5100_tco.h
+++ b/drivers/watchdog/sp5100_tco.h
@@ -9,33 +9,57 @@
9/* 9/*
10 * Some address definitions for the Watchdog 10 * Some address definitions for the Watchdog
11 */ 11 */
12
13#define SP5100_WDT_MEM_MAP_SIZE 0x08 12#define SP5100_WDT_MEM_MAP_SIZE 0x08
14#define SP5100_WDT_CONTROL(base) ((base) + 0x00) /* Watchdog Control */ 13#define SP5100_WDT_CONTROL(base) ((base) + 0x00) /* Watchdog Control */
15#define SP5100_WDT_COUNT(base) ((base) + 0x04) /* Watchdog Count */ 14#define SP5100_WDT_COUNT(base) ((base) + 0x04) /* Watchdog Count */
16 15
17#define SP5100_WDT_START_STOP_BIT 1 16#define SP5100_WDT_START_STOP_BIT (1 << 0)
18#define SP5100_WDT_TRIGGER_BIT (1 << 7) 17#define SP5100_WDT_TRIGGER_BIT (1 << 7)
19 18
20#define SP5100_PCI_WATCHDOG_MISC_REG 0x41
21#define SP5100_PCI_WATCHDOG_DECODE_EN (1 << 3)
22
23#define SP5100_PM_IOPORTS_SIZE 0x02 19#define SP5100_PM_IOPORTS_SIZE 0x02
24 20
25/* These two IO registers are hardcoded and there doesn't seem to be a way to 21/*
22 * These two IO registers are hardcoded and there doesn't seem to be a way to
26 * read them from a register. 23 * read them from a register.
27 */ 24 */
25
26/* For SP5100/SB7x0 chipset */
28#define SP5100_IO_PM_INDEX_REG 0xCD6 27#define SP5100_IO_PM_INDEX_REG 0xCD6
29#define SP5100_IO_PM_DATA_REG 0xCD7 28#define SP5100_IO_PM_DATA_REG 0xCD7
30 29
30#define SP5100_SB_RESOURCE_MMIO_BASE 0x9C
31
31#define SP5100_PM_WATCHDOG_CONTROL 0x69 32#define SP5100_PM_WATCHDOG_CONTROL 0x69
32#define SP5100_PM_WATCHDOG_BASE0 0x6C 33#define SP5100_PM_WATCHDOG_BASE 0x6C
33#define SP5100_PM_WATCHDOG_BASE1 0x6D
34#define SP5100_PM_WATCHDOG_BASE2 0x6E
35#define SP5100_PM_WATCHDOG_BASE3 0x6F
36 34
37#define SP5100_PM_WATCHDOG_FIRED (1 << 1) 35#define SP5100_PM_WATCHDOG_FIRED (1 << 1)
38#define SP5100_PM_WATCHDOG_ACTION_RESET (1 << 2) 36#define SP5100_PM_WATCHDOG_ACTION_RESET (1 << 2)
39 37
40#define SP5100_PM_WATCHDOG_DISABLE 1 38#define SP5100_PCI_WATCHDOG_MISC_REG 0x41
39#define SP5100_PCI_WATCHDOG_DECODE_EN (1 << 3)
40
41#define SP5100_PM_WATCHDOG_DISABLE (1 << 0)
41#define SP5100_PM_WATCHDOG_SECOND_RES (3 << 1) 42#define SP5100_PM_WATCHDOG_SECOND_RES (3 << 1)
43
44#define SP5100_DEVNAME "SP5100 TCO"
45
46
47/* For SB8x0(or later) chipset */
48#define SB800_IO_PM_INDEX_REG 0xCD6
49#define SB800_IO_PM_DATA_REG 0xCD7
50
51#define SB800_PM_ACPI_MMIO_EN 0x24
52#define SB800_PM_WATCHDOG_CONTROL 0x48
53#define SB800_PM_WATCHDOG_BASE 0x48
54#define SB800_PM_WATCHDOG_CONFIG 0x4C
55
56#define SB800_PCI_WATCHDOG_DECODE_EN (1 << 0)
57#define SB800_PM_WATCHDOG_DISABLE (1 << 2)
58#define SB800_PM_WATCHDOG_SECOND_RES (3 << 0)
59#define SB800_ACPI_MMIO_DECODE_EN (1 << 0)
60#define SB800_ACPI_MMIO_SEL (1 << 2)
61
62
63#define SB800_PM_WDT_MMIO_OFFSET 0xB00
64
65#define SB800_DEVNAME "SB800 TCO"