Lines Matching +full:watchdog +full:- +full:timeout +full:- +full:ms

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2010-2012 Hans de Goede <hdegoede@redhat.com> *
17 #include <linux/watchdog.h>
20 #include "sch56xx-common.h"
25 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
29 #define SIO_UNLOCK_KEY 0x55 /* Key to enable Super-I/O */
30 #define SIO_LOCK_KEY 0xAA /* Key to disable Super-I/O */
45 /* Watchdog registers */
76 return -EBUSY; in superio_enter()
102 * the EM to respond is 15 ms, but testing shows in practice it in sch56xx_send_cmd()
103 * responds within 15-32 reads, so we first busy poll, and if in sch56xx_send_cmd()
105 * the 15 ms maximum response time. in sch56xx_send_cmd()
110 /* (Optional) Write-Clear the EC to Host Mailbox Register */ in sch56xx_send_cmd()
120 outb(0x01, addr + 5); /* # of Entries: 1 Byte (8-bit) */ in sch56xx_send_cmd()
132 outb(0x01, addr); /* Write 01h to the Host-to-EC register */ in sch56xx_send_cmd()
150 return -EIO; in sch56xx_send_cmd()
158 /* Read EC-to-Host Register */ in sch56xx_send_cmd()
171 return -EIO; in sch56xx_send_cmd()
242 * Watchdog routines
246 unsigned int timeout) in watchdog_set_timeout() argument
254 if (timeout <= 255) in watchdog_set_timeout()
259 if (timeout < resolution || timeout > (resolution * 255)) in watchdog_set_timeout()
260 return -EINVAL; in watchdog_set_timeout()
263 control = data->watchdog_control | SCH56XX_WDOG_TIME_BASE_SEC; in watchdog_set_timeout()
265 control = data->watchdog_control & ~SCH56XX_WDOG_TIME_BASE_SEC; in watchdog_set_timeout()
267 if (data->watchdog_control != control) { in watchdog_set_timeout()
268 mutex_lock(data->io_lock); in watchdog_set_timeout()
269 ret = sch56xx_write_virtual_reg(data->addr, in watchdog_set_timeout()
272 mutex_unlock(data->io_lock); in watchdog_set_timeout()
276 data->watchdog_control = control; in watchdog_set_timeout()
280 * Remember new timeout value, but do not write as that (re)starts in watchdog_set_timeout()
281 * the watchdog countdown. in watchdog_set_timeout()
283 data->watchdog_preset = DIV_ROUND_UP(timeout, resolution); in watchdog_set_timeout()
284 wddev->timeout = data->watchdog_preset * resolution; in watchdog_set_timeout()
296 * The sch56xx's watchdog cannot really be started / stopped in watchdog_start()
300 * The sch56xx's watchdog will set the watchdog event bit, bit 0 in watchdog_start()
301 * of the second interrupt source register (at base-address + 9), in watchdog_start()
304 * This will only cause a system reset if the 0-1 flank happens when in watchdog_start()
307 * This means we must clear the watchdog event bit in case it is set. in watchdog_start()
314 mutex_lock(data->io_lock); in watchdog_start()
316 /* 1. Reset the watchdog countdown counter */ in watchdog_start()
317 ret = sch56xx_write_virtual_reg(data->addr, SCH56XX_REG_WDOG_PRESET, in watchdog_start()
318 data->watchdog_preset); in watchdog_start()
323 val = data->watchdog_output_enable | SCH56XX_WDOG_OUTPUT_ENABLE; in watchdog_start()
324 ret = sch56xx_write_virtual_reg(data->addr, in watchdog_start()
329 data->watchdog_output_enable = val; in watchdog_start()
331 /* 3. Clear the watchdog event bit if set */ in watchdog_start()
332 val = inb(data->addr + 9); in watchdog_start()
334 outb(0x01, data->addr + 9); in watchdog_start()
337 mutex_unlock(data->io_lock); in watchdog_start()
346 /* Reset the watchdog countdown counter */ in watchdog_trigger()
347 mutex_lock(data->io_lock); in watchdog_trigger()
348 ret = sch56xx_write_virtual_reg(data->addr, SCH56XX_REG_WDOG_PRESET, in watchdog_trigger()
349 data->watchdog_preset); in watchdog_trigger()
350 mutex_unlock(data->io_lock); in watchdog_trigger()
361 val = data->watchdog_output_enable & ~SCH56XX_WDOG_OUTPUT_ENABLE; in watchdog_stop()
362 mutex_lock(data->io_lock); in watchdog_stop()
363 ret = sch56xx_write_virtual_reg(data->addr, in watchdog_stop()
365 mutex_unlock(data->io_lock); in watchdog_stop()
369 data->watchdog_output_enable = val; in watchdog_stop()
387 /* Cache the watchdog registers */ in sch56xx_watchdog_register()
400 pr_warn("Watchdog not enabled by BIOS, not registering\n"); in sch56xx_watchdog_register()
408 data->addr = addr; in sch56xx_watchdog_register()
409 data->io_lock = io_lock; in sch56xx_watchdog_register()
411 strlcpy(data->wdinfo.identity, "sch56xx watchdog", in sch56xx_watchdog_register()
412 sizeof(data->wdinfo.identity)); in sch56xx_watchdog_register()
413 data->wdinfo.firmware_version = revision; in sch56xx_watchdog_register()
414 data->wdinfo.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT; in sch56xx_watchdog_register()
416 data->wdinfo.options |= WDIOF_MAGICCLOSE; in sch56xx_watchdog_register()
418 data->wddev.info = &data->wdinfo; in sch56xx_watchdog_register()
419 data->wddev.ops = &watchdog_ops; in sch56xx_watchdog_register()
420 data->wddev.parent = parent; in sch56xx_watchdog_register()
421 data->wddev.timeout = 60; in sch56xx_watchdog_register()
422 data->wddev.min_timeout = 1; in sch56xx_watchdog_register()
423 data->wddev.max_timeout = 255 * 60; in sch56xx_watchdog_register()
425 set_bit(WDOG_NO_WAY_OUT, &data->wddev.status); in sch56xx_watchdog_register()
427 set_bit(WDOG_HW_RUNNING, &data->wddev.status); in sch56xx_watchdog_register()
429 /* Since the watchdog uses a downcounter there is no register to read in sch56xx_watchdog_register()
430 the BIOS set timeout from (if any was set at all) -> in sch56xx_watchdog_register()
431 Choose a preset which will give us a 1 minute timeout */ in sch56xx_watchdog_register()
433 data->watchdog_preset = 60; /* seconds */ in sch56xx_watchdog_register()
435 data->watchdog_preset = 1; /* minute */ in sch56xx_watchdog_register()
437 data->watchdog_control = control; in sch56xx_watchdog_register()
438 data->watchdog_output_enable = output_enable; in sch56xx_watchdog_register()
440 watchdog_set_drvdata(&data->wddev, data); in sch56xx_watchdog_register()
441 err = watchdog_register_device(&data->wddev); in sch56xx_watchdog_register()
443 pr_err("Registering watchdog chardev: %d\n", err); in sch56xx_watchdog_register()
454 watchdog_unregister_device(&data->wddev); in sch56xx_watchdog_unregister()
484 err = -ENODEV; in sch56xx_find()
492 err = -ENODEV; in sch56xx_find()
504 err = -ENODEV; in sch56xx_find()
518 .end = address + REGION_LENGTH - 1, in sch56xx_device_add()
525 return -ENOMEM; in sch56xx_device_add()
527 res.name = sch56xx_pdev->name; in sch56xx_device_add()