mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Chin-Ting Kuo <chin-ting_kuo@aspeedtech.com>
To: <patrick@stwcx.xyz>, <joel@jms.id.au>,
	<andrew@codeconstruct.com.au>, <wim@linux-watchdog.org>,
	<linux@roeck-us.net>, <linux-arm-kernel@lists.infradead.org>,
	<linux-aspeed@lists.ozlabs.org>, <linux-kernel@vger.kernel.org>,
	<linux-watchdog@vger.kernel.org>
Cc: <Peter.Yin@quantatw.com>, <Patrick_NC_Lin@wiwynn.com>,
	<Bonnie_Lo@wiwynn.com>, <DELPHINE_CHIU@wiwynn.com>,
	<bmc-sw@aspeedtech.com>, <chnguyen@amperecomputing.com>
Subject: [PATCH v4 3/3] watchdog: aspeed: Update restart implementations
Date: Fri, 1 Nov 2024 20:12:01 +0800	[thread overview]
Message-ID: <20241101121201.2464091-4-chin-ting_kuo@aspeedtech.com> (raw)
In-Reply-To: <20241101121201.2464091-1-chin-ting_kuo@aspeedtech.com>

Restart callback function is created to distinguish the restart mechanisms
between AST2400/AST2500 and AST2600.

On AST2400 and AST2500 platforms, system can only be reset by enabling
WDT and waiting for WDT timeout. Since AST2600, SW can trigger the reset
event consciously and directly by just cinfiguring some HW registers
without waiting for WDT timeout. This mechanism is named "SW restart" and
is implemented by HW. The WDT counter is not enabled when SW restart
is adopted.

Signed-off-by: Chin-Ting Kuo <chin-ting_kuo@aspeedtech.com>
---
 drivers/watchdog/aspeed_wdt.c | 59 +++++++++++++++++++++++++++++------
 1 file changed, 49 insertions(+), 10 deletions(-)

diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c
index 63b5ff9e2751..28a16a0c442d 100644
--- a/drivers/watchdog/aspeed_wdt.c
+++ b/drivers/watchdog/aspeed_wdt.c
@@ -23,6 +23,14 @@ 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 {
+	struct watchdog_device	wdd;
+	void __iomem		*base;
+	u32			ctrl;
+	const struct aspeed_wdt_data *data;
+};
+
 struct aspeed_wdt_scu {
 	const char *compatible;
 	u32 reset_status_reg;
@@ -36,14 +44,11 @@ struct aspeed_wdt_data {
 	u32 irq_shift;
 	u32 irq_mask;
 	struct aspeed_wdt_scu scu;
+	int (*restart)(struct aspeed_wdt *wdt);
 };
 
-struct aspeed_wdt {
-	struct watchdog_device	wdd;
-	void __iomem		*base;
-	u32			ctrl;
-	const struct aspeed_wdt_data *data;
-};
+static int aspeed_ast2400_wdt_restart(struct aspeed_wdt *wdt);
+static int aspeed_ast2600_wdt_restart(struct aspeed_wdt *wdt);
 
 static const struct aspeed_wdt_data ast2400_data = {
 	.ext_pulse_width_mask = 0xff,
@@ -56,6 +61,7 @@ static const struct aspeed_wdt_data ast2400_data = {
 		.wdt_sw_reset_mask = 0,
 		.wdt_reset_mask_shift = 1,
 	},
+	.restart = aspeed_ast2400_wdt_restart,
 };
 
 static const struct aspeed_wdt_data ast2500_data = {
@@ -69,6 +75,7 @@ static const struct aspeed_wdt_data ast2500_data = {
 		.wdt_sw_reset_mask = 0,
 		.wdt_reset_mask_shift = 2,
 	},
+	.restart = aspeed_ast2400_wdt_restart,
 };
 
 static const struct aspeed_wdt_data ast2600_data = {
@@ -82,6 +89,7 @@ static const struct aspeed_wdt_data ast2600_data = {
 		.wdt_sw_reset_mask = 0x8,
 		.wdt_reset_mask_shift = 16,
 	},
+	.restart = aspeed_ast2600_wdt_restart,
 };
 
 static const struct of_device_id aspeed_wdt_of_table[] = {
@@ -112,6 +120,11 @@ MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table);
 #define   WDT_CLEAR_TIMEOUT_AND_BOOT_CODE_SELECTION	BIT(0)
 #define WDT_RESET_MASK1		0x1c
 #define WDT_RESET_MASK2		0x20
+#define WDT_SW_RESET_CTRL	0x24
+#define   WDT_SW_RESET_COUNT_CLEAR	0xDEADDEAD
+#define   WDT_SW_RESET_ENABLE	0xAEEDF123
+#define WDT_SW_RESET_MASK1	0x28
+#define WDT_SW_RESET_MASK2	0x2c
 
 /*
  * WDT_RESET_WIDTH controls the characteristics of the external pulse (if
@@ -231,11 +244,8 @@ static int aspeed_wdt_set_pretimeout(struct watchdog_device *wdd,
 	return 0;
 }
 
-static int aspeed_wdt_restart(struct watchdog_device *wdd,
-			      unsigned long action, void *data)
+static int aspeed_ast2400_wdt_restart(struct aspeed_wdt *wdt)
 {
-	struct aspeed_wdt *wdt = to_aspeed_wdt(wdd);
-
 	wdt->ctrl &= ~WDT_CTRL_BOOT_SECONDARY;
 	aspeed_wdt_enable(wdt, 128 * WDT_RATE_1MHZ / 1000);
 
@@ -244,6 +254,35 @@ static int aspeed_wdt_restart(struct watchdog_device *wdd,
 	return 0;
 }
 
+static int aspeed_ast2600_wdt_restart(struct aspeed_wdt *wdt)
+{
+	u32 reg;
+	u32 ctrl = WDT_CTRL_RESET_MODE_SOC |
+		   WDT_CTRL_RESET_SYSTEM;
+
+	reg = readl(wdt->base + WDT_RESET_MASK1);
+	writel(reg, wdt->base + WDT_SW_RESET_MASK1);
+	reg = readl(wdt->base + WDT_RESET_MASK2);
+	writel(reg, wdt->base + WDT_SW_RESET_MASK2);
+
+	writel(ctrl, wdt->base + WDT_CTRL);
+	writel(WDT_SW_RESET_COUNT_CLEAR, wdt->base + WDT_SW_RESET_CTRL);
+	writel(WDT_SW_RESET_ENABLE, wdt->base + WDT_SW_RESET_CTRL);
+
+	/* system must be reset immediately */
+	mdelay(1000);
+
+	return 0;
+}
+
+static int aspeed_wdt_restart(struct watchdog_device *wdd,
+			      unsigned long action, void *data)
+{
+	struct aspeed_wdt *wdt = to_aspeed_wdt(wdd);
+
+	return wdt->data->restart(wdt);
+}
+
 static int aspeed_wdt_update_bootstatus(struct platform_device *pdev,
 					struct aspeed_wdt *wdt)
 {
-- 
2.34.1


      parent reply	other threads:[~2024-11-01 12:12 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-11-01 12:11 [PATCH v4 0/3] Update ASPEED WDT bootstatus Chin-Ting Kuo
2024-11-01 12:11 ` [PATCH v4 1/3] watchdog: aspeed: Update bootstatus handling Chin-Ting Kuo
2024-11-01 18:21   ` Patrick Williams
2024-11-04  0:01     ` Andrew Jeffery
2024-11-07  5:35       ` Chin-Ting Kuo
2024-11-07 23:49         ` Andrew Jeffery
2024-11-08  5:42           ` Chin-Ting Kuo
2024-11-08 14:07             ` Guenter Roeck
2024-11-18 12:46               ` Chin-Ting Kuo
2024-11-18 20:50                 ` Guenter Roeck
2024-11-18 23:00                   ` Andrew Jeffery
2024-11-19  1:27                     ` Guenter Roeck
2024-11-20  4:54                       ` Andrew Jeffery
2024-12-17  2:15                         ` Chin-Ting Kuo
2024-11-07  5:34     ` Chin-Ting Kuo
2024-11-01 22:16   ` Guenter Roeck
2024-11-07  5:35     ` Chin-Ting Kuo
2024-11-01 12:12 ` [PATCH v4 2/3] watchdog: aspeed: Change aspeed_wdt_config struct name to aspeed_wdt_data Chin-Ting Kuo
2024-11-01 22:19   ` Guenter Roeck
2024-11-01 12:12 ` Chin-Ting Kuo [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20241101121201.2464091-4-chin-ting_kuo@aspeedtech.com \
    --to=chin-ting_kuo@aspeedtech.com \
    --cc=Bonnie_Lo@wiwynn.com \
    --cc=DELPHINE_CHIU@wiwynn.com \
    --cc=Patrick_NC_Lin@wiwynn.com \
    --cc=Peter.Yin@quantatw.com \
    --cc=andrew@codeconstruct.com.au \
    --cc=bmc-sw@aspeedtech.com \
    --cc=chnguyen@amperecomputing.com \
    --cc=joel@jms.id.au \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-aspeed@lists.ozlabs.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-watchdog@vger.kernel.org \
    --cc=linux@roeck-us.net \
    --cc=patrick@stwcx.xyz \
    --cc=wim@linux-watchdog.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®