From: Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx> Add support for selecting the count clock source used by the watchdog timer. The RZ/V2H(P) SoC uses the LOCO as the count source, whereas on RZ/T2H and RZ/N2H SoCs, the count source is the peripheral clock (PCLKL). Introduce a `count_source` field in the SoC-specific data structure and refactor the clock rate selection logic accordingly. This prepares the driver for supporting the RZ/T2H and RZ/N2H SoCs, which differ in their watchdog clocking architecture from RZ/V2H(P). Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx> Reviewed-by: Wolfram Sang <wsa+renesas@xxxxxxxxxxxxxxxxxxxx> --- v2->v3: - Added reviewed-by from Wolfram. v1->v2: - No changes. --- drivers/watchdog/rzv2h_wdt.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/watchdog/rzv2h_wdt.c b/drivers/watchdog/rzv2h_wdt.c index 3c02960b65cf..e71d1e108f69 100644 --- a/drivers/watchdog/rzv2h_wdt.c +++ b/drivers/watchdog/rzv2h_wdt.c @@ -42,12 +42,18 @@ module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); +enum rzv2h_wdt_count_source { + COUNT_SOURCE_LOCO, + COUNT_SOURCE_PCLK, +}; + struct rzv2h_of_data { u8 cks_min; u8 cks_max; u16 cks_div; u8 tops; u16 timeout_cycles; + enum rzv2h_wdt_count_source count_source; }; struct rzv2h_wdt_priv { @@ -214,6 +220,7 @@ static int rzv2h_wdt_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct rzv2h_wdt_priv *priv; + struct clk *count_clk; int ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); @@ -239,8 +246,19 @@ static int rzv2h_wdt_probe(struct platform_device *pdev) return dev_err_probe(dev, PTR_ERR(priv->rstc), "failed to get cpg reset"); + switch (priv->of_data->count_source) { + case COUNT_SOURCE_LOCO: + count_clk = priv->oscclk; + break; + case COUNT_SOURCE_PCLK: + count_clk = priv->pclk; + break; + default: + return dev_err_probe(dev, -EINVAL, "Invalid count source\n"); + } + priv->wdev.max_hw_heartbeat_ms = (MILLI * priv->of_data->timeout_cycles * - priv->of_data->cks_div) / clk_get_rate(priv->oscclk); + priv->of_data->cks_div) / clk_get_rate(count_clk); dev_dbg(dev, "max hw timeout of %dms\n", priv->wdev.max_hw_heartbeat_ms); ret = devm_pm_runtime_enable(dev); @@ -269,6 +287,7 @@ static const struct rzv2h_of_data rzv2h_wdt_of_data = { .cks_div = 256, .tops = WDTCR_TOPS_16384, .timeout_cycles = 16384, + .count_source = COUNT_SOURCE_LOCO, }; static const struct of_device_id rzv2h_wdt_ids[] = { -- 2.50.1