diff options
author | Takahisa Tanaka <mc74hc00@gmail.com> | 2013-01-13 21:01:58 -0500 |
---|---|---|
committer | Wim Van Sebroeck <wim@iguana.be> | 2013-03-01 06:19:35 -0500 |
commit | 41adafbd7b84c66c2cdad857b75d5d45032310a6 (patch) | |
tree | 8b38fb0f4b675d359f5e19b5622b89affa00128f /drivers/watchdog | |
parent | 10ab329b5db7e592a3a60b4594e4e5f40b60c45c (diff) |
watchdog: sp5100_tco: Write back the original value to reserved bits, instead of zero
In case of SP5100 or SB7x0 chipsets, the sp5100_tco module writes zero to
reserved bits. The module, however, shouldn't depend on specific default
value, and should perform a read-merge-write operation for the reserved
bits.
This patch makes the sp5100_tco module perform a read-merge-write operation
on all the chipset (sp5100, sb7x0, sb8x0 or later).
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=43176
Signed-off-by: Takahisa Tanaka <mc74hc00@gmail.com>
Tested-by: Paul Menzel <paulepanter@users.sourceforge.net>
Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
Cc: stable <stable@vger.kernel.org>
Diffstat (limited to 'drivers/watchdog')
-rw-r--r-- | drivers/watchdog/sp5100_tco.c | 28 |
1 files changed, 8 insertions, 20 deletions
diff --git a/drivers/watchdog/sp5100_tco.c b/drivers/watchdog/sp5100_tco.c index 5dfe86ebdc8b..e3b8f757d2d3 100644 --- a/drivers/watchdog/sp5100_tco.c +++ b/drivers/watchdog/sp5100_tco.c | |||
@@ -361,7 +361,7 @@ static unsigned char sp5100_tco_setupdevice(void) | |||
361 | { | 361 | { |
362 | struct pci_dev *dev = NULL; | 362 | struct pci_dev *dev = NULL; |
363 | const char *dev_name = NULL; | 363 | const char *dev_name = NULL; |
364 | u32 val; | 364 | u32 val, tmp_val; |
365 | u32 index_reg, data_reg, base_addr; | 365 | u32 index_reg, data_reg, base_addr; |
366 | 366 | ||
367 | /* Match the PCI device */ | 367 | /* Match the PCI device */ |
@@ -497,31 +497,19 @@ static unsigned char sp5100_tco_setupdevice(void) | |||
497 | pr_debug("Got 0x%04x from resource tree\n", val); | 497 | pr_debug("Got 0x%04x from resource tree\n", val); |
498 | } | 498 | } |
499 | 499 | ||
500 | /* Restore to the low three bits, if chipset is SB8x0(or later) */ | 500 | /* Restore to the low three bits */ |
501 | if (sp5100_tco_pci->revision >= 0x40) { | 501 | outb(base_addr+0, index_reg); |
502 | u8 reserved_bit; | 502 | tmp_val = val | (inb(data_reg) & 0x7); |
503 | outb(base_addr+0, index_reg); | ||
504 | reserved_bit = inb(data_reg) & 0x7; | ||
505 | val |= (u32)reserved_bit; | ||
506 | } | ||
507 | 503 | ||
508 | /* Re-programming the watchdog timer base address */ | 504 | /* Re-programming the watchdog timer base address */ |
509 | outb(base_addr+0, index_reg); | 505 | outb(base_addr+0, index_reg); |
510 | /* Low three bits of BASE are reserved */ | 506 | outb((tmp_val >> 0) & 0xff, data_reg); |
511 | outb((val >> 0) & 0xff, data_reg); | ||
512 | outb(base_addr+1, index_reg); | 507 | outb(base_addr+1, index_reg); |
513 | outb((val >> 8) & 0xff, data_reg); | 508 | outb((tmp_val >> 8) & 0xff, data_reg); |
514 | outb(base_addr+2, index_reg); | 509 | outb(base_addr+2, index_reg); |
515 | outb((val >> 16) & 0xff, data_reg); | 510 | outb((tmp_val >> 16) & 0xff, data_reg); |
516 | outb(base_addr+3, index_reg); | 511 | outb(base_addr+3, index_reg); |
517 | outb((val >> 24) & 0xff, data_reg); | 512 | outb((tmp_val >> 24) & 0xff, data_reg); |
518 | |||
519 | /* | ||
520 | * Clear unnecessary the low three bits, | ||
521 | * if chipset is SB8x0(or later) | ||
522 | */ | ||
523 | if (sp5100_tco_pci->revision >= 0x40) | ||
524 | val &= ~0x7; | ||
525 | 513 | ||
526 | if (!request_mem_region_exclusive(val, SP5100_WDT_MEM_MAP_SIZE, | 514 | if (!request_mem_region_exclusive(val, SP5100_WDT_MEM_MAP_SIZE, |
527 | dev_name)) { | 515 | dev_name)) { |