[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20250312202132.GA1072616@ax162>
Date: Wed, 12 Mar 2025 21:21:32 +0100
From: Nathan Chancellor <nathan@...nel.org>
To: Chin-Ting Kuo <chin-ting_kuo@...eedtech.com>
Cc: patrick@...cx.xyz, andrew@...econstruct.com.au, linux@...ck-us.net,
wim@...ux-watchdog.org, joel@....id.au,
linux-watchdog@...r.kernel.org,
linux-arm-kernel@...ts.infradead.org, linux-aspeed@...ts.ozlabs.org,
linux-kernel@...r.kernel.org, Peter.Yin@...ntatw.com,
Patrick_NC_Lin@...ynn.com, BMC-SW@...eedtech.com,
chnguyen@...erecomputing.com, aaron_lee@...eedtech.com
Subject: Re: [PATCH v7 1/1] watchdog: aspeed: Update bootstatus handling
On Mon, Jan 13, 2025 at 05:37:37PM +0800, Chin-Ting Kuo wrote:
> The boot status in the watchdog device struct is updated during
> controller probe stage. Application layer can get the boot status
> through the command, cat /sys/class/watchdog/watchdogX/bootstatus.
> The bootstatus can be,
> WDIOF_CARDRESET => System is reset due to WDT timeout occurs.
> Others => Other reset events, e.g., power on reset.
>
> On ASPEED platforms, boot status is recorded in the SCU registers.
> - AST2400: Only a bit is used to represent system reset triggered by
> any WDT controller.
> - AST2500/AST2600: System reset triggered by different WDT controllers
> can be distinguished by different SCU bits.
>
> Besides, on AST2400 and AST2500, since alternating boot event is
> also triggered by using WDT timeout mechanism, it is classified
> as WDIOF_CARDRESET.
>
> Signed-off-by: Chin-Ting Kuo <chin-ting_kuo@...eedtech.com>
> ---
> drivers/watchdog/aspeed_wdt.c | 81 ++++++++++++++++++++++++++++++++++-
> 1 file changed, 79 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c
...
> +static void aspeed_wdt_update_bootstatus(struct platform_device *pdev,
> + struct aspeed_wdt *wdt)
> +{
> + const struct resource *res;
> + struct aspeed_wdt_scu scu = wdt->cfg->scu;
> + struct regmap *scu_base;
> + u32 reset_mask_width;
> + u32 reset_mask_shift;
> + u32 idx = 0;
> + u32 status;
> + int ret;
> +
> + if (!of_device_is_compatible(pdev->dev.of_node, "aspeed,ast2400-wdt")) {
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + idx = ((intptr_t)wdt->base & 0x00000fff) / resource_size(res);
This division breaks the build when CONFIG_ARM_LPAE is enabled, which
selects CONFIG_PHYS_ADDR_T_64BIT, turning resource_size_t into a 64-bit
type.
$ make -skj"$(nproc)" ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- mrproper multi_v7_lpae_defconfig all
arm-linux-gnueabi-ld: drivers/watchdog/aspeed_wdt.o: in function `aspeed_wdt_update_bootstatus':
drivers/watchdog/aspeed_wdt.c:257:(.text+0x80c): undefined reference to `__aeabi_uldivmod'
> + }
> +
> + scu_base = syscon_regmap_lookup_by_compatible(scu.compatible);
> + if (IS_ERR(scu_base)) {
> + wdt->wdd.bootstatus = WDIOS_UNKNOWN;
> + return;
> + }
> +
> + ret = regmap_read(scu_base, scu.reset_status_reg, &status);
> + if (ret) {
> + wdt->wdd.bootstatus = WDIOS_UNKNOWN;
> + return;
> + }
> +
> + reset_mask_width = hweight32(scu.wdt_reset_mask);
> + reset_mask_shift = scu.wdt_reset_mask_shift +
> + reset_mask_width * idx;
> +
> + if (status & (scu.wdt_reset_mask << reset_mask_shift))
> + wdt->wdd.bootstatus = WDIOF_CARDRESET;
> +
> + /* clear wdt reset event flag */
> + if (of_device_is_compatible(pdev->dev.of_node, "aspeed,ast2400-wdt") ||
> + of_device_is_compatible(pdev->dev.of_node, "aspeed,ast2500-wdt")) {
> + ret = regmap_read(scu_base, scu.reset_status_reg, &status);
> + if (!ret) {
> + status &= ~(scu.wdt_reset_mask << reset_mask_shift);
> + regmap_write(scu_base, scu.reset_status_reg, status);
> + }
> + } else {
> + regmap_write(scu_base, scu.reset_status_reg,
> + scu.wdt_reset_mask << reset_mask_shift);
> + }
> +}
> +
Cheers,
Nathan
Powered by blists - more mailing lists