From 4497ee914f10264894b08066cbee026604cd244f Mon Sep 17 00:00:00 2001 From: Yan Zhen Date: Mon, 23 Sep 2024 15:50:16 +0800 Subject: watchdog: fix typo in the comment Correctly spelled comments make it easier for the reader to understand the code. Fix typos: 'hearbeat' -> 'heartbeat', 'retrigggers' -> 'retriggers', 'funtions' -> 'functions', 'Resgister' -> 'Register'. Signed-off-by: Yan Zhen Reviewed-by: Wim Van Sebroeck Link: https://lore.kernel.org/r/20240923075016.2439774-1-yanzhen@vivo.com Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/pcwd.c | 2 +- drivers/watchdog/rzn1_wdt.c | 2 +- drivers/watchdog/smsc37b787_wdt.c | 2 +- drivers/watchdog/starfive-wdt.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/watchdog/pcwd.c b/drivers/watchdog/pcwd.c index 1a4282235aac..31d3dcbf815e 100644 --- a/drivers/watchdog/pcwd.c +++ b/drivers/watchdog/pcwd.c @@ -833,7 +833,7 @@ static int pcwd_isa_match(struct device *dev, unsigned int id) port0 = inb_p(base_addr); port1 = inb_p(base_addr + 1); - /* Has either hearbeat bit changed? */ + /* Has either heartbeat bit changed? */ if ((port0 ^ last_port0) & WD_HRTBT || (port1 ^ last_port1) & WD_REVC_HRBT) { retval = 1; diff --git a/drivers/watchdog/rzn1_wdt.c b/drivers/watchdog/rzn1_wdt.c index 7d3192d34afd..96fd04fbc2a2 100644 --- a/drivers/watchdog/rzn1_wdt.c +++ b/drivers/watchdog/rzn1_wdt.c @@ -52,7 +52,7 @@ static int rzn1_wdt_ping(struct watchdog_device *w) { struct rzn1_watchdog *wdt = watchdog_get_drvdata(w); - /* Any value retrigggers the watchdog */ + /* Any value retriggers the watchdog */ writel(0, wdt->base + RZN1_WDT_RETRIGGER); return 0; diff --git a/drivers/watchdog/smsc37b787_wdt.c b/drivers/watchdog/smsc37b787_wdt.c index 97ca500ec8a8..3011e1af00f9 100644 --- a/drivers/watchdog/smsc37b787_wdt.c +++ b/drivers/watchdog/smsc37b787_wdt.c @@ -485,7 +485,7 @@ static long wb_smsc_wdt_ioctl(struct file *file, } } -/* -- Notifier funtions -----------------------------------------*/ +/* -- Notifier functions -----------------------------------------*/ static int wb_smsc_wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) diff --git a/drivers/watchdog/starfive-wdt.c b/drivers/watchdog/starfive-wdt.c index 19a2620d3d38..a8b6cf767117 100644 --- a/drivers/watchdog/starfive-wdt.c +++ b/drivers/watchdog/starfive-wdt.c @@ -80,7 +80,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); struct starfive_wdt_variant { - unsigned int control; /* Watchdog Control Resgister for reset enable */ + unsigned int control; /* Watchdog Control Register for reset enable */ unsigned int load; /* Watchdog Load register */ unsigned int reload; /* Watchdog Reload Control register */ unsigned int enable; /* Watchdog Enable Register */ -- cgit v1.2.3 From daa814d784ac034c62ab3fb0ef83daeafef527e2 Mon Sep 17 00:00:00 2001 From: Oleksandr Ocheretnyi Date: Fri, 13 Sep 2024 12:14:03 -0700 Subject: iTCO_wdt: mask NMI_NOW bit for update_no_reboot_bit() call Commit da23b6faa8bf ("watchdog: iTCO: Add support for Cannon Lake PCH iTCO") does not mask NMI_NOW bit during TCO1_CNT register's value comparison for update_no_reboot_bit() call causing following failure: ... iTCO_vendor_support: vendor-support=0 iTCO_wdt iTCO_wdt: unable to reset NO_REBOOT flag, device disabled by hardware/BIOS ... and this can lead to unexpected NMIs later during regular crashkernel's workflow because of watchdog probe call failures. This change masks NMI_NOW bit for TCO1_CNT register values to avoid unexpected NMI_NOW bit inversions. Fixes: da23b6faa8bf ("watchdog: iTCO: Add support for Cannon Lake PCH iTCO") Signed-off-by: Oleksandr Ocheretnyi Reviewed-by: Guenter Roeck Reviewed-by: Mika Westerberg Link: https://lore.kernel.org/r/20240913191403.2560805-1-oocheret@cisco.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/iTCO_wdt.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index 35b358bcf94c..f01ed38aba67 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c @@ -82,6 +82,13 @@ #define TCO2_CNT(p) (TCOBASE(p) + 0x0a) /* TCO2 Control Register */ #define TCOv2_TMR(p) (TCOBASE(p) + 0x12) /* TCOv2 Timer Initial Value*/ +/* + * NMI_NOW is bit 8 of TCO1_CNT register + * Read/Write + * This bit is implemented as RW but has no effect on HW. + */ +#define NMI_NOW BIT(8) + /* internal variables */ struct iTCO_wdt_private { struct watchdog_device wddev; @@ -219,13 +226,23 @@ static int update_no_reboot_bit_cnt(void *priv, bool set) struct iTCO_wdt_private *p = priv; u16 val, newval; - val = inw(TCO1_CNT(p)); + /* + * writing back 1b1 to NMI_NOW of TCO1_CNT register + * causes NMI_NOW bit inversion what consequently does + * not allow to perform the register's value comparison + * properly. + * + * NMI_NOW bit masking for TCO1_CNT register values + * helps to avoid possible NMI_NOW bit inversions on + * following write operation. + */ + val = inw(TCO1_CNT(p)) & ~NMI_NOW; if (set) val |= BIT(0); else val &= ~BIT(0); outw(val, TCO1_CNT(p)); - newval = inw(TCO1_CNT(p)); + newval = inw(TCO1_CNT(p)) & ~NMI_NOW; /* make sure the update is successful */ return val != newval ? -EIO : 0; -- cgit v1.2.3 From 006778844c2c132c28cfa90e3570560351e01b9a Mon Sep 17 00:00:00 2001 From: Harini T Date: Fri, 13 Sep 2024 17:02:30 +0530 Subject: watchdog: xilinx_wwdt: Calculate max_hw_heartbeat_ms using clock frequency In the current implementation, the value of max_hw_heartbeat_ms is set to the timeout period expressed in milliseconds and fails to verify if the close window percentage exceeds the maximum value that the hardware supports. 1. Calculate max_hw_heartbeat_ms based on input clock frequency. 2. Update frequency check to require a minimum frequency of 1Mhz. 3. Limit the close and open window percent to hardware supported value to avoid truncation. 4. If the user input timeout exceeds the maximum timeout supported, use only open window and the framework supports the higher timeouts. Fixes: 12984cea1b8c ("watchdog: xilinx_wwdt: Add Versal window watchdog support") Signed-off-by: Harini T Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20240913113230.1939373-1-harini.t@amd.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/xilinx_wwdt.c | 75 +++++++++++++++++++++++++++++++++++------- 1 file changed, 63 insertions(+), 12 deletions(-) diff --git a/drivers/watchdog/xilinx_wwdt.c b/drivers/watchdog/xilinx_wwdt.c index d271e2e8d6e2..3d2a156f7180 100644 --- a/drivers/watchdog/xilinx_wwdt.c +++ b/drivers/watchdog/xilinx_wwdt.c @@ -2,7 +2,7 @@ /* * Window watchdog device driver for Xilinx Versal WWDT * - * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc. + * Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc. */ #include @@ -36,6 +36,12 @@ #define XWWDT_CLOSE_WINDOW_PERCENT 50 +/* Maximum count value of each 32 bit window */ +#define XWWDT_MAX_COUNT_WINDOW GENMASK(31, 0) + +/* Maximum count value of closed and open window combined */ +#define XWWDT_MAX_COUNT_WINDOW_COMBINED GENMASK_ULL(32, 1) + static int wwdt_timeout; static int closed_window_percent; @@ -54,6 +60,8 @@ MODULE_PARM_DESC(closed_window_percent, * @xilinx_wwdt_wdd: watchdog device structure * @freq: source clock frequency of WWDT * @close_percent: Closed window percent + * @closed_timeout: Closed window timeout in ticks + * @open_timeout: Open window timeout in ticks */ struct xwwdt_device { void __iomem *base; @@ -61,27 +69,22 @@ struct xwwdt_device { struct watchdog_device xilinx_wwdt_wdd; unsigned long freq; u32 close_percent; + u64 closed_timeout; + u64 open_timeout; }; static int xilinx_wwdt_start(struct watchdog_device *wdd) { struct xwwdt_device *xdev = watchdog_get_drvdata(wdd); struct watchdog_device *xilinx_wwdt_wdd = &xdev->xilinx_wwdt_wdd; - u64 time_out, closed_timeout, open_timeout; u32 control_status_reg; - /* Calculate timeout count */ - time_out = xdev->freq * wdd->timeout; - closed_timeout = div_u64(time_out * xdev->close_percent, 100); - open_timeout = time_out - closed_timeout; - wdd->min_hw_heartbeat_ms = xdev->close_percent * 10 * wdd->timeout; - spin_lock(&xdev->spinlock); iowrite32(XWWDT_MWR_MASK, xdev->base + XWWDT_MWR_OFFSET); iowrite32(~(u32)XWWDT_ESR_WEN_MASK, xdev->base + XWWDT_ESR_OFFSET); - iowrite32((u32)closed_timeout, xdev->base + XWWDT_FWR_OFFSET); - iowrite32((u32)open_timeout, xdev->base + XWWDT_SWR_OFFSET); + iowrite32((u32)xdev->closed_timeout, xdev->base + XWWDT_FWR_OFFSET); + iowrite32((u32)xdev->open_timeout, xdev->base + XWWDT_SWR_OFFSET); /* Enable the window watchdog timer */ control_status_reg = ioread32(xdev->base + XWWDT_ESR_OFFSET); @@ -133,7 +136,12 @@ static int xwwdt_probe(struct platform_device *pdev) struct watchdog_device *xilinx_wwdt_wdd; struct device *dev = &pdev->dev; struct xwwdt_device *xdev; + u64 max_per_window_ms; + u64 min_per_window_ms; + u64 timeout_count; struct clk *clk; + u32 timeout_ms; + u64 ms_count; int ret; xdev = devm_kzalloc(dev, sizeof(*xdev), GFP_KERNEL); @@ -154,12 +162,13 @@ static int xwwdt_probe(struct platform_device *pdev) return PTR_ERR(clk); xdev->freq = clk_get_rate(clk); - if (!xdev->freq) + if (xdev->freq < 1000000) return -EINVAL; xilinx_wwdt_wdd->min_timeout = XWWDT_MIN_TIMEOUT; xilinx_wwdt_wdd->timeout = XWWDT_DEFAULT_TIMEOUT; - xilinx_wwdt_wdd->max_hw_heartbeat_ms = 1000 * xilinx_wwdt_wdd->timeout; + xilinx_wwdt_wdd->max_hw_heartbeat_ms = + div64_u64(XWWDT_MAX_COUNT_WINDOW_COMBINED, xdev->freq) * 1000; if (closed_window_percent == 0 || closed_window_percent >= 100) xdev->close_percent = XWWDT_CLOSE_WINDOW_PERCENT; @@ -167,6 +176,48 @@ static int xwwdt_probe(struct platform_device *pdev) xdev->close_percent = closed_window_percent; watchdog_init_timeout(xilinx_wwdt_wdd, wwdt_timeout, &pdev->dev); + + /* Calculate ticks for 1 milli-second */ + ms_count = div_u64(xdev->freq, 1000); + timeout_ms = xilinx_wwdt_wdd->timeout * 1000; + timeout_count = timeout_ms * ms_count; + + if (timeout_ms > xilinx_wwdt_wdd->max_hw_heartbeat_ms) { + /* + * To avoid ping restrictions until the minimum hardware heartbeat, + * we will solely rely on the open window and + * adjust the minimum hardware heartbeat to 0. + */ + xdev->closed_timeout = 0; + xdev->open_timeout = XWWDT_MAX_COUNT_WINDOW; + xilinx_wwdt_wdd->min_hw_heartbeat_ms = 0; + xilinx_wwdt_wdd->max_hw_heartbeat_ms = xilinx_wwdt_wdd->max_hw_heartbeat_ms / 2; + } else { + xdev->closed_timeout = div64_u64(timeout_count * xdev->close_percent, 100); + xilinx_wwdt_wdd->min_hw_heartbeat_ms = + div64_u64(timeout_ms * xdev->close_percent, 100); + + if (timeout_ms > xilinx_wwdt_wdd->max_hw_heartbeat_ms / 2) { + max_per_window_ms = xilinx_wwdt_wdd->max_hw_heartbeat_ms / 2; + min_per_window_ms = timeout_ms - max_per_window_ms; + + if (xilinx_wwdt_wdd->min_hw_heartbeat_ms > max_per_window_ms) { + dev_info(xilinx_wwdt_wdd->parent, + "Closed window cannot be set to %d%%. Using maximum supported value.\n", + xdev->close_percent); + xdev->closed_timeout = max_per_window_ms * ms_count; + xilinx_wwdt_wdd->min_hw_heartbeat_ms = max_per_window_ms; + } else if (xilinx_wwdt_wdd->min_hw_heartbeat_ms < min_per_window_ms) { + dev_info(xilinx_wwdt_wdd->parent, + "Closed window cannot be set to %d%%. Using minimum supported value.\n", + xdev->close_percent); + xdev->closed_timeout = min_per_window_ms * ms_count; + xilinx_wwdt_wdd->min_hw_heartbeat_ms = min_per_window_ms; + } + } + xdev->open_timeout = timeout_count - xdev->closed_timeout; + } + spin_lock_init(&xdev->spinlock); watchdog_set_drvdata(xilinx_wwdt_wdd, xdev); watchdog_set_nowayout(xilinx_wwdt_wdd, 1); -- cgit v1.2.3 From b2dd16c277bce344b168ed5286f2378868a58d42 Mon Sep 17 00:00:00 2001 From: lijuang Date: Fri, 20 Sep 2024 15:11:41 +0800 Subject: dt-bindings: watchdog: Document Qualcomm QCS615 watchdog Add devicetree binding for watchdog present on Qualcomm QCS615 SoC. Signed-off-by: Lijuan Gao Acked-by: Rob Herring (Arm) Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20240920-add_watchdog_compatible_for_qcs615-v2-1-427944f1151e@quicinc.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml b/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml index 932393f8c649..32eaf43aadb3 100644 --- a/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml @@ -26,6 +26,7 @@ properties: - qcom,apss-wdt-msm8994 - qcom,apss-wdt-qcm2290 - qcom,apss-wdt-qcs404 + - qcom,apss-wdt-qcs615 - qcom,apss-wdt-sa8255p - qcom,apss-wdt-sa8775p - qcom,apss-wdt-sc7180 -- cgit v1.2.3 From 8af9ff6b11122bf4b91378148ded7177bfbae582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 20 Sep 2024 17:34:36 +0200 Subject: watchdog: ziirave_wdt: Drop explicit initialization of struct i2c_device_id::driver_data to 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These drivers don't use the driver_data member of struct i2c_device_id, so don't explicitly initialize this member. This prepares putting driver_data in an anonymous union which requires either no initialization or named designators. But it's also a nice cleanup on its own. Signed-off-by: Uwe Kleine-König Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20240920153430.503212-18-u.kleine-koenig@baylibre.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/ziirave_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/watchdog/ziirave_wdt.c b/drivers/watchdog/ziirave_wdt.c index 775838346bb5..fcc1ba02e75b 100644 --- a/drivers/watchdog/ziirave_wdt.c +++ b/drivers/watchdog/ziirave_wdt.c @@ -715,7 +715,7 @@ static void ziirave_wdt_remove(struct i2c_client *client) } static const struct i2c_device_id ziirave_wdt_id[] = { - { "rave-wdt", 0 }, + { "rave-wdt" }, { } }; MODULE_DEVICE_TABLE(i2c, ziirave_wdt_id); -- cgit v1.2.3 From 68adabf48f79a46bf2bb615264a54d9bf88528e6 Mon Sep 17 00:00:00 2001 From: Xingyu Wu Date: Fri, 27 Sep 2024 14:50:32 +0800 Subject: MAINTAINERS: Update the maintainer of StarFive watchdog driver Samin quits maintaining the StarFive watchdog driver and Ziv joins instead. Update the maintainer of this driver from Samin to Ziv. Signed-off-by: Xingyu Wu Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20240927065032.2773997-1-xingyu.wu@starfivetech.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index bdae0faf000c..04a831ad728d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -22059,7 +22059,7 @@ F: drivers/char/hw_random/jh7110-trng.c STARFIVE WATCHDOG DRIVER M: Xingyu Wu -M: Samin Guo +M: Ziv Xu S: Supported F: Documentation/devicetree/bindings/watchdog/starfive* F: drivers/watchdog/starfive-wdt.c -- cgit v1.2.3 From 3ab1663af6c1ac7d4bd1fb1371a4972bac2922a4 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 15 Apr 2024 15:48:47 +0200 Subject: watchdog: stm32_iwdg: Add pretimeout support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The STM32MP15xx IWDG adds registers which permit this IP to generate pretimeout interrupt. This interrupt can also be used to wake the CPU from suspend. Implement support for generating this interrupt and let userspace configure the pretimeout. In case the pretimeout is not configured by user, set pretimeout to 3/4 of the WDT timeout cycle. Signed-off-by: Marek Vasut Reviewed-by: Clément Le Goffic Tested-by: Clément Le Goffic Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20240415134903.8084-1-marex@denx.de Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/stm32_iwdg.c | 95 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 1 deletion(-) diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c index 5404e0387620..d700e0d49bb9 100644 --- a/drivers/watchdog/stm32_iwdg.c +++ b/drivers/watchdog/stm32_iwdg.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #define DEFAULT_TIMEOUT 10 @@ -28,6 +29,7 @@ #define IWDG_RLR 0x08 /* ReLoad Register */ #define IWDG_SR 0x0C /* Status Register */ #define IWDG_WINR 0x10 /* Windows Register */ +#define IWDG_EWCR 0x14 /* Early Wake-up Register */ /* IWDG_KR register bit mask */ #define KR_KEY_RELOAD 0xAAAA /* reload counter enable */ @@ -47,22 +49,29 @@ #define SR_PVU BIT(0) /* Watchdog prescaler value update */ #define SR_RVU BIT(1) /* Watchdog counter reload value update */ +#define EWCR_EWIT GENMASK(11, 0) /* Watchdog counter window value */ +#define EWCR_EWIC BIT(14) /* Watchdog early interrupt acknowledge */ +#define EWCR_EWIE BIT(15) /* Watchdog early interrupt enable */ + /* set timeout to 100000 us */ #define TIMEOUT_US 100000 #define SLEEP_US 1000 struct stm32_iwdg_data { bool has_pclk; + bool has_early_wakeup; u32 max_prescaler; }; static const struct stm32_iwdg_data stm32_iwdg_data = { .has_pclk = false, + .has_early_wakeup = false, .max_prescaler = 256, }; static const struct stm32_iwdg_data stm32mp1_iwdg_data = { .has_pclk = true, + .has_early_wakeup = true, .max_prescaler = 1024, }; @@ -88,13 +97,18 @@ static inline void reg_write(void __iomem *base, u32 reg, u32 val) static int stm32_iwdg_start(struct watchdog_device *wdd) { struct stm32_iwdg *wdt = watchdog_get_drvdata(wdd); - u32 tout, presc, iwdg_rlr, iwdg_pr, iwdg_sr; + u32 tout, ptot, presc, iwdg_rlr, iwdg_ewcr, iwdg_pr, iwdg_sr; int ret; dev_dbg(wdd->parent, "%s\n", __func__); + if (!wdd->pretimeout) + wdd->pretimeout = 3 * wdd->timeout / 4; + tout = clamp_t(unsigned int, wdd->timeout, wdd->min_timeout, wdd->max_hw_heartbeat_ms / 1000); + ptot = clamp_t(unsigned int, tout - wdd->pretimeout, + wdd->min_timeout, tout); presc = DIV_ROUND_UP(tout * wdt->rate, RLR_MAX + 1); @@ -102,6 +116,7 @@ static int stm32_iwdg_start(struct watchdog_device *wdd) presc = roundup_pow_of_two(presc); iwdg_pr = presc <= 1 << PR_SHIFT ? 0 : ilog2(presc) - PR_SHIFT; iwdg_rlr = ((tout * wdt->rate) / presc) - 1; + iwdg_ewcr = ((ptot * wdt->rate) / presc) - 1; /* enable write access */ reg_write(wdt->regs, IWDG_KR, KR_KEY_EWA); @@ -109,6 +124,8 @@ static int stm32_iwdg_start(struct watchdog_device *wdd) /* set prescaler & reload registers */ reg_write(wdt->regs, IWDG_PR, iwdg_pr); reg_write(wdt->regs, IWDG_RLR, iwdg_rlr); + if (wdt->data->has_early_wakeup) + reg_write(wdt->regs, IWDG_EWCR, iwdg_ewcr | EWCR_EWIE); reg_write(wdt->regs, IWDG_KR, KR_KEY_ENABLE); /* wait for the registers to be updated (max 100ms) */ @@ -151,6 +168,34 @@ static int stm32_iwdg_set_timeout(struct watchdog_device *wdd, return 0; } +static int stm32_iwdg_set_pretimeout(struct watchdog_device *wdd, + unsigned int pretimeout) +{ + dev_dbg(wdd->parent, "%s pretimeout: %d sec\n", __func__, pretimeout); + + wdd->pretimeout = pretimeout; + + if (watchdog_active(wdd)) + return stm32_iwdg_start(wdd); + + return 0; +} + +static irqreturn_t stm32_iwdg_isr(int irq, void *wdog_arg) +{ + struct watchdog_device *wdd = wdog_arg; + struct stm32_iwdg *wdt = watchdog_get_drvdata(wdd); + u32 reg; + + reg = reg_read(wdt->regs, IWDG_EWCR); + reg |= EWCR_EWIC; + reg_write(wdt->regs, IWDG_EWCR, reg); + + watchdog_notify_pretimeout(wdd); + + return IRQ_HANDLED; +} + static void stm32_clk_disable_unprepare(void *data) { clk_disable_unprepare(data); @@ -207,11 +252,20 @@ static const struct watchdog_info stm32_iwdg_info = { .identity = "STM32 Independent Watchdog", }; +static const struct watchdog_info stm32_iwdg_preinfo = { + .options = WDIOF_SETTIMEOUT | + WDIOF_MAGICCLOSE | + WDIOF_KEEPALIVEPING | + WDIOF_PRETIMEOUT, + .identity = "STM32 Independent Watchdog", +}; + static const struct watchdog_ops stm32_iwdg_ops = { .owner = THIS_MODULE, .start = stm32_iwdg_start, .ping = stm32_iwdg_ping, .set_timeout = stm32_iwdg_set_timeout, + .set_pretimeout = stm32_iwdg_set_pretimeout, }; static const struct of_device_id stm32_iwdg_of_match[] = { @@ -221,6 +275,40 @@ static const struct of_device_id stm32_iwdg_of_match[] = { }; MODULE_DEVICE_TABLE(of, stm32_iwdg_of_match); +static int stm32_iwdg_irq_init(struct platform_device *pdev, + struct stm32_iwdg *wdt) +{ + struct device_node *np = pdev->dev.of_node; + struct watchdog_device *wdd = &wdt->wdd; + struct device *dev = &pdev->dev; + int irq, ret; + + if (!wdt->data->has_early_wakeup) + return 0; + + irq = platform_get_irq(pdev, 0); + if (irq <= 0) + return 0; + + if (of_property_read_bool(np, "wakeup-source")) { + ret = device_init_wakeup(dev, true); + if (ret) + return ret; + + ret = dev_pm_set_wake_irq(dev, irq); + if (ret) + return ret; + } + + ret = devm_request_irq(dev, irq, stm32_iwdg_isr, 0, + dev_name(dev), wdd); + if (ret) + return ret; + + wdd->info = &stm32_iwdg_preinfo; + return 0; +} + static int stm32_iwdg_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -255,6 +343,11 @@ static int stm32_iwdg_probe(struct platform_device *pdev) wdd->max_hw_heartbeat_ms = ((RLR_MAX + 1) * wdt->data->max_prescaler * 1000) / wdt->rate; + /* Initialize IRQ, this might override wdd->info, hence it is here. */ + ret = stm32_iwdg_irq_init(pdev, wdt); + if (ret) + return ret; + watchdog_set_drvdata(wdd, wdt); watchdog_set_nowayout(wdd, WATCHDOG_NOWAYOUT); watchdog_init_timeout(wdd, 0, dev); -- cgit v1.2.3 From 51dfe714c03c066aabc815a2bb2adcc998dfcb30 Mon Sep 17 00:00:00 2001 From: Nick Chan Date: Wed, 2 Oct 2024 00:59:51 +0800 Subject: watchdog: apple: Actually flush writes after requesting watchdog restart Although there is an existing code comment about flushing the writes, writes were not actually being flushed. Actually flush the writes by changing readl_relaxed() to readl(). Fixes: 4ed224aeaf661 ("watchdog: Add Apple SoC watchdog driver") Suggested-by: Arnd Bergmann Signed-off-by: Nick Chan Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241001170018.20139-2-towinchenmi@gmail.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/apple_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/watchdog/apple_wdt.c b/drivers/watchdog/apple_wdt.c index d4f739932f0b..62dabf223d90 100644 --- a/drivers/watchdog/apple_wdt.c +++ b/drivers/watchdog/apple_wdt.c @@ -130,7 +130,7 @@ static int apple_wdt_restart(struct watchdog_device *wdd, unsigned long mode, * can take up to ~20-25ms until the SoC is actually reset. Just wait * 50ms here to be safe. */ - (void)readl_relaxed(wdt->regs + APPLE_WDT_WD1_CUR_TIME); + (void)readl(wdt->regs + APPLE_WDT_WD1_CUR_TIME); mdelay(50); return 0; -- cgit v1.2.3 From e6a08988eb5948a99d1f3b48afab4ffff01ae9a4 Mon Sep 17 00:00:00 2001 From: Nick Chan Date: Wed, 2 Oct 2024 00:59:52 +0800 Subject: watchdog: apple: Increase reset delay to 150ms The Apple A8X SoC seems to be slowest at resetting, taking up to around 125ms to reset. Wait 150ms to be safe here. Signed-off-by: Nick Chan Reviewed-by: Sven Peter Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241001170018.20139-3-towinchenmi@gmail.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/apple_wdt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/watchdog/apple_wdt.c b/drivers/watchdog/apple_wdt.c index 62dabf223d90..95d9e37df41c 100644 --- a/drivers/watchdog/apple_wdt.c +++ b/drivers/watchdog/apple_wdt.c @@ -127,11 +127,11 @@ static int apple_wdt_restart(struct watchdog_device *wdd, unsigned long mode, /* * Flush writes and then wait for the SoC to reset. Even though the * reset is queued almost immediately experiments have shown that it - * can take up to ~20-25ms until the SoC is actually reset. Just wait - * 50ms here to be safe. + * can take up to ~120-125ms until the SoC is actually reset. Just + * wait 150ms here to be safe. */ (void)readl(wdt->regs + APPLE_WDT_WD1_CUR_TIME); - mdelay(50); + mdelay(150); return 0; } -- cgit v1.2.3 From 06ba0b8da1daabaf10dbec4c04e883d7a6c81706 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Thu, 3 Oct 2024 14:45:08 -0700 Subject: watchdog: armada_37xx_wdt: remove struct resource MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No need for it with devm_platform_ioremap_resource. Simplifies probe slightly. Signed-off-by: Rosen Penev Reviewed-by: Marek Behún Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241003214508.121107-1-rosenp@gmail.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/armada_37xx_wdt.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/watchdog/armada_37xx_wdt.c b/drivers/watchdog/armada_37xx_wdt.c index 8133a5d05647..a17a7911771a 100644 --- a/drivers/watchdog/armada_37xx_wdt.c +++ b/drivers/watchdog/armada_37xx_wdt.c @@ -248,7 +248,6 @@ static const struct watchdog_ops armada_37xx_wdt_ops = { static int armada_37xx_wdt_probe(struct platform_device *pdev) { struct armada_37xx_watchdog *dev; - struct resource *res; struct regmap *regmap; int ret; @@ -266,12 +265,9 @@ static int armada_37xx_wdt_probe(struct platform_device *pdev) return PTR_ERR(regmap); dev->cpu_misc = regmap; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - dev->reg = devm_ioremap(&pdev->dev, res->start, resource_size(res)); - if (!dev->reg) - return -ENOMEM; + dev->reg = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(dev->reg)) + return PTR_ERR(dev->reg); /* init clock */ dev->clk = devm_clk_get_enabled(&pdev->dev, NULL); -- cgit v1.2.3 From 140fb00c40c1b751eb352c09c608477444da0420 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 4 Oct 2024 22:03:04 +0200 Subject: watchdog: always print when registering watchdog fails So far, only 'watchdog_register_device' prints an error if registering the watchdog driver fails. '__watchdog_register_device' doesn't. Refactor the code so that both print out. Drivers can then rely on that and skip their own error messages. Signed-off-by: Wolfram Sang Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241004200314.5459-2-wsa+renesas@sang-engineering.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/watchdog_core.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/drivers/watchdog/watchdog_core.c b/drivers/watchdog/watchdog_core.c index aff2c3912ead..d46d8c8c01f2 100644 --- a/drivers/watchdog/watchdog_core.c +++ b/drivers/watchdog/watchdog_core.c @@ -237,7 +237,7 @@ void watchdog_set_restart_priority(struct watchdog_device *wdd, int priority) } EXPORT_SYMBOL_GPL(watchdog_set_restart_priority); -static int __watchdog_register_device(struct watchdog_device *wdd) +static int ___watchdog_register_device(struct watchdog_device *wdd) { int ret, id = -1; @@ -337,6 +337,22 @@ static int __watchdog_register_device(struct watchdog_device *wdd) return 0; } +static int __watchdog_register_device(struct watchdog_device *wdd) +{ + const char *dev_str; + int ret; + + ret = ___watchdog_register_device(wdd); + if (ret) { + dev_str = wdd->parent ? dev_name(wdd->parent) : + (const char *)wdd->info->identity; + pr_err("%s: failed to register watchdog device (err = %d)\n", + dev_str, ret); + } + + return ret; +} + /** * watchdog_register_device() - register a watchdog device * @wdd: watchdog device @@ -350,7 +366,6 @@ static int __watchdog_register_device(struct watchdog_device *wdd) int watchdog_register_device(struct watchdog_device *wdd) { - const char *dev_str; int ret = 0; mutex_lock(&wtd_deferred_reg_mutex); @@ -360,13 +375,6 @@ int watchdog_register_device(struct watchdog_device *wdd) watchdog_deferred_registration_add(wdd); mutex_unlock(&wtd_deferred_reg_mutex); - if (ret) { - dev_str = wdd->parent ? dev_name(wdd->parent) : - (const char *)wdd->info->identity; - pr_err("%s: failed to register watchdog device (err = %d)\n", - dev_str, ret); - } - return ret; } EXPORT_SYMBOL_GPL(watchdog_register_device); -- cgit v1.2.3 From c9e8ba37163a34929304d9c5f6392bd038d6cfe5 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 4 Oct 2024 22:03:05 +0200 Subject: watchdog: da9055_wdt: don't print out if registering watchdog fails The core will do this already. Signed-off-by: Wolfram Sang Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241004200314.5459-3-wsa+renesas@sang-engineering.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/da9055_wdt.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/watchdog/da9055_wdt.c b/drivers/watchdog/da9055_wdt.c index 389a4bdd208c..9d5a2009466f 100644 --- a/drivers/watchdog/da9055_wdt.c +++ b/drivers/watchdog/da9055_wdt.c @@ -146,12 +146,7 @@ static int da9055_wdt_probe(struct platform_device *pdev) return ret; } - ret = devm_watchdog_register_device(dev, &driver_data->wdt); - if (ret != 0) - dev_err(da9055->dev, "watchdog_register_device() failed: %d\n", - ret); - - return ret; + return devm_watchdog_register_device(dev, &driver_data->wdt); } static struct platform_driver da9055_wdt_driver = { -- cgit v1.2.3 From 7022274d625935d99c2a5c8ac84ed4754229ce64 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 4 Oct 2024 22:03:06 +0200 Subject: watchdog: gxp-wdt: don't print out if registering watchdog fails The core will do this already. Signed-off-by: Wolfram Sang Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241004200314.5459-4-wsa+renesas@sang-engineering.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/gxp-wdt.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/watchdog/gxp-wdt.c b/drivers/watchdog/gxp-wdt.c index 2fd85be88278..f2c236160266 100644 --- a/drivers/watchdog/gxp-wdt.c +++ b/drivers/watchdog/gxp-wdt.c @@ -151,10 +151,8 @@ static int gxp_wdt_probe(struct platform_device *pdev) watchdog_stop_on_reboot(&drvdata->wdd); err = devm_watchdog_register_device(dev, &drvdata->wdd); - if (err) { - dev_err(dev, "Failed to register watchdog device"); + if (err) return err; - } dev_info(dev, "HPE GXP watchdog timer"); -- cgit v1.2.3 From fb2de4ea05780b19cb4c082b481d65477564ddce Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 4 Oct 2024 22:03:07 +0200 Subject: watchdog: iTCO_wdt: don't print out if registering watchdog fails The core will do this already. Signed-off-by: Wolfram Sang Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241004200314.5459-5-wsa+renesas@sang-engineering.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/iTCO_wdt.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index f01ed38aba67..7672582fa407 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c @@ -609,10 +609,8 @@ static int iTCO_wdt_probe(struct platform_device *pdev) watchdog_stop_on_reboot(&p->wddev); watchdog_stop_on_unregister(&p->wddev); ret = devm_watchdog_register_device(dev, &p->wddev); - if (ret != 0) { - dev_err(dev, "cannot register watchdog device (err=%d)\n", ret); + if (ret != 0) return ret; - } dev_info(dev, "initialized. heartbeat=%d sec (nowayout=%d)\n", heartbeat, nowayout); -- cgit v1.2.3 From ebc75304f0b65246dedc79c6b7a9c98ee64e3a8c Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 4 Oct 2024 22:03:08 +0200 Subject: watchdog: it87_wdt: don't print out if registering watchdog fails The core will do this already. Signed-off-by: Wolfram Sang Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241004200314.5459-6-wsa+renesas@sang-engineering.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/it87_wdt.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/watchdog/it87_wdt.c b/drivers/watchdog/it87_wdt.c index 3e8c15138edd..676cd134e677 100644 --- a/drivers/watchdog/it87_wdt.c +++ b/drivers/watchdog/it87_wdt.c @@ -349,10 +349,8 @@ static int __init it87_wdt_init(void) watchdog_stop_on_reboot(&wdt_dev); rc = watchdog_register_device(&wdt_dev); - if (rc) { - pr_err("Cannot register watchdog device (err=%d)\n", rc); + if (rc) return rc; - } pr_info("Chip IT%04x revision %d initialized. timeout=%d sec (nowayout=%d testmode=%d)\n", chip_type, chip_rev, timeout, nowayout, testmode); -- cgit v1.2.3 From 8904da69098512968dbcf310668c521b0a360108 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 4 Oct 2024 22:03:09 +0200 Subject: watchdog: octeon-wdt: don't print out if registering watchdog fails The core will do this already. Signed-off-by: Wolfram Sang Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241004200314.5459-7-wsa+renesas@sang-engineering.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/octeon-wdt-main.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/watchdog/octeon-wdt-main.c b/drivers/watchdog/octeon-wdt-main.c index 52d49e4e35a0..0615bb816082 100644 --- a/drivers/watchdog/octeon-wdt-main.c +++ b/drivers/watchdog/octeon-wdt-main.c @@ -559,10 +559,8 @@ static int __init octeon_wdt_init(void) watchdog_set_nowayout(&octeon_wdt, nowayout); ret = watchdog_register_device(&octeon_wdt); - if (ret) { - pr_err("watchdog_register_device() failed: %d\n", ret); + if (ret) return ret; - } if (disable) { pr_notice("disabled\n"); -- cgit v1.2.3 From 844f8dff29e52a054fc82ca102060ee3a16620f0 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 4 Oct 2024 22:03:10 +0200 Subject: watchdog: rti_wdt: don't print out if registering watchdog fails The core will do this already. Signed-off-by: Wolfram Sang Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241004200314.5459-8-wsa+renesas@sang-engineering.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/rti_wdt.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/watchdog/rti_wdt.c b/drivers/watchdog/rti_wdt.c index 4895a69015a8..e319fa0787c2 100644 --- a/drivers/watchdog/rti_wdt.c +++ b/drivers/watchdog/rti_wdt.c @@ -336,10 +336,8 @@ static int rti_wdt_probe(struct platform_device *pdev) watchdog_init_timeout(wdd, heartbeat, dev); ret = watchdog_register_device(wdd); - if (ret) { - dev_err(dev, "cannot register watchdog device\n"); + if (ret) goto err_iomap; - } if (last_ping) watchdog_set_last_hw_keepalive(wdd, last_ping); -- cgit v1.2.3 From 74ccee5e6ceff65ea83b0da8e300c62b313e8ebc Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 4 Oct 2024 22:03:11 +0200 Subject: watchdog: rza_wdt: don't print out if registering watchdog fails The core will do this already. Signed-off-by: Wolfram Sang Reviewed-by: Wim Van Sebroeck Link: https://lore.kernel.org/r/20241004200314.5459-9-wsa+renesas@sang-engineering.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/rza_wdt.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/watchdog/rza_wdt.c b/drivers/watchdog/rza_wdt.c index cb4901b3f777..9334255a37e9 100644 --- a/drivers/watchdog/rza_wdt.c +++ b/drivers/watchdog/rza_wdt.c @@ -169,7 +169,6 @@ static int rza_wdt_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct rza_wdt *priv; unsigned long rate; - int ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -218,11 +217,7 @@ static int rza_wdt_probe(struct platform_device *pdev) watchdog_init_timeout(&priv->wdev, 0, dev); watchdog_set_drvdata(&priv->wdev, priv); - ret = devm_watchdog_register_device(dev, &priv->wdev); - if (ret) - dev_err(dev, "Cannot register watchdog device\n"); - - return ret; + return devm_watchdog_register_device(dev, &priv->wdev); } static const struct of_device_id rza_wdt_of_match[] = { -- cgit v1.2.3 From 39885f22e9f44f6c85d126789c7b0ee099904acd Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 4 Oct 2024 22:03:12 +0200 Subject: watchdog: sl28cpld_wdt: don't print out if registering watchdog fails The core will do this already. Signed-off-by: Wolfram Sang Reviewed-by: Michael Walle Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241004200314.5459-10-wsa+renesas@sang-engineering.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/sl28cpld_wdt.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/watchdog/sl28cpld_wdt.c b/drivers/watchdog/sl28cpld_wdt.c index 9ce456f09f73..8630c29818f2 100644 --- a/drivers/watchdog/sl28cpld_wdt.c +++ b/drivers/watchdog/sl28cpld_wdt.c @@ -198,10 +198,8 @@ static int sl28cpld_wdt_probe(struct platform_device *pdev) } ret = devm_watchdog_register_device(&pdev->dev, wdd); - if (ret < 0) { - dev_err(&pdev->dev, "failed to register watchdog device\n"); + if (ret < 0) return ret; - } dev_info(&pdev->dev, "initial timeout %d sec%s\n", wdd->timeout, nowayout ? ", nowayout" : ""); -- cgit v1.2.3 From bcbd7b2b031d14c2e239039c74897cb2e7d5425a Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Fri, 11 Oct 2024 12:43:52 +0200 Subject: dt-bindings: watchdog: airoha: document watchdog for Airoha EN7581 Document watchdog for Airoha EN7581. This SoC implement a simple watchdog that supports a max timeout of 28 seconds. The watchdog ticks on half the BUS clock and requires the BUS clock to be referenced. Signed-off-by: Christian Marangi Reviewed-by: Krzysztof Kozlowski Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241011104411.28659-1-ansuelsmth@gmail.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- .../bindings/watchdog/airoha,en7581-wdt.yaml | 47 ++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 Documentation/devicetree/bindings/watchdog/airoha,en7581-wdt.yaml diff --git a/Documentation/devicetree/bindings/watchdog/airoha,en7581-wdt.yaml b/Documentation/devicetree/bindings/watchdog/airoha,en7581-wdt.yaml new file mode 100644 index 000000000000..6bbab3cb28e5 --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/airoha,en7581-wdt.yaml @@ -0,0 +1,47 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/watchdog/airoha,en7581-wdt.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Airoha EN7581 Watchdog Timer + +maintainers: + - Christian Marangi + +allOf: + - $ref: watchdog.yaml# + +properties: + compatible: + const: airoha,en7581-wdt + + reg: + maxItems: 1 + + clocks: + description: BUS clock (timer ticks at half the BUS clock) + maxItems: 1 + + clock-names: + const: bus + +required: + - compatible + - reg + - clocks + - clock-names + +unevaluatedProperties: false + +examples: + - | + #include + + watchdog@1fbf0100 { + compatible = "airoha,en7581-wdt"; + reg = <0x1fbf0100 0x3c>; + + clocks = <&scuclk EN7523_CLK_BUS>; + clock-names = "bus"; + }; -- cgit v1.2.3 From 3cf67f3769b8227ca75ca7102180a2e270ee01aa Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Fri, 11 Oct 2024 12:43:53 +0200 Subject: watchdog: Add support for Airoha EN7851 watchdog Add support for Airoha EN7851 watchdog. This is a very basic watchdog with no pretimeout support, max timeout is 28 seconds and it ticks based on half the SoC BUS clock. Signed-off-by: Christian Marangi Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241011104411.28659-2-ansuelsmth@gmail.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/Kconfig | 8 ++ drivers/watchdog/Makefile | 1 + drivers/watchdog/airoha_wdt.c | 216 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 225 insertions(+) create mode 100644 drivers/watchdog/airoha_wdt.c diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 684b9fe84fff..6e0944cfb409 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -408,6 +408,14 @@ config SL28CPLD_WATCHDOG # ARM Architecture +config AIROHA_WATCHDOG + tristate "Airoha EN7581 Watchdog" + depends on ARCH_AIROHA || COMPILE_TEST + select WATCHDOG_CORE + help + Watchdog timer embedded into Airoha SoC. This will reboot your + system when the timeout is reached. + config ARM_SP805_WATCHDOG tristate "ARM SP805 Watchdog" depends on (ARM || ARM64 || COMPILE_TEST) && ARM_AMBA diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index ab6f2b41e38e..99eccefd6c33 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o obj-$(CONFIG_ARM_SP805_WATCHDOG) += sp805_wdt.o obj-$(CONFIG_ARM_SBSA_WATCHDOG) += sbsa_gwdt.o obj-$(CONFIG_ARMADA_37XX_WATCHDOG) += armada_37xx_wdt.o +obj-$(CONFIG_AIROHA_WATCHDOG) += airoha_wdt.o obj-$(CONFIG_ASM9260_WATCHDOG) += asm9260_wdt.o obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o diff --git a/drivers/watchdog/airoha_wdt.c b/drivers/watchdog/airoha_wdt.c new file mode 100644 index 000000000000..dc8ca11c14d8 --- /dev/null +++ b/drivers/watchdog/airoha_wdt.c @@ -0,0 +1,216 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Airoha Watchdog Driver + * + * Copyright (c) 2024, AIROHA All rights reserved. + * + * Mayur Kumar + * Christian Marangi + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Base address of timer and watchdog registers */ +#define TIMER_CTRL 0x0 +#define WDT_ENABLE BIT(25) +#define WDT_TIMER_INTERRUPT BIT(21) +/* Timer3 is used as Watchdog Timer */ +#define WDT_TIMER_ENABLE BIT(5) +#define WDT_TIMER_LOAD_VALUE 0x2c +#define WDT_TIMER_CUR_VALUE 0x30 +#define WDT_TIMER_VAL GENMASK(31, 0) +#define WDT_RELOAD 0x38 +#define WDT_RLD BIT(0) + +/* Airoha watchdog structure description */ +struct airoha_wdt_desc { + struct watchdog_device wdog_dev; + unsigned int wdt_freq; + void __iomem *base; +}; + +#define WDT_HEARTBEAT 24 +static int heartbeat = WDT_HEARTBEAT; +module_param(heartbeat, int, 0); +MODULE_PARM_DESC(heartbeat, "Watchdog heartbeats in seconds. (default=" + __MODULE_STRING(WDT_HEARTBEAT) ")"); + +static bool nowayout = WATCHDOG_NOWAYOUT; +module_param(nowayout, bool, 0); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + +static int airoha_wdt_start(struct watchdog_device *wdog_dev) +{ + struct airoha_wdt_desc *airoha_wdt = watchdog_get_drvdata(wdog_dev); + u32 val; + + val = readl(airoha_wdt->base + TIMER_CTRL); + val |= (WDT_TIMER_ENABLE | WDT_ENABLE | WDT_TIMER_INTERRUPT); + writel(val, airoha_wdt->base + TIMER_CTRL); + val = wdog_dev->timeout * airoha_wdt->wdt_freq; + writel(val, airoha_wdt->base + WDT_TIMER_LOAD_VALUE); + + return 0; +} + +static int airoha_wdt_stop(struct watchdog_device *wdog_dev) +{ + struct airoha_wdt_desc *airoha_wdt = watchdog_get_drvdata(wdog_dev); + u32 val; + + val = readl(airoha_wdt->base + TIMER_CTRL); + val &= (~WDT_ENABLE & ~WDT_TIMER_ENABLE); + writel(val, airoha_wdt->base + TIMER_CTRL); + + return 0; +} + +static int airoha_wdt_ping(struct watchdog_device *wdog_dev) +{ + struct airoha_wdt_desc *airoha_wdt = watchdog_get_drvdata(wdog_dev); + u32 val; + + val = readl(airoha_wdt->base + WDT_RELOAD); + val |= WDT_RLD; + writel(val, airoha_wdt->base + WDT_RELOAD); + + return 0; +} + +static int airoha_wdt_set_timeout(struct watchdog_device *wdog_dev, unsigned int timeout) +{ + wdog_dev->timeout = timeout; + + if (watchdog_active(wdog_dev)) { + airoha_wdt_stop(wdog_dev); + return airoha_wdt_start(wdog_dev); + } + + return 0; +} + +static unsigned int airoha_wdt_get_timeleft(struct watchdog_device *wdog_dev) +{ + struct airoha_wdt_desc *airoha_wdt = watchdog_get_drvdata(wdog_dev); + u32 val; + + val = readl(airoha_wdt->base + WDT_TIMER_CUR_VALUE); + return DIV_ROUND_UP(val, airoha_wdt->wdt_freq); +} + +static const struct watchdog_info airoha_wdt_info = { + .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, + .identity = "Airoha Watchdog", +}; + +static const struct watchdog_ops airoha_wdt_ops = { + .owner = THIS_MODULE, + .start = airoha_wdt_start, + .stop = airoha_wdt_stop, + .ping = airoha_wdt_ping, + .set_timeout = airoha_wdt_set_timeout, + .get_timeleft = airoha_wdt_get_timeleft, +}; + +static int airoha_wdt_probe(struct platform_device *pdev) +{ + struct airoha_wdt_desc *airoha_wdt; + struct watchdog_device *wdog_dev; + struct device *dev = &pdev->dev; + struct clk *bus_clk; + int ret; + + airoha_wdt = devm_kzalloc(dev, sizeof(*airoha_wdt), GFP_KERNEL); + if (!airoha_wdt) + return -ENOMEM; + + airoha_wdt->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(airoha_wdt->base)) + return PTR_ERR(airoha_wdt->base); + + bus_clk = devm_clk_get_enabled(dev, "bus"); + if (IS_ERR(bus_clk)) + return dev_err_probe(dev, PTR_ERR(bus_clk), + "failed to enable bus clock\n"); + + /* Watchdog ticks at half the bus rate */ + airoha_wdt->wdt_freq = clk_get_rate(bus_clk) / 2; + + /* Initialize struct watchdog device */ + wdog_dev = &airoha_wdt->wdog_dev; + wdog_dev->timeout = heartbeat; + wdog_dev->info = &airoha_wdt_info; + wdog_dev->ops = &airoha_wdt_ops; + /* Bus 300MHz, watchdog 150MHz, 28 seconds */ + wdog_dev->max_timeout = FIELD_MAX(WDT_TIMER_VAL) / airoha_wdt->wdt_freq; + wdog_dev->parent = dev; + + watchdog_set_drvdata(wdog_dev, airoha_wdt); + watchdog_set_nowayout(wdog_dev, nowayout); + watchdog_stop_on_unregister(wdog_dev); + + ret = devm_watchdog_register_device(dev, wdog_dev); + if (ret) + return ret; + + platform_set_drvdata(pdev, airoha_wdt); + return 0; +} + +static int airoha_wdt_suspend(struct device *dev) +{ + struct airoha_wdt_desc *airoha_wdt = dev_get_drvdata(dev); + + if (watchdog_active(&airoha_wdt->wdog_dev)) + airoha_wdt_stop(&airoha_wdt->wdog_dev); + + return 0; +} + +static int airoha_wdt_resume(struct device *dev) +{ + struct airoha_wdt_desc *airoha_wdt = dev_get_drvdata(dev); + + if (watchdog_active(&airoha_wdt->wdog_dev)) { + airoha_wdt_start(&airoha_wdt->wdog_dev); + airoha_wdt_ping(&airoha_wdt->wdog_dev); + } + return 0; +} + +static const struct of_device_id airoha_wdt_of_match[] = { + { .compatible = "airoha,en7581-wdt", }, + { }, +}; + +MODULE_DEVICE_TABLE(of, airoha_wdt_of_match); + +static DEFINE_SIMPLE_DEV_PM_OPS(airoha_wdt_pm_ops, airoha_wdt_suspend, airoha_wdt_resume); + +static struct platform_driver airoha_wdt_driver = { + .probe = airoha_wdt_probe, + .driver = { + .name = "airoha-wdt", + .pm = pm_sleep_ptr(&airoha_wdt_pm_ops), + .of_match_table = airoha_wdt_of_match, + }, +}; + +module_platform_driver(airoha_wdt_driver); + +MODULE_AUTHOR("Mayur Kumar "); +MODULE_AUTHOR("Christian Marangi "); +MODULE_DESCRIPTION("Airoha EN7581 Watchdog Driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 3a6a399cfbb72a96d61597c519a4076d4ab8669f Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 22 Oct 2024 11:47:31 +0200 Subject: watchdog: Delete the cpu5wdt driver This driver has a number of issues (accesses arbitrary I/O ports without identifying the hardware, doesn't document what hardware it supports, suspiciously inconsistent locking model, doesn't implement WDIOC_SETTIMEOUT, potential integer overflow...) The driver was added in 2003 and there's no evidence that it has any recent user, all changes seem to be tree-wide, subsystem-wide, or the result of static code analysis. So I believe we should simply drop this legacy piece of code. Signed-off-by: Jean Delvare Message-ID: <20241011170710.484a257a@endymion.delvare> Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241022114731.31f69c94@endymion.delvare Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- Documentation/watchdog/watchdog-parameters.rst | 10 - drivers/watchdog/Kconfig | 8 - drivers/watchdog/Makefile | 1 - drivers/watchdog/cpu5wdt.c | 284 ------------------------- 4 files changed, 303 deletions(-) delete mode 100644 drivers/watchdog/cpu5wdt.c diff --git a/Documentation/watchdog/watchdog-parameters.rst b/Documentation/watchdog/watchdog-parameters.rst index 29153eed6689..0a0119edfa82 100644 --- a/Documentation/watchdog/watchdog-parameters.rst +++ b/Documentation/watchdog/watchdog-parameters.rst @@ -120,16 +120,6 @@ coh901327_wdt: ------------------------------------------------- -cpu5wdt: - port: - base address of watchdog card, default is 0x91 - verbose: - be verbose, default is 0 (no) - ticks: - count down ticks, default is 10000 - -------------------------------------------------- - cpwd: wd0_timeout: Default watchdog0 timeout in 1/10secs diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 6e0944cfb409..b0010f5943f5 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -1541,14 +1541,6 @@ config SBC7240_WDT To compile this driver as a module, choose M here: the module will be called sbc7240_wdt. -config CPU5_WDT - tristate "SMA CPU5 Watchdog" - depends on (X86 || COMPILE_TEST) && HAS_IOPORT - help - TBD. - To compile this driver as a module, choose M here: the - module will be called cpu5wdt. - config SMSC_SCH311X_WDT tristate "SMSC SCH311X Watchdog Timer" depends on (X86 || COMPILE_TEST) && HAS_IOPORT diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 99eccefd6c33..9ee08e260d6f 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -138,7 +138,6 @@ obj-$(CONFIG_RDC321X_WDT) += rdc321x_wdt.o obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o obj-$(CONFIG_SBC8360_WDT) += sbc8360.o obj-$(CONFIG_SBC7240_WDT) += sbc7240_wdt.o -obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o obj-$(CONFIG_SMSC_SCH311X_WDT) += sch311x_wdt.o obj-$(CONFIG_SMSC37B787_WDT) += smsc37b787_wdt.o obj-$(CONFIG_TQMX86_WDT) += tqmx86_wdt.o diff --git a/drivers/watchdog/cpu5wdt.c b/drivers/watchdog/cpu5wdt.c deleted file mode 100644 index f94b84048612..000000000000 --- a/drivers/watchdog/cpu5wdt.c +++ /dev/null @@ -1,284 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * sma cpu5 watchdog driver - * - * Copyright (C) 2003 Heiko Ronsdorf - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* adjustable parameters */ - -static int verbose; -static int port = 0x91; -static int ticks = 10000; -static DEFINE_SPINLOCK(cpu5wdt_lock); - -#define PFX "cpu5wdt: " - -#define CPU5WDT_EXTENT 0x0A - -#define CPU5WDT_STATUS_REG 0x00 -#define CPU5WDT_TIME_A_REG 0x02 -#define CPU5WDT_TIME_B_REG 0x03 -#define CPU5WDT_MODE_REG 0x04 -#define CPU5WDT_TRIGGER_REG 0x07 -#define CPU5WDT_ENABLE_REG 0x08 -#define CPU5WDT_RESET_REG 0x09 - -#define CPU5WDT_INTERVAL (HZ/10+1) - -/* some device data */ - -static struct { - struct completion stop; - int running; - struct timer_list timer; - int queue; - int default_ticks; - unsigned long inuse; -} cpu5wdt_device; - -/* generic helper functions */ - -static void cpu5wdt_trigger(struct timer_list *unused) -{ - if (verbose > 2) - pr_debug("trigger at %i ticks\n", ticks); - - if (cpu5wdt_device.running) - ticks--; - - spin_lock(&cpu5wdt_lock); - /* keep watchdog alive */ - outb(1, port + CPU5WDT_TRIGGER_REG); - - /* requeue?? */ - if (cpu5wdt_device.queue && ticks) - mod_timer(&cpu5wdt_device.timer, jiffies + CPU5WDT_INTERVAL); - else { - /* ticks doesn't matter anyway */ - complete(&cpu5wdt_device.stop); - } - spin_unlock(&cpu5wdt_lock); - -} - -static void cpu5wdt_reset(void) -{ - ticks = cpu5wdt_device.default_ticks; - - if (verbose) - pr_debug("reset (%i ticks)\n", (int) ticks); - -} - -static void cpu5wdt_start(void) -{ - unsigned long flags; - - spin_lock_irqsave(&cpu5wdt_lock, flags); - if (!cpu5wdt_device.queue) { - cpu5wdt_device.queue = 1; - outb(0, port + CPU5WDT_TIME_A_REG); - outb(0, port + CPU5WDT_TIME_B_REG); - outb(1, port + CPU5WDT_MODE_REG); - outb(0, port + CPU5WDT_RESET_REG); - outb(0, port + CPU5WDT_ENABLE_REG); - mod_timer(&cpu5wdt_device.timer, jiffies + CPU5WDT_INTERVAL); - } - /* if process dies, counter is not decremented */ - cpu5wdt_device.running++; - spin_unlock_irqrestore(&cpu5wdt_lock, flags); -} - -static int cpu5wdt_stop(void) -{ - unsigned long flags; - - spin_lock_irqsave(&cpu5wdt_lock, flags); - if (cpu5wdt_device.running) - cpu5wdt_device.running = 0; - ticks = cpu5wdt_device.default_ticks; - spin_unlock_irqrestore(&cpu5wdt_lock, flags); - if (verbose) - pr_crit("stop not possible\n"); - return -EIO; -} - -/* filesystem operations */ - -static int cpu5wdt_open(struct inode *inode, struct file *file) -{ - if (test_and_set_bit(0, &cpu5wdt_device.inuse)) - return -EBUSY; - return stream_open(inode, file); -} - -static int cpu5wdt_release(struct inode *inode, struct file *file) -{ - clear_bit(0, &cpu5wdt_device.inuse); - return 0; -} - -static long cpu5wdt_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - void __user *argp = (void __user *)arg; - int __user *p = argp; - unsigned int value; - static const struct watchdog_info ident = { - .options = WDIOF_CARDRESET, - .identity = "CPU5 WDT", - }; - - switch (cmd) { - case WDIOC_GETSUPPORT: - if (copy_to_user(argp, &ident, sizeof(ident))) - return -EFAULT; - break; - case WDIOC_GETSTATUS: - value = inb(port + CPU5WDT_STATUS_REG); - value = (value >> 2) & 1; - return put_user(value, p); - case WDIOC_GETBOOTSTATUS: - return put_user(0, p); - case WDIOC_SETOPTIONS: - if (get_user(value, p)) - return -EFAULT; - if (value & WDIOS_ENABLECARD) - cpu5wdt_start(); - if (value & WDIOS_DISABLECARD) - cpu5wdt_stop(); - break; - case WDIOC_KEEPALIVE: - cpu5wdt_reset(); - break; - default: - return -ENOTTY; - } - return 0; -} - -static ssize_t cpu5wdt_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - if (!count) - return -EIO; - cpu5wdt_reset(); - return count; -} - -static const struct file_operations cpu5wdt_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = cpu5wdt_ioctl, - .compat_ioctl = compat_ptr_ioctl, - .open = cpu5wdt_open, - .write = cpu5wdt_write, - .release = cpu5wdt_release, -}; - -static struct miscdevice cpu5wdt_misc = { - .minor = WATCHDOG_MINOR, - .name = "watchdog", - .fops = &cpu5wdt_fops, -}; - -/* init/exit function */ - -static int cpu5wdt_init(void) -{ - unsigned int val; - int err; - - if (verbose) - pr_debug("port=0x%x, verbose=%i\n", port, verbose); - - init_completion(&cpu5wdt_device.stop); - cpu5wdt_device.queue = 0; - timer_setup(&cpu5wdt_device.timer, cpu5wdt_trigger, 0); - cpu5wdt_device.default_ticks = ticks; - - if (!request_region(port, CPU5WDT_EXTENT, PFX)) { - pr_err("request_region failed\n"); - err = -EBUSY; - goto no_port; - } - - /* watchdog reboot? */ - val = inb(port + CPU5WDT_STATUS_REG); - val = (val >> 2) & 1; - if (!val) - pr_info("sorry, was my fault\n"); - - err = misc_register(&cpu5wdt_misc); - if (err < 0) { - pr_err("misc_register failed\n"); - goto no_misc; - } - - - pr_info("init success\n"); - return 0; - -no_misc: - release_region(port, CPU5WDT_EXTENT); -no_port: - return err; -} - -static int cpu5wdt_init_module(void) -{ - return cpu5wdt_init(); -} - -static void cpu5wdt_exit(void) -{ - if (cpu5wdt_device.queue) { - cpu5wdt_device.queue = 0; - wait_for_completion(&cpu5wdt_device.stop); - timer_shutdown_sync(&cpu5wdt_device.timer); - } - - misc_deregister(&cpu5wdt_misc); - - release_region(port, CPU5WDT_EXTENT); - -} - -static void cpu5wdt_exit_module(void) -{ - cpu5wdt_exit(); -} - -/* module entry points */ - -module_init(cpu5wdt_init_module); -module_exit(cpu5wdt_exit_module); - -MODULE_AUTHOR("Heiko Ronsdorf "); -MODULE_DESCRIPTION("sma cpu5 watchdog driver"); -MODULE_LICENSE("GPL"); - -module_param_hw(port, int, ioport, 0); -MODULE_PARM_DESC(port, "base address of watchdog card, default is 0x91"); - -module_param(verbose, int, 0); -MODULE_PARM_DESC(verbose, "be verbose, default is 0 (no)"); - -module_param(ticks, int, 0); -MODULE_PARM_DESC(ticks, "count down ticks, default is 10000"); -- cgit v1.2.3 From 076354a4d4a73cb792a680a7f40f603c9b145a76 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 18 Oct 2024 10:58:20 -0300 Subject: watchdog: da9063: Do not use a global variable Using the 'use_sw_pm' variable as global is not recommended as it prevents multi instances of the driver to run. Make it a member of the da9063 structure instead. Signed-off-by: Fabio Estevam Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241018135821.274376-1-festevam@gmail.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/da9063_wdt.c | 9 +++++---- include/linux/mfd/da9063/core.h | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/watchdog/da9063_wdt.c b/drivers/watchdog/da9063_wdt.c index 684667469b10..69f884cf1a7b 100644 --- a/drivers/watchdog/da9063_wdt.c +++ b/drivers/watchdog/da9063_wdt.c @@ -27,7 +27,6 @@ * others: timeout = 2048 ms * 2^(TWDSCALE-1). */ static const unsigned int wdt_timeout[] = { 0, 2, 4, 8, 16, 32, 65, 131 }; -static bool use_sw_pm; #define DA9063_TWDSCALE_DISABLE 0 #define DA9063_TWDSCALE_MIN 1 @@ -230,7 +229,7 @@ static int da9063_wdt_probe(struct platform_device *pdev) if (!wdd) return -ENOMEM; - use_sw_pm = device_property_present(dev, "dlg,use-sw-pm"); + da9063->use_sw_pm = device_property_present(dev, "dlg,use-sw-pm"); wdd->info = &da9063_watchdog_info; wdd->ops = &da9063_watchdog_ops; @@ -267,8 +266,9 @@ static int da9063_wdt_probe(struct platform_device *pdev) static int __maybe_unused da9063_wdt_suspend(struct device *dev) { struct watchdog_device *wdd = dev_get_drvdata(dev); + struct da9063 *da9063 = watchdog_get_drvdata(wdd); - if (!use_sw_pm) + if (!da9063->use_sw_pm) return 0; if (watchdog_active(wdd)) @@ -280,8 +280,9 @@ static int __maybe_unused da9063_wdt_suspend(struct device *dev) static int __maybe_unused da9063_wdt_resume(struct device *dev) { struct watchdog_device *wdd = dev_get_drvdata(dev); + struct da9063 *da9063 = watchdog_get_drvdata(wdd); - if (!use_sw_pm) + if (!da9063->use_sw_pm) return 0; if (watchdog_active(wdd)) diff --git a/include/linux/mfd/da9063/core.h b/include/linux/mfd/da9063/core.h index 8db52324f416..eae82f421414 100644 --- a/include/linux/mfd/da9063/core.h +++ b/include/linux/mfd/da9063/core.h @@ -78,6 +78,7 @@ struct da9063 { enum da9063_type type; unsigned char variant_code; unsigned int flags; + bool use_sw_pm; /* Control interface */ struct regmap *regmap; -- cgit v1.2.3 From 90fc2c8e720b149af6b937f702aca273d00c670e Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 18 Oct 2024 10:58:21 -0300 Subject: watchdog: da9063: Remove __maybe_unused notations Use the DEFINE_SIMPLE_DEV_PM_OPS() and pm_sleep_ptr() macros to handle the .suspend/.resume callbacks. These macros allow the suspend and resume functions to be automatically dropped by the compiler when CONFIG_SUSPEND is disabled, without having to use __maybe_unused notation. Signed-off-by: Fabio Estevam Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241018135821.274376-2-festevam@gmail.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/da9063_wdt.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/watchdog/da9063_wdt.c b/drivers/watchdog/da9063_wdt.c index 69f884cf1a7b..92e1b78ff481 100644 --- a/drivers/watchdog/da9063_wdt.c +++ b/drivers/watchdog/da9063_wdt.c @@ -263,7 +263,7 @@ static int da9063_wdt_probe(struct platform_device *pdev) return devm_watchdog_register_device(dev, wdd); } -static int __maybe_unused da9063_wdt_suspend(struct device *dev) +static int da9063_wdt_suspend(struct device *dev) { struct watchdog_device *wdd = dev_get_drvdata(dev); struct da9063 *da9063 = watchdog_get_drvdata(wdd); @@ -277,7 +277,7 @@ static int __maybe_unused da9063_wdt_suspend(struct device *dev) return 0; } -static int __maybe_unused da9063_wdt_resume(struct device *dev) +static int da9063_wdt_resume(struct device *dev) { struct watchdog_device *wdd = dev_get_drvdata(dev); struct da9063 *da9063 = watchdog_get_drvdata(wdd); @@ -291,14 +291,14 @@ static int __maybe_unused da9063_wdt_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(da9063_wdt_pm_ops, - da9063_wdt_suspend, da9063_wdt_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(da9063_wdt_pm_ops, da9063_wdt_suspend, + da9063_wdt_resume); static struct platform_driver da9063_wdt_driver = { .probe = da9063_wdt_probe, .driver = { .name = DA9063_DRVNAME_WATCHDOG, - .pm = &da9063_wdt_pm_ops, + .pm = pm_sleep_ptr(&da9063_wdt_pm_ops), }, }; module_platform_driver(da9063_wdt_driver); -- cgit v1.2.3 From 43439076383a7611300334d1357c0f8883f40816 Mon Sep 17 00:00:00 2001 From: James Hilliard Date: Fri, 25 Oct 2024 00:34:40 -0600 Subject: watchdog: it87_wdt: add PWRGD enable quirk for Qotom QCML04 For the watchdog timer to work properly on the QCML04 board we need to set PWRGD enable in the Environment Controller Configuration Registers Special Configuration Register 1 when it is not already set, this may be the case when the watchdog is not enabled from within the BIOS. Signed-off-by: James Hilliard Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241025063441.3494837-1-james.hilliard1@gmail.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/it87_wdt.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/drivers/watchdog/it87_wdt.c b/drivers/watchdog/it87_wdt.c index 676cd134e677..a1e23dce8810 100644 --- a/drivers/watchdog/it87_wdt.c +++ b/drivers/watchdog/it87_wdt.c @@ -20,6 +20,8 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include +#include #include #include #include @@ -40,6 +42,7 @@ #define VAL 0x2f /* Logical device Numbers LDN */ +#define EC 0x04 #define GPIO 0x07 /* Configuration Registers and Functions */ @@ -73,6 +76,12 @@ #define IT8784_ID 0x8784 #define IT8786_ID 0x8786 +/* Environment Controller Configuration Registers LDN=0x04 */ +#define SCR1 0xfa + +/* Environment Controller Bits SCR1 */ +#define WDT_PWRGD 0x20 + /* GPIO Configuration Registers LDN=0x07 */ #define WDTCTRL 0x71 #define WDTCFG 0x72 @@ -240,6 +249,21 @@ static int wdt_set_timeout(struct watchdog_device *wdd, unsigned int t) return ret; } +enum { + IT87_WDT_OUTPUT_THROUGH_PWRGD = BIT(0), +}; + +static const struct dmi_system_id it87_quirks[] = { + { + /* Qotom Q30900P (IT8786) */ + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_NAME, "QCML04"), + }, + .driver_data = (void *)IT87_WDT_OUTPUT_THROUGH_PWRGD, + }, + {} +}; + static const struct watchdog_info ident = { .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, .firmware_version = 1, @@ -261,8 +285,10 @@ static struct watchdog_device wdt_dev = { static int __init it87_wdt_init(void) { + const struct dmi_system_id *dmi_id; u8 chip_rev; u8 ctrl; + int quirks = 0; int rc; rc = superio_enter(); @@ -273,6 +299,10 @@ static int __init it87_wdt_init(void) chip_rev = superio_inb(CHIPREV) & 0x0f; superio_exit(); + dmi_id = dmi_first_match(it87_quirks); + if (dmi_id) + quirks = (long)dmi_id->driver_data; + switch (chip_type) { case IT8702_ID: max_units = 255; @@ -333,6 +363,15 @@ static int __init it87_wdt_init(void) superio_outb(0x00, WDTCTRL); } + if (quirks & IT87_WDT_OUTPUT_THROUGH_PWRGD) { + superio_select(EC); + ctrl = superio_inb(SCR1); + if (!(ctrl & WDT_PWRGD)) { + ctrl |= WDT_PWRGD; + superio_outb(ctrl, SCR1); + } + } + superio_exit(); if (timeout < 1 || timeout > max_units * 60) { -- cgit v1.2.3 From 562b0b03193b567cd55334b25e5c8d624cd6a06f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Thu, 10 Oct 2024 22:36:22 +0200 Subject: watchdog: Switch back to struct platform_driver::remove() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After commit 0edb555a65d1 ("platform: Make platform_driver::remove() return void") .remove() is (again) the right callback to implement for platform drivers. Convert all platform drivers below drivers/watchdog/ to use .remove(), with the eventual goal to drop struct platform_driver::remove_new(). As .remove() and .remove_new() have the same prototypes, conversion is done by just changing the structure member name in the driver initializer. While touching these files, make indention of the struct initializer consistent in several files. Signed-off-by: Uwe Kleine-König Acked-by: Guenter Roeck Link: https://lore.kernel.org/r/20241010203622.839625-4-u.kleine-koenig@baylibre.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/acquirewdt.c | 2 +- drivers/watchdog/advantechwdt.c | 2 +- drivers/watchdog/at91rm9200_wdt.c | 2 +- drivers/watchdog/at91sam9_wdt.c | 2 +- drivers/watchdog/ath79_wdt.c | 2 +- drivers/watchdog/bcm2835_wdt.c | 2 +- drivers/watchdog/bcm_kona_wdt.c | 2 +- drivers/watchdog/cpwd.c | 2 +- drivers/watchdog/dw_wdt.c | 2 +- drivers/watchdog/gef_wdt.c | 2 +- drivers/watchdog/geodewdt.c | 2 +- drivers/watchdog/ib700wdt.c | 2 +- drivers/watchdog/ie6xx_wdt.c | 2 +- drivers/watchdog/lpc18xx_wdt.c | 2 +- drivers/watchdog/mtx-1_wdt.c | 2 +- drivers/watchdog/nic7018_wdt.c | 2 +- drivers/watchdog/nv_tco.c | 2 +- drivers/watchdog/omap_wdt.c | 2 +- drivers/watchdog/orion_wdt.c | 2 +- drivers/watchdog/rc32434_wdt.c | 2 +- drivers/watchdog/rdc321x_wdt.c | 2 +- drivers/watchdog/renesas_wdt.c | 2 +- drivers/watchdog/riowd.c | 2 +- drivers/watchdog/rti_wdt.c | 2 +- drivers/watchdog/sa1100_wdt.c | 4 ++-- drivers/watchdog/sch311x_wdt.c | 2 +- drivers/watchdog/shwdt.c | 2 +- drivers/watchdog/st_lpc_wdt.c | 2 +- drivers/watchdog/starfive-wdt.c | 2 +- drivers/watchdog/stmp3xxx_rtc_wdt.c | 2 +- drivers/watchdog/txx9wdt.c | 2 +- 31 files changed, 32 insertions(+), 32 deletions(-) diff --git a/drivers/watchdog/acquirewdt.c b/drivers/watchdog/acquirewdt.c index 08ca18e91124..052f65c48a70 100644 --- a/drivers/watchdog/acquirewdt.c +++ b/drivers/watchdog/acquirewdt.c @@ -285,7 +285,7 @@ static void acq_shutdown(struct platform_device *dev) } static struct platform_driver acquirewdt_driver = { - .remove_new = acq_remove, + .remove = acq_remove, .shutdown = acq_shutdown, .driver = { .name = DRV_NAME, diff --git a/drivers/watchdog/advantechwdt.c b/drivers/watchdog/advantechwdt.c index e41cd3ba4e0e..42d3f3771781 100644 --- a/drivers/watchdog/advantechwdt.c +++ b/drivers/watchdog/advantechwdt.c @@ -293,7 +293,7 @@ static void advwdt_shutdown(struct platform_device *dev) } static struct platform_driver advwdt_driver = { - .remove_new = advwdt_remove, + .remove = advwdt_remove, .shutdown = advwdt_shutdown, .driver = { .name = DRV_NAME, diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c index 17382512a609..1795aaf1ec45 100644 --- a/drivers/watchdog/at91rm9200_wdt.c +++ b/drivers/watchdog/at91rm9200_wdt.c @@ -295,7 +295,7 @@ MODULE_DEVICE_TABLE(of, at91_wdt_dt_ids); static struct platform_driver at91wdt_driver = { .probe = at91wdt_probe, - .remove_new = at91wdt_remove, + .remove = at91wdt_remove, .shutdown = at91wdt_shutdown, .suspend = pm_ptr(at91wdt_suspend), .resume = pm_ptr(at91wdt_resume), diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c index 2c6474cb858b..7be70b98d091 100644 --- a/drivers/watchdog/at91sam9_wdt.c +++ b/drivers/watchdog/at91sam9_wdt.c @@ -392,7 +392,7 @@ MODULE_DEVICE_TABLE(of, at91_wdt_dt_ids); static struct platform_driver at91wdt_driver = { .probe = at91wdt_probe, - .remove_new = at91wdt_remove, + .remove = at91wdt_remove, .driver = { .name = "at91_wdt", .of_match_table = of_match_ptr(at91_wdt_dt_ids), diff --git a/drivers/watchdog/ath79_wdt.c b/drivers/watchdog/ath79_wdt.c index d16b2c583fa4..7df703e9852a 100644 --- a/drivers/watchdog/ath79_wdt.c +++ b/drivers/watchdog/ath79_wdt.c @@ -305,7 +305,7 @@ MODULE_DEVICE_TABLE(of, ath79_wdt_match); static struct platform_driver ath79_wdt_driver = { .probe = ath79_wdt_probe, - .remove_new = ath79_wdt_remove, + .remove = ath79_wdt_remove, .shutdown = ath79_wdt_shutdown, .driver = { .name = DRIVER_NAME, diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c index bb001c5d7f17..9fcfee63905b 100644 --- a/drivers/watchdog/bcm2835_wdt.c +++ b/drivers/watchdog/bcm2835_wdt.c @@ -227,7 +227,7 @@ static void bcm2835_wdt_remove(struct platform_device *pdev) static struct platform_driver bcm2835_wdt_driver = { .probe = bcm2835_wdt_probe, - .remove_new = bcm2835_wdt_remove, + .remove = bcm2835_wdt_remove, .driver = { .name = "bcm2835-wdt", }, diff --git a/drivers/watchdog/bcm_kona_wdt.c b/drivers/watchdog/bcm_kona_wdt.c index 49e12d47b073..66bd0324fd68 100644 --- a/drivers/watchdog/bcm_kona_wdt.c +++ b/drivers/watchdog/bcm_kona_wdt.c @@ -328,7 +328,7 @@ static struct platform_driver bcm_kona_wdt_driver = { .of_match_table = bcm_kona_wdt_of_match, }, .probe = bcm_kona_wdt_probe, - .remove_new = bcm_kona_wdt_remove, + .remove = bcm_kona_wdt_remove, }; module_platform_driver(bcm_kona_wdt_driver); diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c index 8ee81f018dda..4fb92c9e046a 100644 --- a/drivers/watchdog/cpwd.c +++ b/drivers/watchdog/cpwd.c @@ -653,7 +653,7 @@ static struct platform_driver cpwd_driver = { .of_match_table = cpwd_match, }, .probe = cpwd_probe, - .remove_new = cpwd_remove, + .remove = cpwd_remove, }; module_platform_driver(cpwd_driver); diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c index 84dca3695f86..26efca9ae0e7 100644 --- a/drivers/watchdog/dw_wdt.c +++ b/drivers/watchdog/dw_wdt.c @@ -684,7 +684,7 @@ MODULE_DEVICE_TABLE(of, dw_wdt_of_match); static struct platform_driver dw_wdt_driver = { .probe = dw_wdt_drv_probe, - .remove_new = dw_wdt_drv_remove, + .remove = dw_wdt_drv_remove, .driver = { .name = "dw_wdt", .of_match_table = of_match_ptr(dw_wdt_of_match), diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c index d854fcfbfa5b..bf6f733dfb5f 100644 --- a/drivers/watchdog/gef_wdt.c +++ b/drivers/watchdog/gef_wdt.c @@ -305,7 +305,7 @@ static struct platform_driver gef_wdt_driver = { .of_match_table = gef_wdt_ids, }, .probe = gef_wdt_probe, - .remove_new = gef_wdt_remove, + .remove = gef_wdt_remove, }; static int __init gef_wdt_init(void) diff --git a/drivers/watchdog/geodewdt.c b/drivers/watchdog/geodewdt.c index 4ed6d139320b..5b80ade1c681 100644 --- a/drivers/watchdog/geodewdt.c +++ b/drivers/watchdog/geodewdt.c @@ -248,7 +248,7 @@ static void geodewdt_shutdown(struct platform_device *dev) } static struct platform_driver geodewdt_driver = { - .remove_new = geodewdt_remove, + .remove = geodewdt_remove, .shutdown = geodewdt_shutdown, .driver = { .name = DRV_NAME, diff --git a/drivers/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c index b041ad90a62c..5ce6101d236d 100644 --- a/drivers/watchdog/ib700wdt.c +++ b/drivers/watchdog/ib700wdt.c @@ -331,7 +331,7 @@ static void ibwdt_shutdown(struct platform_device *dev) } static struct platform_driver ibwdt_driver = { - .remove_new = ibwdt_remove, + .remove = ibwdt_remove, .shutdown = ibwdt_shutdown, .driver = { .name = DRV_NAME, diff --git a/drivers/watchdog/ie6xx_wdt.c b/drivers/watchdog/ie6xx_wdt.c index e5cbb409df25..5a7bb7e84653 100644 --- a/drivers/watchdog/ie6xx_wdt.c +++ b/drivers/watchdog/ie6xx_wdt.c @@ -280,7 +280,7 @@ static void ie6xx_wdt_remove(struct platform_device *pdev) static struct platform_driver ie6xx_wdt_driver = { .probe = ie6xx_wdt_probe, - .remove_new = ie6xx_wdt_remove, + .remove = ie6xx_wdt_remove, .driver = { .name = DRIVER_NAME, }, diff --git a/drivers/watchdog/lpc18xx_wdt.c b/drivers/watchdog/lpc18xx_wdt.c index 19535f4a2fd2..f19580e1b318 100644 --- a/drivers/watchdog/lpc18xx_wdt.c +++ b/drivers/watchdog/lpc18xx_wdt.c @@ -281,7 +281,7 @@ static struct platform_driver lpc18xx_wdt_driver = { .of_match_table = lpc18xx_wdt_match, }, .probe = lpc18xx_wdt_probe, - .remove_new = lpc18xx_wdt_remove, + .remove = lpc18xx_wdt_remove, }; module_platform_driver(lpc18xx_wdt_driver); diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c index 11f05024a181..f75426cfa425 100644 --- a/drivers/watchdog/mtx-1_wdt.c +++ b/drivers/watchdog/mtx-1_wdt.c @@ -233,7 +233,7 @@ static void mtx1_wdt_remove(struct platform_device *pdev) static struct platform_driver mtx1_wdt_driver = { .probe = mtx1_wdt_probe, - .remove_new = mtx1_wdt_remove, + .remove = mtx1_wdt_remove, .driver.name = "mtx1-wdt", }; diff --git a/drivers/watchdog/nic7018_wdt.c b/drivers/watchdog/nic7018_wdt.c index c3f0a4926667..44982b37ba6f 100644 --- a/drivers/watchdog/nic7018_wdt.c +++ b/drivers/watchdog/nic7018_wdt.c @@ -236,7 +236,7 @@ MODULE_DEVICE_TABLE(acpi, nic7018_device_ids); static struct platform_driver watchdog_driver = { .probe = nic7018_probe, - .remove_new = nic7018_remove, + .remove = nic7018_remove, .driver = { .name = KBUILD_MODNAME, .acpi_match_table = ACPI_PTR(nic7018_device_ids), diff --git a/drivers/watchdog/nv_tco.c b/drivers/watchdog/nv_tco.c index f8eb1f65a59e..f16cee5173d5 100644 --- a/drivers/watchdog/nv_tco.c +++ b/drivers/watchdog/nv_tco.c @@ -466,7 +466,7 @@ static void nv_tco_shutdown(struct platform_device *dev) static struct platform_driver nv_tco_driver = { .probe = nv_tco_init, - .remove_new = nv_tco_remove, + .remove = nv_tco_remove, .shutdown = nv_tco_shutdown, .driver = { .name = TCO_MODULE_NAME, diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c index b6e0236509bb..d523428a8d22 100644 --- a/drivers/watchdog/omap_wdt.c +++ b/drivers/watchdog/omap_wdt.c @@ -357,7 +357,7 @@ MODULE_DEVICE_TABLE(of, omap_wdt_of_match); static struct platform_driver omap_wdt_driver = { .probe = omap_wdt_probe, - .remove_new = omap_wdt_remove, + .remove = omap_wdt_remove, .shutdown = omap_wdt_shutdown, .suspend = pm_ptr(omap_wdt_suspend), .resume = pm_ptr(omap_wdt_resume), diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c index 1fe583e8a95b..0e145f762f6f 100644 --- a/drivers/watchdog/orion_wdt.c +++ b/drivers/watchdog/orion_wdt.c @@ -665,7 +665,7 @@ static void orion_wdt_shutdown(struct platform_device *pdev) static struct platform_driver orion_wdt_driver = { .probe = orion_wdt_probe, - .remove_new = orion_wdt_remove, + .remove = orion_wdt_remove, .shutdown = orion_wdt_shutdown, .driver = { .name = "orion_wdt", diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c index efadbb9d7ce7..0e5c5c96af58 100644 --- a/drivers/watchdog/rc32434_wdt.c +++ b/drivers/watchdog/rc32434_wdt.c @@ -309,7 +309,7 @@ static void rc32434_wdt_shutdown(struct platform_device *pdev) static struct platform_driver rc32434_wdt_driver = { .probe = rc32434_wdt_probe, - .remove_new = rc32434_wdt_remove, + .remove = rc32434_wdt_remove, .shutdown = rc32434_wdt_shutdown, .driver = { .name = "rc32434_wdt", diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c index 80490316a27f..8955177072fa 100644 --- a/drivers/watchdog/rdc321x_wdt.c +++ b/drivers/watchdog/rdc321x_wdt.c @@ -268,7 +268,7 @@ static void rdc321x_wdt_remove(struct platform_device *pdev) static struct platform_driver rdc321x_wdt_driver = { .probe = rdc321x_wdt_probe, - .remove_new = rdc321x_wdt_remove, + .remove = rdc321x_wdt_remove, .driver = { .name = "rdc321x-wdt", }, diff --git a/drivers/watchdog/renesas_wdt.c b/drivers/watchdog/renesas_wdt.c index 12c41d6e5cd6..c0b2a9c5250d 100644 --- a/drivers/watchdog/renesas_wdt.c +++ b/drivers/watchdog/renesas_wdt.c @@ -337,7 +337,7 @@ static struct platform_driver rwdt_driver = { .pm = &rwdt_pm_ops, }, .probe = rwdt_probe, - .remove_new = rwdt_remove, + .remove = rwdt_remove, }; module_platform_driver(rwdt_driver); diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c index f47d90d01c19..83806ccf06d1 100644 --- a/drivers/watchdog/riowd.c +++ b/drivers/watchdog/riowd.c @@ -238,7 +238,7 @@ static struct platform_driver riowd_driver = { .of_match_table = riowd_match, }, .probe = riowd_probe, - .remove_new = riowd_remove, + .remove = riowd_remove, }; module_platform_driver(riowd_driver); diff --git a/drivers/watchdog/rti_wdt.c b/drivers/watchdog/rti_wdt.c index e319fa0787c2..f410b6e39fb6 100644 --- a/drivers/watchdog/rti_wdt.c +++ b/drivers/watchdog/rti_wdt.c @@ -378,7 +378,7 @@ static struct platform_driver rti_wdt_driver = { .of_match_table = rti_wdt_of_match, }, .probe = rti_wdt_probe, - .remove_new = rti_wdt_remove, + .remove = rti_wdt_remove, }; module_platform_driver(rti_wdt_driver); diff --git a/drivers/watchdog/sa1100_wdt.c b/drivers/watchdog/sa1100_wdt.c index 6e91ee3fbfb5..729a8508b31d 100644 --- a/drivers/watchdog/sa1100_wdt.c +++ b/drivers/watchdog/sa1100_wdt.c @@ -236,8 +236,8 @@ static void sa1100dog_remove(struct platform_device *pdev) static struct platform_driver sa1100dog_driver = { .driver.name = "sa1100_wdt", - .probe = sa1100dog_probe, - .remove_new = sa1100dog_remove, + .probe = sa1100dog_probe, + .remove = sa1100dog_remove, }; module_platform_driver(sa1100dog_driver); diff --git a/drivers/watchdog/sch311x_wdt.c b/drivers/watchdog/sch311x_wdt.c index 76053158d259..9670a1ea57cb 100644 --- a/drivers/watchdog/sch311x_wdt.c +++ b/drivers/watchdog/sch311x_wdt.c @@ -445,7 +445,7 @@ static void sch311x_wdt_shutdown(struct platform_device *dev) static struct platform_driver sch311x_wdt_driver = { .probe = sch311x_wdt_probe, - .remove_new = sch311x_wdt_remove, + .remove = sch311x_wdt_remove, .shutdown = sch311x_wdt_shutdown, .driver = { .name = DRV_NAME, diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c index 10f1fba78ec2..7f0150c39421 100644 --- a/drivers/watchdog/shwdt.c +++ b/drivers/watchdog/shwdt.c @@ -297,7 +297,7 @@ static struct platform_driver sh_wdt_driver = { }, .probe = sh_wdt_probe, - .remove_new = sh_wdt_remove, + .remove = sh_wdt_remove, .shutdown = sh_wdt_shutdown, }; diff --git a/drivers/watchdog/st_lpc_wdt.c b/drivers/watchdog/st_lpc_wdt.c index 4c5b8d98a4f3..d206452072ae 100644 --- a/drivers/watchdog/st_lpc_wdt.c +++ b/drivers/watchdog/st_lpc_wdt.c @@ -286,7 +286,7 @@ static struct platform_driver st_wdog_driver = { .of_match_table = st_wdog_match, }, .probe = st_wdog_probe, - .remove_new = st_wdog_remove, + .remove = st_wdog_remove, }; module_platform_driver(st_wdog_driver); diff --git a/drivers/watchdog/starfive-wdt.c b/drivers/watchdog/starfive-wdt.c index a8b6cf767117..355918d62f63 100644 --- a/drivers/watchdog/starfive-wdt.c +++ b/drivers/watchdog/starfive-wdt.c @@ -597,7 +597,7 @@ MODULE_DEVICE_TABLE(of, starfive_wdt_match); static struct platform_driver starfive_wdt_driver = { .probe = starfive_wdt_probe, - .remove_new = starfive_wdt_remove, + .remove = starfive_wdt_remove, .shutdown = starfive_wdt_shutdown, .driver = { .name = "starfive-wdt", diff --git a/drivers/watchdog/stmp3xxx_rtc_wdt.c b/drivers/watchdog/stmp3xxx_rtc_wdt.c index 4b2caa9807ac..060447101f48 100644 --- a/drivers/watchdog/stmp3xxx_rtc_wdt.c +++ b/drivers/watchdog/stmp3xxx_rtc_wdt.c @@ -143,7 +143,7 @@ static struct platform_driver stmp3xxx_wdt_driver = { .pm = &stmp3xxx_wdt_pm_ops, }, .probe = stmp3xxx_wdt_probe, - .remove_new = stmp3xxx_wdt_remove, + .remove = stmp3xxx_wdt_remove, }; module_platform_driver(stmp3xxx_wdt_driver); diff --git a/drivers/watchdog/txx9wdt.c b/drivers/watchdog/txx9wdt.c index 8d5f67acbff2..305349844b4f 100644 --- a/drivers/watchdog/txx9wdt.c +++ b/drivers/watchdog/txx9wdt.c @@ -159,7 +159,7 @@ static void txx9wdt_shutdown(struct platform_device *dev) static struct platform_driver txx9wdt_driver = { .probe = txx9wdt_probe, - .remove_new = txx9wdt_remove, + .remove = txx9wdt_remove, .shutdown = txx9wdt_shutdown, .driver = { .name = "txx9wdt", -- cgit v1.2.3 From bad201b2ac4e238c6d4b6966a220240e3861640c Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Tue, 15 Oct 2024 19:47:32 +0300 Subject: watchdog: rzg2l_wdt: Power on the watchdog domain in the restart handler On RZ/G3S the watchdog can be part of a software-controlled PM domain. In this case, the watchdog device need to be powered on in struct watchdog_ops::restart API. This can be done though pm_runtime_resume_and_get() API if the watchdog PM domain and watchdog device are marked as IRQ safe. We mark the watchdog PM domain as IRQ safe with GENPD_FLAG_IRQ_SAFE when the watchdog PM domain is registered and the watchdog device though pm_runtime_irq_safe(). Before commit e4cf89596c1f ("watchdog: rzg2l_wdt: Fix 'BUG: Invalid wait context'") pm_runtime_get_sync() was used in watchdog restart handler (which is similar to pm_runtime_resume_and_get() except the later one handles the runtime resume errors). Commit e4cf89596c1f ("watchdog: rzg2l_wdt: Fix 'BUG: Invalid wait context'") dropped the pm_runtime_get_sync() and replaced it with clk_prepare_enable() to avoid invalid wait context due to genpd_lock() in genpd_runtime_resume() being called from atomic context. But clk_prepare_enable() doesn't fit for this either (as reported by Ulf Hansson) as clk_prepare() can also sleep (it just not throw invalid wait context warning as it is not written for this). Because the watchdog device is marked now as IRQ safe (though this patch) the irq_safe_dev_in_sleep_domain() call from genpd_runtime_resume() returns 1 for devices not registering an IRQ safe PM domain for watchdog (as the watchdog device is IRQ safe, PM domain is not and watchdog PM domain is always-on), this being the case for RZ/G3S with old device trees and the rest of the SoCs that use this driver, we can now drop also the clk_prepare_enable() calls in restart handler and rely on pm_runtime_resume_and_get(). Thus, drop clk_prepare_enable() and use pm_runtime_resume_and_get() in watchdog restart handler. Signed-off-by: Claudiu Beznea Reviewed-by: Ulf Hansson Reviewed-by: Geert Uytterhoeven Acked-by: Guenter Roeck Link: https://lore.kernel.org/r/20241015164732.4085249-5-claudiu.beznea.uj@bp.renesas.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/rzg2l_wdt.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/watchdog/rzg2l_wdt.c b/drivers/watchdog/rzg2l_wdt.c index 2a35f890a288..11bbe48160ec 100644 --- a/drivers/watchdog/rzg2l_wdt.c +++ b/drivers/watchdog/rzg2l_wdt.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -166,8 +167,22 @@ static int rzg2l_wdt_restart(struct watchdog_device *wdev, struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev); int ret; - clk_prepare_enable(priv->pclk); - clk_prepare_enable(priv->osc_clk); + /* + * In case of RZ/G3S the watchdog device may be part of an IRQ safe power + * domain that is currently powered off. In this case we need to power + * it on before accessing registers. Along with this the clocks will be + * enabled. We don't undo the pm_runtime_resume_and_get() as the device + * need to be on for the reboot to happen. + * + * For the rest of SoCs not registering a watchdog IRQ safe power + * domain it is safe to call pm_runtime_resume_and_get() as the + * irq_safe_dev_in_sleep_domain() call in genpd_runtime_resume() + * returns non zero value and the genpd_lock() is avoided, thus, there + * will be no invalid wait context reported by lockdep. + */ + ret = pm_runtime_resume_and_get(wdev->parent); + if (ret) + return ret; if (priv->devtype == WDT_RZG2L) { ret = reset_control_deassert(priv->rstc); @@ -275,6 +290,7 @@ static int rzg2l_wdt_probe(struct platform_device *pdev) priv->devtype = (uintptr_t)of_device_get_match_data(dev); + pm_runtime_irq_safe(&pdev->dev); pm_runtime_enable(&pdev->dev); priv->wdev.info = &rzg2l_wdt_ident; -- cgit v1.2.3 From ccfb765944bb66813398958983cb8141e2624a6b Mon Sep 17 00:00:00 2001 From: Peter Griffin Date: Tue, 29 Oct 2024 19:11:31 +0000 Subject: Revert "watchdog: s3c2410_wdt: use exynos_get_pmu_regmap_by_phandle() for PMU regs" This reverts commit 746f0770f916e6c48e422d6a34e67eae16707f0e. Now that we can register a SoC specific regmap with syscon using of_syscon_register_regmap() api we can switch back to using syscon_regmap_lookup_by_phandle() in the client drivers. Signed-off-by: Peter Griffin Reviewed-by: Sam Protsenko Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241029191131.2329414-1-peter.griffin@linaro.org Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/Kconfig | 1 + drivers/watchdog/s3c2410_wdt.c | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index b0010f5943f5..1f1eae0e175f 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -557,6 +557,7 @@ config S3C2410_WATCHDOG tristate "S3C6410/S5Pv210/Exynos Watchdog" depends on ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST select WATCHDOG_CORE + select MFD_SYSCON if ARCH_EXYNOS help Watchdog timer block in the Samsung S3C64xx, S5Pv210 and Exynos SoCs. This will reboot the system when the timer expires with diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index 686cf544d0ae..349d30462c8c 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c @@ -24,9 +24,9 @@ #include #include #include +#include #include #include -#include #define S3C2410_WTCON 0x00 #define S3C2410_WTDAT 0x04 @@ -699,11 +699,11 @@ static int s3c2410wdt_probe(struct platform_device *pdev) return ret; if (wdt->drv_data->quirks & QUIRKS_HAVE_PMUREG) { - wdt->pmureg = exynos_get_pmu_regmap_by_phandle(dev->of_node, - "samsung,syscon-phandle"); + wdt->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node, + "samsung,syscon-phandle"); if (IS_ERR(wdt->pmureg)) return dev_err_probe(dev, PTR_ERR(wdt->pmureg), - "PMU regmap lookup failed.\n"); + "syscon regmap lookup failed.\n"); } wdt_irq = platform_get_irq(pdev, 0); -- cgit v1.2.3 From a5ee1ca57c157fb7b289f9377c08848dae4eb821 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 30 Oct 2024 10:26:24 +0000 Subject: docs: ABI: Fix spelling mistake in pretimeout_avaialable_governors There is a spelling mistake, pretimeout_avaialable_governors should be pretimeout_available_governors. Fix it. Signed-off-by: Colin Ian King Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241030102624.3085369-1-colin.i.king@gmail.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- Documentation/ABI/testing/sysfs-class-watchdog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/sysfs-class-watchdog b/Documentation/ABI/testing/sysfs-class-watchdog index 94fb74615951..70eabccf0557 100644 --- a/Documentation/ABI/testing/sysfs-class-watchdog +++ b/Documentation/ABI/testing/sysfs-class-watchdog @@ -76,7 +76,7 @@ Description: timeout when the pretimeout interrupt is delivered. Pretimeout is an optional feature. -What: /sys/class/watchdog/watchdogn/pretimeout_avaialable_governors +What: /sys/class/watchdog/watchdogn/pretimeout_available_governors Date: February 2017 Contact: Wim Van Sebroeck Description: -- cgit v1.2.3 From 24a2f4d106a57d2ea8dd6ce2dc690396d9077ab2 Mon Sep 17 00:00:00 2001 From: Xin Liu Date: Tue, 29 Oct 2024 11:12:20 +0800 Subject: dt-bindings: watchdog: Document Qualcomm QCS8300 Add devicetree binding for watchdog present on Qualcomm QCS8300 SoC. Signed-off-by: Xin Liu Acked-by: Krzysztof Kozlowski Acked-by: Wim Van Sebroeck Link: https://lore.kernel.org/r/20241029031222.1653123-2-quic_liuxin@quicinc.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml b/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml index 32eaf43aadb3..34896a39fa91 100644 --- a/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml @@ -27,6 +27,7 @@ properties: - qcom,apss-wdt-qcm2290 - qcom,apss-wdt-qcs404 - qcom,apss-wdt-qcs615 + - qcom,apss-wdt-qcs8300 - qcom,apss-wdt-sa8255p - qcom,apss-wdt-sa8775p - qcom,apss-wdt-sc7180 -- cgit v1.2.3 From f6fe9b628f0ba530b02315fd23429c495b0388d6 Mon Sep 17 00:00:00 2001 From: Animesh Agarwal Date: Mon, 7 Oct 2024 17:24:33 -0400 Subject: dt-bindings: watchdog: fsl-imx-wdt: Add missing 'big-endian' property Add missing big-endian property in watchdog/fsl-imx-wdt.yaml schema. Only allow big-endian property for ls1012a and ls1043a. Fix dtbs_check errors. arch/arm64/boot/dts/freescale/fsl-ls1012a-frwy.dtb: watchdog@2ad0000: Unevaluated properties are not allowed ('big-endian' was unexpected) Cc: Daniel Baluta Signed-off-by: Animesh Agarwal Signed-off-by: Frank Li Reviewed-by: Krzysztof Kozlowski Reviewed-by: Wim Van Sebroeck Link: https://lore.kernel.org/r/20241007212434.895521-1-Frank.Li@nxp.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- .../devicetree/bindings/watchdog/fsl-imx-wdt.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.yaml b/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.yaml index 36b836d0620c..0da953cb7127 100644 --- a/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.yaml @@ -48,6 +48,8 @@ properties: clocks: maxItems: 1 + big-endian: true + fsl,ext-reset-output: $ref: /schemas/types.yaml#/definitions/flag description: | @@ -93,6 +95,18 @@ allOf: properties: fsl,suspend-in-wait: false + - if: + not: + properties: + compatible: + contains: + enum: + - fsl,ls1012a-wdt + - fsl,ls1043a-wdt + then: + properties: + big-endian: false + unevaluatedProperties: false examples: -- cgit v1.2.3 From a1495a21e0b8aad92132dfcf9c6fffc1bde9d5b2 Mon Sep 17 00:00:00 2001 From: Yassine Oudjana Date: Wed, 6 Nov 2024 10:47:51 +0000 Subject: watchdog: mediatek: Make sure system reset gets asserted in mtk_wdt_restart() Clear the IRQ enable bit of WDT_MODE before asserting software reset in order to make TOPRGU issue a system reset signal instead of an IRQ. Fixes: a44a45536f7b ("watchdog: Add driver for Mediatek watchdog") Signed-off-by: Yassine Oudjana Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241106104738.195968-2-y.oudjana@protonmail.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/mtk_wdt.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c index c35f85ce8d69..e2d7a57d6ea2 100644 --- a/drivers/watchdog/mtk_wdt.c +++ b/drivers/watchdog/mtk_wdt.c @@ -225,9 +225,15 @@ static int mtk_wdt_restart(struct watchdog_device *wdt_dev, { struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev); void __iomem *wdt_base; + u32 reg; wdt_base = mtk_wdt->wdt_base; + /* Enable reset in order to issue a system reset instead of an IRQ */ + reg = readl(wdt_base + WDT_MODE); + reg &= ~WDT_MODE_IRQ_EN; + writel(reg | WDT_MODE_KEY, wdt_base + WDT_MODE); + while (1) { writel(WDT_SWRST_KEY, wdt_base + WDT_SWRST); mdelay(5); -- cgit v1.2.3 From 15ddf704f56f8c95ff74dfd1157ed8646b322fa1 Mon Sep 17 00:00:00 2001 From: Yassine Oudjana Date: Wed, 6 Nov 2024 10:47:55 +0000 Subject: watchdog: mediatek: Add support for MT6735 TOPRGU/WDT Add support for the Top Reset Generation Unit/Watchdog Timer found on MT6735. Signed-off-by: Yassine Oudjana Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241106104738.195968-3-y.oudjana@protonmail.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/mtk_wdt.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c index e2d7a57d6ea2..91d110646e16 100644 --- a/drivers/watchdog/mtk_wdt.c +++ b/drivers/watchdog/mtk_wdt.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include @@ -87,6 +88,10 @@ static const struct mtk_wdt_data mt2712_data = { .toprgu_sw_rst_num = MT2712_TOPRGU_SW_RST_NUM, }; +static const struct mtk_wdt_data mt6735_data = { + .toprgu_sw_rst_num = MT6735_TOPRGU_RST_NUM, +}; + static const struct mtk_wdt_data mt6795_data = { .toprgu_sw_rst_num = MT6795_TOPRGU_SW_RST_NUM, }; @@ -489,6 +494,7 @@ static int mtk_wdt_resume(struct device *dev) static const struct of_device_id mtk_wdt_dt_ids[] = { { .compatible = "mediatek,mt2712-wdt", .data = &mt2712_data }, { .compatible = "mediatek,mt6589-wdt" }, + { .compatible = "mediatek,mt6735-wdt", .data = &mt6735_data }, { .compatible = "mediatek,mt6795-wdt", .data = &mt6795_data }, { .compatible = "mediatek,mt7986-wdt", .data = &mt7986_data }, { .compatible = "mediatek,mt7988-wdt", .data = &mt7988_data }, -- cgit v1.2.3 From c63e0ee729c8426a04675602965d4fcb795038b9 Mon Sep 17 00:00:00 2001 From: Byoungtae Cho Date: Mon, 21 Oct 2024 15:39:01 +0900 Subject: dt-bindings: watchdog: Document ExynosAutoV920 watchdog bindings Add "samsung-exynosautov920-wdt" compatible to the dt-schema document. ExynosAutoV920 is new SoC for automotive, similar to exynosautov9 but some CPU configurations are quite different. Signed-off-by: Byoungtae Cho Signed-off-by: Taewan Kim Acked-by: Rob Herring (Arm) Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20241021063903.793166-2-trunixs.kim@samsung.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml b/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml index 77a5ddd0426e..d175ae968336 100644 --- a/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml @@ -26,6 +26,7 @@ properties: - samsung,exynos7-wdt # for Exynos7 - samsung,exynos850-wdt # for Exynos850 - samsung,exynosautov9-wdt # for Exynosautov9 + - samsung,exynosautov920-wdt # for Exynosautov920 - items: - enum: - tesla,fsd-wdt @@ -77,6 +78,7 @@ allOf: - samsung,exynos7-wdt - samsung,exynos850-wdt - samsung,exynosautov9-wdt + - samsung,exynosautov920-wdt then: required: - samsung,syscon-phandle @@ -88,6 +90,7 @@ allOf: - google,gs101-wdt - samsung,exynos850-wdt - samsung,exynosautov9-wdt + - samsung,exynosautov920-wdt then: properties: clocks: -- cgit v1.2.3 From a5cb13980e00e9c4fbc382d68eda250ab6a14d7c Mon Sep 17 00:00:00 2001 From: Byoungtae Cho Date: Mon, 21 Oct 2024 15:39:02 +0900 Subject: watchdog: s3c2410_wdt: add support for exynosautov920 SoC Adds the compatibles and drvdata for the ExynosAuto V920 SoC. This SoC is almost similar to ExynosAutoV9, but some CPU configurations are quite different, so it should be added. Plus it also support DBGACK like as GS101 SoC. Signed-off-by: Byoungtae Cho Signed-off-by: Taewan Kim Reviewed-by: Krzysztof Kozlowski Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241021063903.793166-3-trunixs.kim@samsung.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/s3c2410_wdt.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index 349d30462c8c..30450e99e5e9 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c @@ -63,6 +63,10 @@ #define EXYNOS850_CLUSTER1_NONCPU_INT_EN 0x1644 #define EXYNOSAUTOV9_CLUSTER1_NONCPU_OUT 0x1520 #define EXYNOSAUTOV9_CLUSTER1_NONCPU_INT_EN 0x1544 +#define EXYNOSAUTOV920_CLUSTER0_NONCPU_OUT 0x1420 +#define EXYNOSAUTOV920_CLUSTER0_NONCPU_INT_EN 0x1444 +#define EXYNOSAUTOV920_CLUSTER1_NONCPU_OUT 0x1720 +#define EXYNOSAUTOV920_CLUSTER1_NONCPU_INT_EN 0x1744 #define EXYNOS850_CLUSTER0_WDTRESET_BIT 24 #define EXYNOS850_CLUSTER1_WDTRESET_BIT 23 @@ -303,6 +307,32 @@ static const struct s3c2410_wdt_variant drv_data_gs101_cl1 = { QUIRK_HAS_DBGACK_BIT, }; +static const struct s3c2410_wdt_variant drv_data_exynosautov920_cl0 = { + .mask_reset_reg = EXYNOSAUTOV920_CLUSTER0_NONCPU_INT_EN, + .mask_bit = 2, + .mask_reset_inv = true, + .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, + .rst_stat_bit = EXYNOSAUTOV9_CLUSTER0_WDTRESET_BIT, + .cnt_en_reg = EXYNOSAUTOV920_CLUSTER0_NONCPU_OUT, + .cnt_en_bit = 7, + .quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET | + QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN | + QUIRK_HAS_DBGACK_BIT, +}; + +static const struct s3c2410_wdt_variant drv_data_exynosautov920_cl1 = { + .mask_reset_reg = EXYNOSAUTOV920_CLUSTER1_NONCPU_INT_EN, + .mask_bit = 2, + .mask_reset_inv = true, + .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, + .rst_stat_bit = EXYNOSAUTOV9_CLUSTER1_WDTRESET_BIT, + .cnt_en_reg = EXYNOSAUTOV920_CLUSTER1_NONCPU_OUT, + .cnt_en_bit = 7, + .quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET | + QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN | + QUIRK_HAS_DBGACK_BIT, +}; + static const struct of_device_id s3c2410_wdt_match[] = { { .compatible = "google,gs101-wdt", .data = &drv_data_gs101_cl0 }, @@ -320,6 +350,8 @@ static const struct of_device_id s3c2410_wdt_match[] = { .data = &drv_data_exynos850_cl0 }, { .compatible = "samsung,exynosautov9-wdt", .data = &drv_data_exynosautov9_cl0 }, + { .compatible = "samsung,exynosautov920-wdt", + .data = &drv_data_exynosautov920_cl0 }, {}, }; MODULE_DEVICE_TABLE(of, s3c2410_wdt_match); @@ -643,7 +675,8 @@ s3c2410_get_wdt_drv_data(struct platform_device *pdev, struct s3c2410_wdt *wdt) /* Choose Exynos850/ExynosAutov9 driver data w.r.t. cluster index */ if (variant == &drv_data_exynos850_cl0 || variant == &drv_data_exynosautov9_cl0 || - variant == &drv_data_gs101_cl0) { + variant == &drv_data_gs101_cl0 || + variant == &drv_data_exynosautov920_cl0) { u32 index; int err; @@ -662,6 +695,8 @@ s3c2410_get_wdt_drv_data(struct platform_device *pdev, struct s3c2410_wdt *wdt) variant = &drv_data_exynosautov9_cl1; else if (variant == &drv_data_gs101_cl0) variant = &drv_data_gs101_cl1; + else if (variant == &drv_data_exynosautov920_cl0) + variant = &drv_data_exynosautov920_cl1; break; default: return dev_err_probe(dev, -EINVAL, "wrong cluster index: %u\n", index); -- cgit v1.2.3 From 4962ee045d8f06638714d801ab0fb72f89c16690 Mon Sep 17 00:00:00 2001 From: Alexander Sverdlin Date: Thu, 7 Nov 2024 21:38:28 +0100 Subject: watchdog: rti: of: honor timeout-sec property Currently "timeout-sec" Device Tree property is being silently ignored: even though watchdog_init_timeout() is being used, the driver always passes "heartbeat" == DEFAULT_HEARTBEAT == 60 as argument. Fix this by setting struct watchdog_device::timeout to DEFAULT_HEARTBEAT and passing real module parameter value to watchdog_init_timeout() (which may now be 0 if not specified). Cc: stable@vger.kernel.org Fixes: 2d63908bdbfb ("watchdog: Add K3 RTI watchdog support") Signed-off-by: Alexander Sverdlin Reviewed-by: Vignesh Raghavendra Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20241107203830.1068456-1-alexander.sverdlin@siemens.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/rti_wdt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/watchdog/rti_wdt.c b/drivers/watchdog/rti_wdt.c index f410b6e39fb6..58c9445c0f88 100644 --- a/drivers/watchdog/rti_wdt.c +++ b/drivers/watchdog/rti_wdt.c @@ -61,7 +61,7 @@ #define MAX_HW_ERROR 250 -static int heartbeat = DEFAULT_HEARTBEAT; +static int heartbeat; /* * struct to hold data for each WDT device @@ -252,6 +252,7 @@ static int rti_wdt_probe(struct platform_device *pdev) wdd->min_timeout = 1; wdd->max_hw_heartbeat_ms = (WDT_PRELOAD_MAX << WDT_PRELOAD_SHIFT) / wdt->freq * 1000; + wdd->timeout = DEFAULT_HEARTBEAT; wdd->parent = dev; watchdog_set_drvdata(wdd, wdt); -- cgit v1.2.3