diff mbox series

[3/5] watchdog: eiois200_wdt: Implement basic watchdog functionalities

Message ID 61d7009003a08d47a3e5efc2906eb2e76d02cdb3.1696495372.git.advantech.susiteam@gmail.com (mailing list archive)
State New
Headers show
Series watchdog: eiois200_wdt: Add EIO-IS200 Watchdog Driver | expand

Commit Message

Wenkai Oct. 5, 2023, 8:51 a.m. UTC
From: Wenkai <advantech.susiteam@gmail.com>

In this patch, the driver has been extended to include basic watchdog
functionality, allowing users to configure the watchdog timeout duration,
start and stop the watchdog timer, and ping it to prevent system resets.
The driver also reports the remaining time until a watchdog reset is
triggered.

Signed-off-by: Wenkai <advantech.susiteam@gmail.com>
---
 drivers/watchdog/eiois200_wdt.c | 64 ++++++++++++++++++++++++++++++---
 1 file changed, 60 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/drivers/watchdog/eiois200_wdt.c b/drivers/watchdog/eiois200_wdt.c
index ce4435ac62f2..569e619448e5 100644
--- a/drivers/watchdog/eiois200_wdt.c
+++ b/drivers/watchdog/eiois200_wdt.c
@@ -106,6 +106,29 @@  static int get_time(u8 ctrl, u32 *val)
 	return ret;
 }
 
+static int set_time(u8 ctl, u32 time)
+{
+	/* sec to sec */
+	time *= 1000;
+
+	return PMC_WRITE(ctl, &time);
+}
+
+static int wdt_set_config(void)
+{
+	int ret;
+	u32 reset_time = 0;
+
+	reset_time = wddev.timeout;
+
+	ret = set_time(REG_RESET_EVENT_TIME, reset_time);
+	if (ret)
+		return ret;
+
+	dev_info(wdt.dev, "Config wdt reset time %d\n", reset_time);
+
+	return ret;
+}
 
 static int wdt_get_config(void)
 {
@@ -123,24 +146,57 @@  static int wdt_get_config(void)
 	return 0;
 }
 
+static int set_ctrl(u8 data)
+{
+	return PMC_WRITE(REG_CONTROL, &data);
+}
+
 static int wdt_start(struct watchdog_device *dev)
 {
-	return 0;
+	int ret;
+
+	ret = wdt_set_config();
+	if (ret)
+		return ret;
+
+	ret = set_ctrl(CTRL_START);
+	if (ret == 0) {
+		wdt.last_time = jiffies;
+		dev_dbg(wdt.dev, "Watchdog started\n");
+	}
+
+	return ret;
 }
 
 static int wdt_stop(struct watchdog_device *dev)
 {
-	return 0;
+	dev_dbg(wdt.dev, "Watchdog stopped\n");
+	wdt.last_time = 0;
+
+	return set_ctrl(CTRL_STOP);
 }
 
 static int wdt_ping(struct watchdog_device *dev)
 {
-	return 0;
+	int ret;
+
+	dev_dbg(wdt.dev, "Watchdog pings\n");
+
+	ret = set_ctrl(CTRL_TRIGGER);
+	if (ret == 0)
+		wdt.last_time = jiffies;
+
+	return ret;
 }
 
 static unsigned int wdt_get_timeleft(struct watchdog_device *dev)
 {
-	return 0;
+	unsigned int timeleft = 0;
+
+	if (wdt.last_time != 0)
+		timeleft = wddev.timeout - ((jiffies - wdt.last_time) / HZ);
+
+	return timeleft;
 }
 
 static int wdt_support(void)