From patchwork Fri Nov 1 12:11:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chin-Ting Kuo X-Patchwork-Id: 2005115 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ozlabs.org (client-ip=112.213.38.117; helo=lists.ozlabs.org; envelope-from=linux-aspeed+bounces-63-incoming=patchwork.ozlabs.org@lists.ozlabs.org; receiver=patchwork.ozlabs.org) Received: from lists.ozlabs.org (lists.ozlabs.org [112.213.38.117]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Xg09P3n54z1xwc for ; Fri, 1 Nov 2024 23:12:24 +1100 (AEDT) Received: from boromir.ozlabs.org (localhost [127.0.0.1]) by lists.ozlabs.org (Postfix) with ESMTP id 4Xg09N3yJDz2xKN; Fri, 1 Nov 2024 23:12:24 +1100 (AEDT) X-Original-To: linux-aspeed@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; arc=none smtp.remote-ip=211.20.114.72 ARC-Seal: i=1; a=rsa-sha256; d=lists.ozlabs.org; s=201707; t=1730463144; cv=none; b=XYxb9l07zyvM8yFBMjMdjNQix9/7I7wvqmyf4tTfzWfW+CwNlcS1Z7P4b4ig1mRZD5JiTyPJULP/QD/Vwf7J3InHQ0mkH6F55+iT6535HXzla2jOS2xNgy4Bd3lOcHMdmgixbruFZxBrBbLNxengkf17KT/zTEpoAacjUF5NC8r6fNM1LLOf7AqAimv/sjF6McTcBSltrHoiMdH2g2sGLbE4tr9rMBnXzDaDmLtMO8uVcdbEc23A3TciOAuKKam6eIL11stqMn+4UOkMLs+ywZuUkMVA0w+fSWouw2YZ4+Giiium684FLmzQkWqKbvon9xkBPfqpATQ/s8I4SdeHnA== ARC-Message-Signature: i=1; a=rsa-sha256; d=lists.ozlabs.org; s=201707; t=1730463144; c=relaxed/relaxed; bh=NEUCycH5XeaZGgO0PJ+/NV6U01qiFNf6+F6A+GENVSQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Goy6BKYiYEwscnC7m6O3o+C3jJrzbgpClupTVQ9fF62x+nNYlvwQcHjpQUBRBCXHePV+Ej1Xo6RIeJ3QmvrWeLJfeupxp7BcgGvV/2O7X+ot6mGUrdDKYgLuTV/OiuP3+WLwivMVJiDIKbu+ieXuAY8rfA0EVaXOoUYWpTtNC8NmA0mFYJQXSyQOAPcV9WqWDcz83njUJq4rz2e8bWm9xerXSsC0D2Inj0UUYKJ4m9nUZ0eN/u3qQDlIWQJGCEHNxpdDk8uX4TMWFXcomgPFrEnV/z1azZMekfazSwXxT4FBisoa54l8KNogGjjWQ+gcAAHSO4Msbb+UlxNtytaZOg== ARC-Authentication-Results: i=1; lists.ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=aspeedtech.com; spf=pass (client-ip=211.20.114.72; helo=twmbx01.aspeed.com; envelope-from=chin-ting_kuo@aspeedtech.com; receiver=lists.ozlabs.org) smtp.mailfrom=aspeedtech.com Authentication-Results: lists.ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=aspeedtech.com Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=aspeedtech.com (client-ip=211.20.114.72; helo=twmbx01.aspeed.com; envelope-from=chin-ting_kuo@aspeedtech.com; receiver=lists.ozlabs.org) Received: from TWMBX01.aspeed.com (mail.aspeedtech.com [211.20.114.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4Xg09M6Czxz2xH9 for ; Fri, 1 Nov 2024 23:12:23 +1100 (AEDT) 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; Fri, 1 Nov 2024 20:12:01 +0800 Received: from aspeedtech.com (192.168.10.152) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server id 15.2.1258.12 via Frontend Transport; Fri, 1 Nov 2024 20:12:01 +0800 From: Chin-Ting Kuo To: , , , , , , , , CC: , , , , , Subject: [PATCH v4 1/3] watchdog: aspeed: Update bootstatus handling Date: Fri, 1 Nov 2024 20:11:59 +0800 Message-ID: <20241101121201.2464091-2-chin-ting_kuo@aspeedtech.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241101121201.2464091-1-chin-ting_kuo@aspeedtech.com> References: <20241101121201.2464091-1-chin-ting_kuo@aspeedtech.com> X-Mailing-List: linux-aspeed@lists.ozlabs.org List-Id: List-Help: List-Owner: List-Post: List-Archive: , List-Subscribe: , , List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=0.0 required=5.0 tests=SPF_HELO_FAIL,SPF_PASS autolearn=disabled version=4.0.0 X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on lists.ozlabs.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 boot status mapping rule follows the latest design guide from the OpenBMC shown as below. https://github.com/openbmc/docs/blob/master/designs/bmc-reboot-cause-update.md#proposed-design - WDIOF_EXTERN1 => system is reset by Software - WDIOF_CARDRESET => 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: The reset triggered by different WDT controllers can be distinguished by different SCU bits. But, WDIOF_EXTERN1 or WDIOF_CARDRESET still cannot be identified due to HW limitation. - AST2600: Different from AST2500, additional HW bits are added for distinguishing WDIOF_EXTERN1 and WDIOF_CARDRESET. Besides, 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 | 83 ++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 2 deletions(-) diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c index b4773a6aaf8c..4ad6335ff25b 100644 --- a/drivers/watchdog/aspeed_wdt.c +++ b/drivers/watchdog/aspeed_wdt.c @@ -11,21 +11,31 @@ #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_sw_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 +49,39 @@ 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_sw_reset_mask = 0, + .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_sw_reset_mask = 0, + .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_sw_reset_mask = 0x8, + .wdt_reset_mask_shift = 16, + }, }; static const struct of_device_id aspeed_wdt_of_table[] = { @@ -213,6 +244,52 @@ static int aspeed_wdt_restart(struct watchdog_device *wdd, return 0; } +static int 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 = 0; + u32 idx = 0; + u32 status; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg_size = res->end - res->start; + + if (reg_size != 0) + idx = ((intptr_t)wdt->base & 0x00000fff) / reg_size; + + /* On ast2400, only a bit is used to represent WDT reset */ + if (of_device_is_compatible(pdev->dev.of_node, "aspeed,ast2400-wdt")) + idx = 0; + + scu_base = syscon_regmap_lookup_by_compatible(scu.compatible); + if (IS_ERR(scu_base)) + return PTR_ERR(scu_base); + + ret = regmap_read(scu_base, scu.reset_status_reg, &status); + if (ret) + return ret; + + reset_mask_width = hweight32(scu.wdt_reset_mask); + reset_mask_shift = scu.wdt_reset_mask_shift + + reset_mask_width * idx; + + if (status & (scu.wdt_sw_reset_mask << reset_mask_shift)) + wdt->wdd.bootstatus = WDIOF_EXTERN1; + else if (status & (scu.wdt_reset_mask << reset_mask_shift)) + wdt->wdd.bootstatus = WDIOF_CARDRESET; + else + wdt->wdd.bootstatus = 0; + + return 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 +535,12 @@ static int aspeed_wdt_probe(struct platform_device *pdev) writel(duration - 1, wdt->base + WDT_RESET_WIDTH); } + ret = aspeed_wdt_update_bootstatus(pdev, wdt); + if (ret) + return ret; + 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;