diff options
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; |