From patchwork Wed Jan 1 07:01:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chin-Ting Kuo X-Patchwork-Id: 13924153 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 74768E7718B for ; Wed, 1 Jan 2025 07:04:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type: Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date :Subject:CC:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=t5KXlYIdplDlznAf/h1480kdbKFnWzMBkD6KXaxNsQo=; b=RQriOiyz2zH91XBvY071jFew8M +vYvYR5vmibDND1UNiQUvXYN6WCi2/nWVoweur0SCAFsXcbKFqfA3MPeTLzUe9ttCLBNNvU+XDMQE 9EQACGzcHFBi8hCEvfQ8PQasmKCthQIJex5WnbYplIX6B1LzmInimhtWieLlDMY+Xym5OWVRiJgsD Ap+0z/wn/IdBv2IjUn2YnLA2QMtaYxay080qqkYTxAgZVQ1ODp45UQ8kO+lK9teh/uZrhGks+KluH YsEULi0fwNAKBHEHV7E0MNHiIyTfsmcFUBUlqgUxd5/yT43CH0h4B0TxWWvVh643Zd7lVIlVuE3gm Wve7pxGg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tSsll-00000008IVa-2G0n; Wed, 01 Jan 2025 07:03:53 +0000 Received: from mail.aspeedtech.com ([211.20.114.72] helo=TWMBX01.aspeed.com) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tSsjT-00000008IJO-0bSE for linux-arm-kernel@lists.infradead.org; Wed, 01 Jan 2025 07:01:32 +0000 Received: from TWMBX01.aspeed.com (192.168.0.62) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.12; Wed, 1 Jan 2025 15:01:16 +0800 Received: from aspeedtech.com (192.168.10.13) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server id 15.2.1258.12 via Frontend Transport; Wed, 1 Jan 2025 15:01:16 +0800 From: Chin-Ting Kuo To: , , , , , , , , CC: , , , , Subject: [PATCH v5 1/1] watchdog: aspeed: Update bootstatus handling Date: Wed, 1 Jan 2025 15:01:16 +0800 Message-ID: <20250101070116.2287171-2-chin-ting_kuo@aspeedtech.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250101070116.2287171-1-chin-ting_kuo@aspeedtech.com> References: <20250101070116.2287171-1-chin-ting_kuo@aspeedtech.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20241231_230131_185944_715DAD39 X-CRM114-Status: GOOD ( 18.27 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org 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 => the system is reset by WDT SoC reset. Others => other reset events, e.g., power on reset. On ASPEED platform, the boot status is recorded in the SCU registers. - AST2400: Only a bit represents for any WDT reset. - AST2500/AST2600: The reset triggered by different WDT controllers can be distinguished by different SCU bits. Besides, on AST2400 and AST2500, since alternating boot event is triggered by WDT SoC reset, it is classified as WDIOF_CARDRESET. Signed-off-by: Chin-Ting Kuo --- drivers/watchdog/aspeed_wdt.c | 85 ++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 2 deletions(-) diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c index b4773a6aaf8c..1fae70b2fa6b 100644 --- a/drivers/watchdog/aspeed_wdt.c +++ b/drivers/watchdog/aspeed_wdt.c @@ -11,21 +11,30 @@ #include #include #include +#include #include #include #include #include +#include #include static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); +struct aspeed_wdt_scu { + const char *compatible; + u32 reset_status_reg; + u32 wdt_reset_mask; + u32 wdt_reset_mask_shift; +}; struct aspeed_wdt_config { u32 ext_pulse_width_mask; u32 irq_shift; u32 irq_mask; + struct aspeed_wdt_scu scu; }; struct aspeed_wdt { @@ -39,18 +48,36 @@ static const struct aspeed_wdt_config ast2400_config = { .ext_pulse_width_mask = 0xff, .irq_shift = 0, .irq_mask = 0, + .scu = { + .compatible = "aspeed,ast2400-scu", + .reset_status_reg = 0x3c, + .wdt_reset_mask = 0x1, + .wdt_reset_mask_shift = 1, + }, }; static const struct aspeed_wdt_config ast2500_config = { .ext_pulse_width_mask = 0xfffff, .irq_shift = 12, .irq_mask = GENMASK(31, 12), + .scu = { + .compatible = "aspeed,ast2500-scu", + .reset_status_reg = 0x3c, + .wdt_reset_mask = 0x1, + .wdt_reset_mask_shift = 2, + }, }; static const struct aspeed_wdt_config ast2600_config = { .ext_pulse_width_mask = 0xfffff, .irq_shift = 0, .irq_mask = GENMASK(31, 10), + .scu = { + .compatible = "aspeed,ast2600-scu", + .reset_status_reg = 0x74, + .wdt_reset_mask = 0xf, + .wdt_reset_mask_shift = 16, + }, }; static const struct of_device_id aspeed_wdt_of_table[] = { @@ -213,6 +240,60 @@ static int aspeed_wdt_restart(struct watchdog_device *wdd, return 0; } +static void aspeed_wdt_update_bootstatus(struct platform_device *pdev, + struct aspeed_wdt *wdt) +{ + struct resource *res; + struct aspeed_wdt_scu scu = wdt->cfg->scu; + struct regmap *scu_base; + u32 reset_mask_width; + u32 reset_mask_shift; + u32 reg_size; + 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); + if (res) { + reg_size = res->end - res->start; + if (reg_size) + idx = ((intptr_t)wdt->base & 0x00000fff) / reg_size; + } + } + + wdt->wdd.bootstatus = WDIOS_UNKNOWN; + scu_base = syscon_regmap_lookup_by_compatible(scu.compatible); + if (IS_ERR(scu_base)) + return; + + ret = regmap_read(scu_base, scu.reset_status_reg, &status); + if (ret) + 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; + else + wdt->wdd.bootstatus = 0; + + /* 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); + } +} + /* access_cs0 shows if cs0 is accessible, hence the reverted bit */ static ssize_t access_cs0_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -458,10 +539,10 @@ static int aspeed_wdt_probe(struct platform_device *pdev) writel(duration - 1, wdt->base + WDT_RESET_WIDTH); } + aspeed_wdt_update_bootstatus(pdev, wdt); + status = readl(wdt->base + WDT_TIMEOUT_STATUS); if (status & WDT_TIMEOUT_STATUS_BOOT_SECONDARY) { - wdt->wdd.bootstatus = WDIOF_CARDRESET; - if (of_device_is_compatible(np, "aspeed,ast2400-wdt") || of_device_is_compatible(np, "aspeed,ast2500-wdt")) wdt->wdd.groups = bswitch_groups;