staticbool early_enable;
module_param(early_enable, bool, 0);
MODULE_PARM_DESC(early_enable, "Watchdog is started on module insertion (default=false)");
/* * Conforming to the documentation, the timeout counter is * loaded when servicing is operated (aka ping) or when the * counter is enabled. In case the watchdog is already started * it must be stopped and started again to update the timeout * register or a ping can be sent to refresh the counter. Here * we choose to send a ping to the watchdog which is harmless * if the watchdog is stopped.
*/ return s32g_wdt_ping(wdog);
}
/* * The counter output can be read only if the SWT is * disabled. Given the latency between the internal counter * and the counter output update, there can be very small * difference. However, we can accept this matter of fact * given the resolution is a second based unit for the output.
*/
is_running = watchdog_hw_running(wdog);
/* Set the watchdog's Time-Out value */
val = wdog_sec_to_count(wdev, wdev->wdog.timeout);
writel(val, S32G_SWT_TO(wdev->base));
/* * Get the control register content. We are at init time, the * watchdog should not be started.
*/
val = readl(S32G_SWT_CR(wdev->base));
/* * We want to allow the watchdog timer to be stopped when * device enters debug mode.
*/
val |= S32G_SWT_CR_FRZ;
/* * However, when the CPU is in WFI or suspend mode, the * watchdog must continue. The documentation refers it as the * stopped mode.
*/
val &= ~S32G_SWT_CR_STP;
/* * Use Fixed Service Sequence to ping the watchdog which is * 0x00 configuration value for the service mode. It should be * already set because it is the default value but we reset it * in case.
*/
val &= ~S32G_SWT_CR_SM;
writel(val, S32G_SWT_CR(wdev->base));
/* * When the 'early_enable' option is set, we start the * watchdog from the kernel.
*/ if (early_enable) {
s32g_wdt_start(&wdev->wdog);
set_bit(WDOG_HW_RUNNING, &wdev->wdog.status);
}
}
wdev = devm_kzalloc(dev, sizeof(*wdev), GFP_KERNEL); if (!wdev) return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
wdev->base = devm_ioremap_resource(dev, res); if (IS_ERR(wdev->base)) return dev_err_probe(&pdev->dev, PTR_ERR(wdev->base), "Can not get resource\n");
clk = devm_clk_get_enabled(dev, "counter"); if (IS_ERR(clk)) return dev_err_probe(dev, PTR_ERR(clk), "Can't get Watchdog clock\n");
wdev->rate = clk_get_rate(clk); if (!wdev->rate) {
dev_err(dev, "Input clock rate is not valid\n"); return -EINVAL;
}
/* * The code converts the timeout into a counter a value, if * the value is less than 0x100, then it is clamped by the SWT * module, so it is safe to specify a zero value as the * minimum timeout.
*/
wdog->min_timeout = 0;
/* * The counter register is a 32 bits long, so the maximum * counter value is UINT_MAX and the timeout in second is the * value divided by the rate. * * For instance, a rate of 51MHz lead to 84 seconds maximum * timeout.
*/
wdog->max_timeout = UINT_MAX / wdev->rate;
/* * The module param and the DT 'timeout-sec' property will * override the default value if they are specified.
*/
ret = watchdog_init_timeout(wdog, timeout_param, dev); if (ret) return ret;
/* * As soon as the watchdog is started, there is no way to stop * it if the 'nowayout' option is set at boot time
*/
watchdog_set_nowayout(wdog, nowayout);
/* * The devm_ version of the watchdog_register_device() * function will call watchdog_unregister_device() when the * device is removed.
*/
watchdog_stop_on_unregister(wdog);
s32g_wdt_init(wdev);
ret = devm_watchdog_register_device(dev, wdog); if (ret) return dev_err_probe(dev, ret, "Cannot register watchdog device\n");
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.