mbox series

[v3,0/7] Nuvoton WPCM450 clock and reset driver

Message ID 20220508194333.2170161-1-j.neuschaefer@gmx.net
Headers show
Series Nuvoton WPCM450 clock and reset driver | expand

Message

J. Neuschäfer May 8, 2022, 7:43 p.m. UTC
This series adds support for the clock and reset controller in the Nuvoton
WPCM450 SoC. This means that the clock rates for peripherals will be calculated
automatically based on the clock tree as it was preconfigured by the bootloader.
The 24 MHz dummy clock, that is currently in the devicetree, is no longer needed.
Somewhat unfortunately, this also means that there is a breaking change once
the devicetree starts relying on the clock driver, but I find it acceptable in
this case, because WPCM450 is still at a somewhat early stage.


Upstreaming plan (although other suggestions are welcome):

Once reviewed,

- The ARM/dts changes should go through Joel Stanley's bmc tree
- The clocksource/timer changes should probably go via Daniel Lezcano and TIP
- The watchdog patch should go via the watchdog tree
- The clock controller bindings and driver should go through the clk tree
- It might make sense to delay the final ARM/dts patch ("ARM: dts: wpcm450:
  Switch clocks to clock controller") until next cycle to make sure it is
  merged after the clock driver.


v3:
- Changed "refclk" string to "ref"
- Fixed some dead code in the driver
- Added clk_prepare_enable call to the watchdog restart handler
- Added a few review tags

v2:
- https://lore.kernel.org/lkml/20220429172030.398011-1-j.neuschaefer@gmx.net/
- various small improvements

v1:
- https://lore.kernel.org/lkml/20220422183012.444674-1-j.neuschaefer@gmx.net/


Jonathan Neuschäfer (7):
  dt-bindings: timer: nuvoton,npcm7xx-timer: Allow specifying all clocks
  clocksource: timer-npcm7xx: Enable timer 1 clock before use
  watchdog: npcm: Enable clock if provided
  dt-bindings: clock: Add Nuvoton WPCM450 clock/reset controller
  ARM: dts: wpcm450: Add clock controller node
  clk: wpcm450: Add Nuvoton WPCM450 clock/reset controller driver
  ARM: dts: wpcm450: Switch clocks to clock controller

 .../bindings/clock/nuvoton,wpcm450-clk.yaml   |  66 ++++
 .../bindings/timer/nuvoton,npcm7xx-timer.yaml |   8 +-
 arch/arm/boot/dts/nuvoton-wpcm450.dtsi        |  29 +-
 drivers/clk/Makefile                          |   1 +
 drivers/clk/clk-wpcm450.c                     | 363 ++++++++++++++++++
 drivers/clocksource/timer-npcm7xx.c           |  10 +
 drivers/reset/Kconfig                         |   2 +-
 drivers/watchdog/npcm_wdt.c                   |  18 +
 .../dt-bindings/clock/nuvoton,wpcm450-clk.h   |  67 ++++
 9 files changed, 555 insertions(+), 9 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/nuvoton,wpcm450-clk.yaml
 create mode 100644 drivers/clk/clk-wpcm450.c
 create mode 100644 include/dt-bindings/clock/nuvoton,wpcm450-clk.h

--
2.35.1

Comments

Daniel Lezcano May 9, 2022, 11:37 a.m. UTC | #1
On 08/05/2022 21:43, Jonathan Neuschäfer wrote:
> In the WPCM450 SoC, the clocks for each timer can be gated individually.
> To prevent the timer 1 clock from being gated, enable it explicitly.
> 
> Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
> ---


Applied, thanks
Guenter Roeck May 10, 2022, 2:31 a.m. UTC | #2
On 5/8/22 12:43, 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>
> ---
> 
> v3:
> - 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 | 18 ++++++++++++++++++
>   1 file changed, 18 insertions(+)
> 
> diff --git a/drivers/watchdog/npcm_wdt.c b/drivers/watchdog/npcm_wdt.c
> index 28a24caa2627c..a1240a906ef2a 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,9 +155,15 @@ static int npcm_wdt_restart(struct watchdog_device *wdd,
>   {
>   	struct npcm_wdt *wdt = to_npcm_wdt(wdd);
> 
> +	if (wdt->clk)
> +		clk_prepare_enable(wdt->clk);
> +
>   	writel(NPCM_WTR | NPCM_WTRE | NPCM_WTE, wdt->reg);
>   	udelay(1000);
> 
> +	if (wdt->clk)
> +		clk_disable_unprepare(wdt->clk);
> +

I am trying to understand why you stop the clock here.
If the watchdog didn't reset the system by now, for whatever reason,
you explicitly don't want it to reset the system ? If so, please add
a comment describing the reason for stopping the clock here.

Thanks,
Guenter

>   	return 0;
>   }
> 
> @@ -191,6 +205,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;
> --
> 2.35.1
>
J. Neuschäfer May 17, 2022, 2:02 p.m. UTC | #3
On Mon, May 09, 2022 at 07:31:31PM -0700, Guenter Roeck wrote:
> On 5/8/22 12:43, 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>
> > ---
> > 
> > v3:
> > - 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/
> > ---
[...]
> > @@ -147,9 +155,15 @@ static int npcm_wdt_restart(struct watchdog_device *wdd,
> >   {
> >   	struct npcm_wdt *wdt = to_npcm_wdt(wdd);
> > 
> > +	if (wdt->clk)
> > +		clk_prepare_enable(wdt->clk);
> > +
> >   	writel(NPCM_WTR | NPCM_WTRE | NPCM_WTE, wdt->reg);
> >   	udelay(1000);
> > 
> > +	if (wdt->clk)
> > +		clk_disable_unprepare(wdt->clk);
> > +
> 
> I am trying to understand why you stop the clock here.
> If the watchdog didn't reset the system by now, for whatever reason,
> you explicitly don't want it to reset the system ? If so, please add
> a comment describing the reason for stopping the clock here.

It was for symmetry with starting the clock, and in the hope that
udelay(1000) will be enough to reach timer expiration. (In practice it
does appear to work, although 1ms is not much.)

Upon reconsideration, I agree it's better to leave the clock running for
reset (with a comment pointing out the asymmetry).


Best regards,
Jonathan
J. Neuschäfer Nov. 1, 2022, 11:46 a.m. UTC | #4
On Mon, May 09, 2022 at 01:37:40PM +0200, Daniel Lezcano wrote:
> On 08/05/2022 21:43, Jonathan Neuschäfer wrote:
> > In the WPCM450 SoC, the clocks for each timer can be gated individually.
> > To prevent the timer 1 clock from being gated, enable it explicitly.
> > 
> > Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
> > ---
> 
> 
> Applied, thanks

Hi, I didn't see this patch in linux-next. May I know where you applied it?

If it got lost somehow, I can also resend it later.


Best regards,
Jonathan