Message ID | 20250113112349.801875-6-prabhakar.mahadev-lad.rj@bp.renesas.com |
---|---|
State | New |
Headers | show |
Series | [v3,1/6] dt-bindings: clock: rzv2h-cpg: Add syscon compatible for CPG block | expand |
Hi Prabhakar, Thanks for the patch. > -----Original Message----- > From: Prabhakar <prabhakar.csengg@gmail.com> > Sent: 13 January 2025 11:24 > Subject: [PATCH v3 5/6] watchdog: rzv2h_wdt: Add support to retrieve the bootstatus information > > From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> > > On the RZ/V2H(P) SoC we can determine if the current boot is due to `Power-on-Reset` or due to the > `Watchdog`. The information used to determine this is present on the CPG block. > > The CPG_ERROR_RSTm(m = 2 - 8) registers are set in response to an error interrupt causing an reset. > CPG_ERROR_RST2[ERROR_RST0/1/2] is set if there was an underflow/overflow on WDT1 causing an error > interrupt. > > To fetch this information from CPG block `syscon` is used and bootstatus field in the watchdog device > is updated based on the CPG_ERROR_RST2[ERROR_RST0/1/2] bit. Upon consumig > CPG_ERROR_RST2[ERROR_RST0/1/2] bit we clear it. As syscon-cpg is available, can we get rid of Linux assuming TF_A/U-boot for configuring Error Reset Select Registers(0x10420B04)for the watchdog to reset the system? After this, each watchdog device node will have, selection{offset,bit} status{ offset,bit} renesas,syscon-cpg-error-rst-sel = <&cpg 0xb04 1>; renesas,syscon-cpg-error-rst = <&cpg 0xb40 1>; Or renesas,syscon-cpg-error-rst = < &cpg 0xb04 1 0xb40 1>; Cheers, Biju
Hi Biju, On Tue, Jan 14, 2025 at 9:55 AM Biju Das <biju.das.jz@bp.renesas.com> wrote: > > Hi Prabhakar, > > Thanks for the patch. > > > -----Original Message----- > > From: Prabhakar <prabhakar.csengg@gmail.com> > > Sent: 13 January 2025 11:24 > > Subject: [PATCH v3 5/6] watchdog: rzv2h_wdt: Add support to retrieve the bootstatus information > > > > From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> > > > > On the RZ/V2H(P) SoC we can determine if the current boot is due to `Power-on-Reset` or due to the > > `Watchdog`. The information used to determine this is present on the CPG block. > > > > The CPG_ERROR_RSTm(m = 2 - 8) registers are set in response to an error interrupt causing an reset. > > CPG_ERROR_RST2[ERROR_RST0/1/2] is set if there was an underflow/overflow on WDT1 causing an error > > interrupt. > > > > To fetch this information from CPG block `syscon` is used and bootstatus field in the watchdog device > > is updated based on the CPG_ERROR_RST2[ERROR_RST0/1/2] bit. Upon consumig > > CPG_ERROR_RST2[ERROR_RST0/1/2] bit we clear it. > > As syscon-cpg is available, can we get rid of Linux assuming TF_A/U-boot for configuring Error Reset > Select Registers(0x10420B04)for the watchdog to reset the system? > Agreed. > After this, each watchdog device node will have, selection{offset,bit} status{ offset,bit} > renesas,syscon-cpg-error-rst-sel = <&cpg 0xb04 1>; > renesas,syscon-cpg-error-rst = <&cpg 0xb40 1>; > > Or > > renesas,syscon-cpg-error-rst = < &cpg 0xb04 1 0xb40 1>; > As we already have 0xb40 we can do 0xb40 - 0x3c to get `0xb04` in the WDT driver and the same bit numbers can be re-used for CPG_ERRORRST_SEL2, so by this way we can avoid adding another property in DT. And I think this works for G3E too? Cheers, Prabhakar
diff --git a/drivers/watchdog/rzv2h_wdt.c b/drivers/watchdog/rzv2h_wdt.c index 8defd0241213..ab7e35928190 100644 --- a/drivers/watchdog/rzv2h_wdt.c +++ b/drivers/watchdog/rzv2h_wdt.c @@ -4,14 +4,17 @@ * * Copyright (C) 2024 Renesas Electronics Corporation. */ +#include <linux/bitfield.h> #include <linux/clk.h> #include <linux/delay.h> #include <linux/io.h> #include <linux/kernel.h> +#include <linux/mfd/syscon.h> #include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> +#include <linux/regmap.h> #include <linux/reset.h> #include <linux/units.h> #include <linux/watchdog.h> @@ -40,6 +43,9 @@ #define WDT_DEFAULT_TIMEOUT 60U +#define CPG_ERROR_RST2(x) BIT(x) +#define CPG_ERROR_RST2_WEN(x) BIT((x) + 16) + static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" @@ -206,9 +212,37 @@ static const struct watchdog_ops rzv2h_wdt_ops = { static int rzv2h_wdt_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; struct rzv2h_wdt_priv *priv; + unsigned int bootstatus = 0; + struct regmap *syscon; int ret; + /* Do not error out to maintain old DT compatibility */ + syscon = syscon_regmap_lookup_by_phandle(np, "renesas,syscon-cpg-error-rst"); + if (!IS_ERR(syscon)) { + struct of_phandle_args args; + u32 reg; + + ret = of_parse_phandle_with_fixed_args(np, "renesas,syscon-cpg-error-rst", + 2, 0, &args); + if (ret) + return ret; + + ret = regmap_read(syscon, args.args[0], ®); + if (ret) + return ret; + + if (reg & CPG_ERROR_RST2(args.args[1])) { + ret = regmap_write(syscon, args.args[0], + CPG_ERROR_RST2(args.args[1]) | + CPG_ERROR_RST2_WEN(args.args[1])); + if (ret) + return ret; + } + bootstatus = reg & CPG_ERROR_RST2(args.args[1]) ? WDIOF_CARDRESET : 0; + } + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -243,6 +277,7 @@ static int rzv2h_wdt_probe(struct platform_device *pdev) priv->wdev.info = &rzv2h_wdt_ident; priv->wdev.ops = &rzv2h_wdt_ops; priv->wdev.parent = dev; + priv->wdev.bootstatus = bootstatus; watchdog_set_drvdata(&priv->wdev, priv); watchdog_set_nowayout(&priv->wdev, nowayout); watchdog_stop_on_unregister(&priv->wdev);