#define BD96801_WDT_DEFAULT_MARGIN_MS 1843 /* Unit is seconds */ #define DEFAULT_TIMEOUT 30
/* * BD96801 WDG supports window mode so the TMO consists of SHORT and LONG * timeout values. SHORT time is meaningful only in window mode where feeding * period shorter than SHORT would be an error. LONG time is used to detect if * feeding is not occurring within given time limit (SoC SW hangs). The LONG * timeout time is a multiple of (2, 4, 8 or 16 times) the SHORT timeout.
*/
if (hw_margin_min * 1000 > FASTNG_MAX_US) {
dev_err(dev, "Unsupported fast timeout %u uS [max %u]\n",
hw_margin_min * 1000, FASTNG_MAX_US);
return -EINVAL;
}
if (hw_margin * 1000 > SLOWNG_MAX_US) {
dev_err(dev, "Unsupported slow timeout %u uS [max %u]\n",
hw_margin * 1000, SLOWNG_MAX_US);
return -EINVAL;
}
/* * Convert to 100uS to guarantee reasonable timeouts fit in * 32bit maintaining also a decent accuracy.
*/
hw_margin *= 10;
hw_margin_min *= 10;
if (hw_margin_min) { unsignedint min;
type = BD96801_WD_TYPE_WIN;
dev_dbg(dev, "Setting type WINDOW 0x%x\n", type);
ret = find_closest_fast(hw_margin_min, &fastng, &min); if (ret) return ret;
ret = find_closest_slow_by_fast(min, &hw_margin, &slowng); if (ret) {
dev_err(dev, "can't support slow timeout %u uS using fast %u uS. [max slow %u uS]\n",
hw_margin * 100, min * 100, min * 100 * 16);
return ret;
}
w->wdt.min_hw_heartbeat_ms = min / 10;
} else {
type = BD96801_WD_TYPE_SLOW;
dev_dbg(dev, "Setting type SLOW 0x%x\n", type);
ret = find_closest_slow(&hw_margin, &slowng, &fastng); if (ret) return ret;
}
/* * The BD96801 supports a somewhat peculiar QA-mode, which we do not * support in this driver. If the QA-mode is enabled then we just * warn and bail-out.
*/ if ((conf_reg & BD96801_WD_EN_MASK) != BD96801_WD_IF_EN) {
dev_err(w->dev, "watchdog set to Q&A mode - exiting\n"); return -EINVAL;
}
ret = regmap_read(w->regmap, BD96801_REG_WD_TMO, &val); if (ret) return ret;
sel = FIELD_GET(BD96801_WD_TMO_SHORT_MASK, val);
fast = FASTNG_MIN << sel;
ret = regmap_read(w->regmap, BD96801_REG_WD_CONF, &val); if (ret) return dev_err_probe(&pdev->dev, ret, "Failed to get the watchdog state\n");
/* * If the WDG is already enabled we assume it is configured by boot. * In this case we just update the hw-timeout based on values set to * the timeout / mode registers and leave the hardware configs * untouched.
*/ if ((val & BD96801_WD_EN_MASK) != BD96801_WD_DISABLE) {
dev_dbg(&pdev->dev, "watchdog was running during probe\n");
ret = bd96801_set_heartbeat_from_hw(w, val); if (ret) return ret;
set_bit(WDOG_HW_RUNNING, &w->wdt.status);
} else { /* If WDG is not running so we will initializate it */
ret = init_wdg_hw(w); if (ret) return ret;
}
dev_dbg(w->dev, "heartbeat set to %u - %u\n",
w->wdt.min_hw_heartbeat_ms, w->wdt.max_hw_heartbeat_ms);
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.