for (i = DA9063_TWDSCALE_MIN; i <= DA9063_TWDSCALE_MAX; i++) { if (wdt_timeout[i] >= secs) return i;
}
return DA9063_TWDSCALE_MAX;
}
/* * Read the currently active timeout. * Zero means the watchdog is disabled.
*/ staticunsignedint da9063_wdt_read_timeout(struct da9063 *da9063)
{ unsignedint val;
/* * The watchdog triggers a reboot if a timeout value is already * programmed because the timeout value combines two functions * in one: indicating the counter limit and starting the watchdog. * The watchdog must be disabled to be able to change the timeout * value if the watchdog is already running. Then we can set the * new timeout value which enables the watchdog again.
*/
ret = da9063_wdt_disable_timer(da9063); if (ret) return ret;
/* * Prevent pings from occurring late in system poweroff/reboot sequence * and possibly locking out restart handler from accessing i2c bus.
*/ if (system_state > SYSTEM_RUNNING) return 0;
ret = regmap_write(da9063->regmap, DA9063_REG_CONTROL_F,
DA9063_WATCHDOG); if (ret)
dev_alert(da9063->dev, "Failed to ping the watchdog (err = %d)\n",
ret);
return ret;
}
staticint da9063_wdt_set_timeout(struct watchdog_device *wdd, unsignedint timeout)
{ struct da9063 *da9063 = watchdog_get_drvdata(wdd); int ret = 0;
/* * There are two cases when a set_timeout() will be called: * 1. The watchdog is off and someone wants to set the timeout for the * further use. * 2. The watchdog is already running and a new timeout value should be * set. * * The watchdog can't store a timeout value not equal zero without * enabling the watchdog, so the timeout must be buffered by the driver.
*/ if (watchdog_active(wdd))
ret = da9063_wdt_update_timeout(da9063, timeout);
if (ret)
dev_err(da9063->dev, "Failed to set watchdog timeout (err = %d)\n",
ret); else
wdd->timeout = wdt_timeout[da9063_wdt_timeout_to_sel(timeout)];
/* * Don't use regmap because it is not atomic safe. Additionally, use * unlocked flavor of i2c_smbus_xfer to avoid scenario where i2c bus * might previously be locked by some process unable to release the * lock due to interrupts already being disabled at this late stage.
*/
msg.byte = DA9063_SHUTDOWN;
ret = __i2c_smbus_xfer(client->adapter, client->addr, client->flags,
I2C_SMBUS_WRITE, DA9063_REG_CONTROL_F,
I2C_SMBUS_BYTE_DATA, &msg);
if (ret < 0)
dev_alert(da9063->dev, "Failed to shutdown (err = %d)\n",
ret);
/* Use pre-configured timeout if watchdog is already running. */
timeout = da9063_wdt_read_timeout(da9063); if (timeout)
wdd->timeout = timeout;
/* Set timeout, maybe override it with DT value, scale it */
watchdog_init_timeout(wdd, 0, dev);
da9063_wdt_set_timeout(wdd, wdd->timeout);
/* Update timeout if the watchdog is already running. */ if (timeout) {
da9063_wdt_update_timeout(da9063, wdd->timeout);
set_bit(WDOG_HW_RUNNING, &wdd->status);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.