/* * Section 3.4 of the datasheet * The password sequence protects the WDT control register from unintended * write actions, which might cause malfunction of the WDT. * * essentially the following two magic passwords need to be written to allow * IO access to the WDT core
*/ #define LTQ_WDT_CR_PW1 0x00BE0000 #define LTQ_WDT_CR_PW2 0x00DC0000
#define LTQ_WDT_CR 0x0 /* watchdog control register */ #define LTQ_WDT_CR_GEN BIT(31) /* enable bit */ /* Pre-warning limit set to 1/16 of max WDT period */ #define LTQ_WDT_CR_PWL (0x3 << 26) /* set clock divider to 0x40000 */ #define LTQ_WDT_CR_CLKDIV (0x3 << 24) #define LTQ_WDT_CR_PW_MASK GENMASK(23, 16) /* Password field */ #define LTQ_WDT_CR_MAX_TIMEOUT ((1 << 16) - 1) /* The reload field is 16 bit */ #define LTQ_WDT_SR 0x8 /* watchdog status register */ #define LTQ_WDT_SR_EN BIT(31) /* Enable */ #define LTQ_WDT_SR_VALUE_MASK GENMASK(15, 0) /* Timer value */
#define LTQ_WDT_DIVIDER 0x40000
staticbool nowayout = WATCHDOG_NOWAYOUT;
struct ltq_wdt_hw { int (*bootstatus_get)(struct device *dev);
};
ltq_wdt_mask(priv, LTQ_WDT_CR_PW_MASK, LTQ_WDT_CR_PW1, LTQ_WDT_CR); /* write the second magic plus the configuration and new timeout */
ltq_wdt_mask(priv, LTQ_WDT_CR_PW_MASK | LTQ_WDT_CR_MAX_TIMEOUT,
LTQ_WDT_CR_GEN | LTQ_WDT_CR_PWL | LTQ_WDT_CR_CLKDIV |
LTQ_WDT_CR_PW2 | timeout,
LTQ_WDT_CR);
ltq_wdt_mask(priv, LTQ_WDT_CR_PW_MASK, LTQ_WDT_CR_PW1, LTQ_WDT_CR); /* write the second magic plus the configuration and new timeout */
ltq_wdt_mask(priv, LTQ_WDT_CR_PW_MASK | LTQ_WDT_CR_MAX_TIMEOUT,
LTQ_WDT_CR_PW2 | timeout, LTQ_WDT_CR);
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM;
priv->membase = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(priv->membase)) return PTR_ERR(priv->membase);
/* we do not need to enable the clock as it is always running */
clk = clk_get_io();
priv->clk_rate = clk_get_rate(clk) / LTQ_WDT_DIVIDER; if (!priv->clk_rate) {
dev_err(dev, "clock rate less than divider %i\n",
LTQ_WDT_DIVIDER); return -EINVAL;
}
status = ltq_wdt_r32(priv, LTQ_WDT_SR); if (status & LTQ_WDT_SR_EN) { /* * If the watchdog is already running overwrite it with our * new settings. Stop is not needed as the start call will * replace all settings anyway.
*/
ltq_wdt_start(wdt);
set_bit(WDOG_HW_RUNNING, &wdt->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.