// SPDX-License-Identifier: GPL-2.0 /* * Watchdog driver for the K3 RTI module * * (c) Copyright 2019-2020 Texas Instruments Inc. * All rights reserved.
*/
/* * struct to hold data for each WDT device * @base - base io address of WD device * @freq - source clock frequency of WDT * @wdd - hold watchdog device as is in WDT core
*/ struct rti_wdt_device { void __iomem *base; unsignedlong freq; struct watchdog_device wdd;
};
ret = pm_runtime_resume_and_get(wdd->parent); if (ret) return ret;
/* set timeout period */
timer_margin = (u64)wdd->timeout * wdt->freq;
timer_margin >>= WDT_PRELOAD_SHIFT; if (timer_margin > WDT_PRELOAD_MAX)
timer_margin = WDT_PRELOAD_MAX;
writel_relaxed(timer_margin, wdt->base + RTIDWDPRLD);
/* * RTI only supports a windowed mode, where the watchdog can only * be petted during the open window; not too early or not too late. * The HW configuration options only allow for the open window size * to be 50% or less than that; we obviouly want to configure the open * window as large as possible so we select the 50% option.
*/
wdd->min_hw_heartbeat_ms = 520 * wdd->timeout + MAX_HW_ERROR;
/* put watchdog in service state */
writel_relaxed(WDKEY_SEQ0, wdt->base + RTIWDKEY); /* put watchdog in active state */
writel_relaxed(WDKEY_SEQ1, wdt->base + RTIWDKEY);
return 0;
}
staticint rti_wdt_setup_hw_hb(struct watchdog_device *wdd, u32 wsize)
{ /* * RTI only supports a windowed mode, where the watchdog can only * be petted during the open window; not too early or not too late. * The HW configuration options only allow for the open window size * to be 50% or less than that. * To avoid any glitches, we accommodate 2% + max hardware error * safety margin.
*/ switch (wsize) { case RTIWWDSIZE_50P: /* 50% open window => 52% min heartbeat */
wdd->min_hw_heartbeat_ms = 520 * heartbeat + MAX_HW_ERROR; break;
case RTIWWDSIZE_25P: /* 25% open window => 77% min heartbeat */
wdd->min_hw_heartbeat_ms = 770 * heartbeat + MAX_HW_ERROR; break;
case RTIWWDSIZE_12P5: /* 12.5% open window => 89.5% min heartbeat */
wdd->min_hw_heartbeat_ms = 895 * heartbeat + MAX_HW_ERROR; break;
case RTIWWDSIZE_6P25: /* 6.5% open window => 95.5% min heartbeat */
wdd->min_hw_heartbeat_ms = 955 * heartbeat + MAX_HW_ERROR; break;
case RTIWWDSIZE_3P125: /* 3.125% open window => 98.9% min heartbeat */
wdd->min_hw_heartbeat_ms = 989 * heartbeat + MAX_HW_ERROR; break;
wsize = readl(wdt->base + RTIWWDSIZECTRL);
ret = rti_wdt_setup_hw_hb(wdd, wsize); if (ret) {
dev_err(dev, "bad window size.\n"); goto err_iomap;
}
last_ping = heartbeat_ms - time_left_ms; if (time_left_ms > heartbeat_ms) {
dev_warn(dev, "time_left > heartbeat? Assuming last ping just before now.\n");
last_ping = 0;
}
}
ret = of_reserved_mem_region_to_resource(pdev->dev.of_node, 0, &res); if (!ret) { /* * If reserved memory is defined for watchdog reset cause. * Readout the Power-on(PON) reason and pass to bootstatus.
*/
paddr = res.start;
reserved_mem_size = resource_size(&res); if (reserved_mem_size < RESERVED_MEM_MIN_SIZE) {
dev_err(dev, "The size of reserved memory is too small.\n");
ret = -EINVAL; goto err_iomap;
}
vaddr = memremap(paddr, reserved_mem_size, MEMREMAP_WB); if (!vaddr) {
dev_err(dev, "Failed to map memory-region.\n");
ret = -ENOMEM; goto err_iomap;
}
MODULE_AUTHOR("Tero Kristo ");
MODULE_DESCRIPTION("K3 RTI Watchdog Driver");
module_param(heartbeat, int, 0);
MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat period in seconds from 1 to "
__MODULE_STRING(MAX_HEARTBEAT) ", default "
__MODULE_STRING(DEFAULT_HEARTBEAT));
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.