Message ID | 20220610072141.347795-3-j.neuschaefer@gmx.net |
---|---|
State | New |
Headers | show |
Series | Nuvoton WPCM450 clock and reset driver | expand |
On Fri, Jun 10, 2022 at 09:21:37AM +0200, Jonathan Neuschäfer wrote: > 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> > --- > > v4: > - Don't disable clock in npcm_wdt_restart function > > v3: > - https://lore.kernel.org/lkml/20220508194333.2170161-4-j.neuschaefer@gmx.net/ > - Add enable/disable calls to npcm_wdt_restart handler > - Not applied due to the above change: Acked-by: Guenter Roeck <linux@roeck-us.net> > > v2: > - https://lore.kernel.org/lkml/20220429172030.398011-4-j.neuschaefer@gmx.net/ > - Add clk_disable_unprepare call, suggested by Guenter Roeck > > v1: > - https://lore.kernel.org/lkml/20220422183012.444674-4-j.neuschaefer@gmx.net/ > --- > drivers/watchdog/npcm_wdt.c | 16 ++++++++++++++++ > 1 file changed, 16 insertions(+) > > -- > 2.35.1 > > diff --git a/drivers/watchdog/npcm_wdt.c b/drivers/watchdog/npcm_wdt.c > index 28a24caa2627c..a5dd1c2301374 100644 > --- a/drivers/watchdog/npcm_wdt.c > +++ b/drivers/watchdog/npcm_wdt.c > @@ -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;
diff --git a/drivers/watchdog/npcm_wdt.c b/drivers/watchdog/npcm_wdt.c index 28a24caa2627c..a5dd1c2301374 100644 --- a/drivers/watchdog/npcm_wdt.c +++ b/drivers/watchdog/npcm_wdt.c @@ -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;
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> --- v4: - Don't disable clock in npcm_wdt_restart function v3: - https://lore.kernel.org/lkml/20220508194333.2170161-4-j.neuschaefer@gmx.net/ - Add enable/disable calls to npcm_wdt_restart handler - Not applied due to the above change: Acked-by: Guenter Roeck <linux@roeck-us.net> v2: - https://lore.kernel.org/lkml/20220429172030.398011-4-j.neuschaefer@gmx.net/ - Add clk_disable_unprepare call, suggested by Guenter Roeck v1: - https://lore.kernel.org/lkml/20220422183012.444674-4-j.neuschaefer@gmx.net/ --- drivers/watchdog/npcm_wdt.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) -- 2.35.1