watchdog: npcm: Enable clock if provided
authorJonathan Neuschäfer <j.neuschaefer@gmx.net>
Fri, 10 Jun 2022 07:21:37 +0000 (09:21 +0200)
committerWim Van Sebroeck <wim@linux-watchdog.org>
Sun, 2 Oct 2022 10:55:41 +0000 (12:55 +0200)
On the Nuvoton WPCM450 SoC, with its upcoming clock driver, peripheral
clocks are individually gated and ungated. Therefore, the watchdog
driver must be able to ungate the watchdog clock.

Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Link: https://lore.kernel.org/r/20220610072141.347795-3-j.neuschaefer@gmx.net
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
drivers/watchdog/npcm_wdt.c

index 28a24caa2627c924416ef628cc548fa6383d2da2..a5dd1c2301374402ae4d28265798438ddd8cba34 100644 (file)
@@ -3,6 +3,7 @@
 // Copyright (c) 2018 IBM Corp.
 
 #include <linux/bitops.h>
+#include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
@@ -43,6 +44,7 @@
 struct npcm_wdt {
        struct watchdog_device  wdd;
        void __iomem            *reg;
+       struct clk              *clk;
 };
 
 static inline struct npcm_wdt *to_npcm_wdt(struct watchdog_device *wdd)
@@ -66,6 +68,9 @@ static int npcm_wdt_start(struct watchdog_device *wdd)
        struct npcm_wdt *wdt = to_npcm_wdt(wdd);
        u32 val;
 
+       if (wdt->clk)
+               clk_prepare_enable(wdt->clk);
+
        if (wdd->timeout < 2)
                val = 0x800;
        else if (wdd->timeout < 3)
@@ -100,6 +105,9 @@ static int npcm_wdt_stop(struct watchdog_device *wdd)
 
        writel(0, wdt->reg);
 
+       if (wdt->clk)
+               clk_disable_unprepare(wdt->clk);
+
        return 0;
 }
 
@@ -147,6 +155,10 @@ static int npcm_wdt_restart(struct watchdog_device *wdd,
 {
        struct npcm_wdt *wdt = to_npcm_wdt(wdd);
 
+       /* For reset, we start the WDT clock and leave it running. */
+       if (wdt->clk)
+               clk_prepare_enable(wdt->clk);
+
        writel(NPCM_WTR | NPCM_WTRE | NPCM_WTE, wdt->reg);
        udelay(1000);
 
@@ -191,6 +203,10 @@ static int npcm_wdt_probe(struct platform_device *pdev)
        if (IS_ERR(wdt->reg))
                return PTR_ERR(wdt->reg);
 
+       wdt->clk = devm_clk_get_optional(&pdev->dev, NULL);
+       if (IS_ERR(wdt->clk))
+               return PTR_ERR(wdt->clk);
+
        irq = platform_get_irq(pdev, 0);
        if (irq < 0)
                return irq;