diff options
author | Wim Van Sebroeck <wim@iguana.be> | 2006-11-12 12:05:09 -0500 |
---|---|---|
committer | Wim Van Sebroeck <wim@iguana.be> | 2006-11-12 12:05:09 -0500 |
commit | e033351d5359f348d2913eb83fbb37023d8f21af (patch) | |
tree | 0ccb7fd82aa28277ace1cd323e3c040db56ee175 /drivers/char/watchdog/iTCO_wdt.c | |
parent | 58c6570add83e30c0905885171fbffc134441165 (diff) |
[WATCHDOG] Add iTCO vendor specific support
Add vendor specific support to the intel TCO timer based watchdog
devices. At this moment we only have additional support for some
SuperMicro Inc. motherboards.
Signed-off-by: Robert Seretny <lkpatches@paypc.com>
Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
Diffstat (limited to 'drivers/char/watchdog/iTCO_wdt.c')
-rw-r--r-- | drivers/char/watchdog/iTCO_wdt.c | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/drivers/char/watchdog/iTCO_wdt.c b/drivers/char/watchdog/iTCO_wdt.c index b6f29cb8bd39..7eac922df867 100644 --- a/drivers/char/watchdog/iTCO_wdt.c +++ b/drivers/char/watchdog/iTCO_wdt.c | |||
@@ -48,8 +48,8 @@ | |||
48 | 48 | ||
49 | /* Module and version information */ | 49 | /* Module and version information */ |
50 | #define DRV_NAME "iTCO_wdt" | 50 | #define DRV_NAME "iTCO_wdt" |
51 | #define DRV_VERSION "1.00" | 51 | #define DRV_VERSION "1.01" |
52 | #define DRV_RELDATE "08-Oct-2006" | 52 | #define DRV_RELDATE "11-Nov-2006" |
53 | #define PFX DRV_NAME ": " | 53 | #define PFX DRV_NAME ": " |
54 | 54 | ||
55 | /* Includes */ | 55 | /* Includes */ |
@@ -189,6 +189,21 @@ static int nowayout = WATCHDOG_NOWAYOUT; | |||
189 | module_param(nowayout, int, 0); | 189 | module_param(nowayout, int, 0); |
190 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); | 190 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); |
191 | 191 | ||
192 | /* iTCO Vendor Specific Support hooks */ | ||
193 | #ifdef CONFIG_ITCO_VENDOR_SUPPORT | ||
194 | extern void iTCO_vendor_pre_start(unsigned long, unsigned int); | ||
195 | extern void iTCO_vendor_pre_stop(unsigned long); | ||
196 | extern void iTCO_vendor_pre_keepalive(unsigned long, unsigned int); | ||
197 | extern void iTCO_vendor_pre_set_heartbeat(unsigned int); | ||
198 | extern int iTCO_vendor_check_noreboot_on(void); | ||
199 | #else | ||
200 | #define iTCO_vendor_pre_start(acpibase, heartbeat) {} | ||
201 | #define iTCO_vendor_pre_stop(acpibase) {} | ||
202 | #define iTCO_vendor_pre_keepalive(acpibase,heartbeat) {} | ||
203 | #define iTCO_vendor_pre_set_heartbeat(heartbeat) {} | ||
204 | #define iTCO_vendor_check_noreboot_on() 1 /* 1=check noreboot; 0=don't check */ | ||
205 | #endif | ||
206 | |||
192 | /* | 207 | /* |
193 | * Some TCO specific functions | 208 | * Some TCO specific functions |
194 | */ | 209 | */ |
@@ -249,6 +264,8 @@ static int iTCO_wdt_start(void) | |||
249 | 264 | ||
250 | spin_lock(&iTCO_wdt_private.io_lock); | 265 | spin_lock(&iTCO_wdt_private.io_lock); |
251 | 266 | ||
267 | iTCO_vendor_pre_start(iTCO_wdt_private.ACPIBASE, heartbeat); | ||
268 | |||
252 | /* disable chipset's NO_REBOOT bit */ | 269 | /* disable chipset's NO_REBOOT bit */ |
253 | if (iTCO_wdt_unset_NO_REBOOT_bit()) { | 270 | if (iTCO_wdt_unset_NO_REBOOT_bit()) { |
254 | printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, reboot disabled by hardware\n"); | 271 | printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, reboot disabled by hardware\n"); |
@@ -273,6 +290,8 @@ static int iTCO_wdt_stop(void) | |||
273 | 290 | ||
274 | spin_lock(&iTCO_wdt_private.io_lock); | 291 | spin_lock(&iTCO_wdt_private.io_lock); |
275 | 292 | ||
293 | iTCO_vendor_pre_stop(iTCO_wdt_private.ACPIBASE); | ||
294 | |||
276 | /* Bit 11: TCO Timer Halt -> 1 = The TCO timer is disabled */ | 295 | /* Bit 11: TCO Timer Halt -> 1 = The TCO timer is disabled */ |
277 | val = inw(TCO1_CNT); | 296 | val = inw(TCO1_CNT); |
278 | val |= 0x0800; | 297 | val |= 0x0800; |
@@ -293,6 +312,8 @@ static int iTCO_wdt_keepalive(void) | |||
293 | { | 312 | { |
294 | spin_lock(&iTCO_wdt_private.io_lock); | 313 | spin_lock(&iTCO_wdt_private.io_lock); |
295 | 314 | ||
315 | iTCO_vendor_pre_keepalive(iTCO_wdt_private.ACPIBASE, heartbeat); | ||
316 | |||
296 | /* Reload the timer by writing to the TCO Timer Counter register */ | 317 | /* Reload the timer by writing to the TCO Timer Counter register */ |
297 | if (iTCO_wdt_private.iTCO_version == 2) { | 318 | if (iTCO_wdt_private.iTCO_version == 2) { |
298 | outw(0x01, TCO_RLD); | 319 | outw(0x01, TCO_RLD); |
@@ -319,6 +340,8 @@ static int iTCO_wdt_set_heartbeat(int t) | |||
319 | ((iTCO_wdt_private.iTCO_version == 1) && (tmrval > 0x03f))) | 340 | ((iTCO_wdt_private.iTCO_version == 1) && (tmrval > 0x03f))) |
320 | return -EINVAL; | 341 | return -EINVAL; |
321 | 342 | ||
343 | iTCO_vendor_pre_set_heartbeat(tmrval); | ||
344 | |||
322 | /* Write new heartbeat to watchdog */ | 345 | /* Write new heartbeat to watchdog */ |
323 | if (iTCO_wdt_private.iTCO_version == 2) { | 346 | if (iTCO_wdt_private.iTCO_version == 2) { |
324 | spin_lock(&iTCO_wdt_private.io_lock); | 347 | spin_lock(&iTCO_wdt_private.io_lock); |
@@ -569,7 +592,7 @@ static int iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device_id *ent, | |||
569 | } | 592 | } |
570 | 593 | ||
571 | /* Check chipset's NO_REBOOT bit */ | 594 | /* Check chipset's NO_REBOOT bit */ |
572 | if (iTCO_wdt_unset_NO_REBOOT_bit()) { | 595 | if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) { |
573 | printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, reboot disabled by hardware\n"); | 596 | printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, reboot disabled by hardware\n"); |
574 | ret = -ENODEV; /* Cannot reset NO_REBOOT bit */ | 597 | ret = -ENODEV; /* Cannot reset NO_REBOOT bit */ |
575 | goto out; | 598 | goto out; |