[PATCH 7/7] rtc: m41t93: Add watchdog support

Akhilesh Patil posted 7 patches 4 weeks, 1 day ago
There is a newer version of this series
[PATCH 7/7] rtc: m41t93: Add watchdog support
Posted by Akhilesh Patil 4 weeks, 1 day ago
Implement watchdog feature driver for m41t93 rtc with 1s resolution and
alarm only mode. Define start, stop, ping, and set_timeout callbacks
as needed by watchdog framework.

Tested by observing IRQ pin(12) going low after intentionally not pinging
watchdog.

Signed-off-by: Akhilesh Patil <akhilesh@ee.iitb.ac.in>
---
 drivers/rtc/rtc-m41t93.c | 93 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 93 insertions(+)

diff --git a/drivers/rtc/rtc-m41t93.c b/drivers/rtc/rtc-m41t93.c
index 83cc34c4baae..e549c5f1e11a 100644
--- a/drivers/rtc/rtc-m41t93.c
+++ b/drivers/rtc/rtc-m41t93.c
@@ -14,6 +14,7 @@
 #include <linux/spi/spi.h>
 #include <linux/regmap.h>
 #include <linux/clk-provider.h>
+#include <linux/watchdog.h>
 
 #define M41T93_REG_SSEC			0
 #define M41T93_REG_ST_SEC		1
@@ -36,6 +37,10 @@
 #define M41T93_SQW_RS_MASK		0xf0
 #define M41T93_SQW_RS_SHIFT		4
 #define M41T93_BIT_SQWE			BIT(6)
+#define M41T93_REG_WATCHDOG		0x9
+#define M41T93_WDT_RB_MASK		0x3
+#define M41T93_WDT_BMB_MASK		0x7c
+#define M41T93_WDT_BMB_SHIFT		2
 
 
 #define M41T93_REG_ALM_HOUR_HT		0xc
@@ -52,6 +57,7 @@ struct m41t93_data {
 #ifdef CONFIG_COMMON_CLK
 	struct clk_hw clks;
 #endif
+	struct watchdog_device wdd;
 };
 
 static int m41t93_set_time(struct device *dev, struct rtc_time *tm)
@@ -409,6 +415,90 @@ static int rtc_m41t93_clks_register(struct device *dev, struct m41t93_data *m41t
 }
 #endif
 
+static int m41t93_wdt_ping(struct watchdog_device *wdd)
+{
+	u8 resolution, mult;
+	u8 val = 0;
+	int ret;
+	struct m41t93_data *m41t93 = watchdog_get_drvdata(wdd);
+
+	/*  Resolution supported by hardware
+	 *  0b00 : 1/16 seconds
+	 *  0b01 : 1/4 second
+	 *  0b10 : 1 second
+	 *  0b11 : 4 seconds
+	 */
+	resolution = 0x2; /* hardcode resolution to 1s */
+	mult = wdd->timeout;
+	val = resolution | (mult << M41T93_WDT_BMB_SHIFT &  M41T93_WDT_BMB_MASK);
+
+	ret = regmap_write_bits(m41t93->regmap, M41T93_REG_WATCHDOG,
+				 M41T93_WDT_RB_MASK | M41T93_WDT_BMB_MASK, val);
+
+	return ret;
+}
+
+static int m41t93_wdt_start(struct watchdog_device *wdd)
+{
+	return m41t93_wdt_ping(wdd);
+}
+
+static int m41t93_wdt_stop(struct watchdog_device *wdd)
+{
+	struct m41t93_data *m41t93 = watchdog_get_drvdata(wdd);
+
+	/* Write 0 to watchdog register */
+	return regmap_write_bits(m41t93->regmap, M41T93_REG_WATCHDOG,
+				  M41T93_WDT_RB_MASK | M41T93_WDT_BMB_MASK, 0);
+}
+
+static int m41t93_wdt_set_timeout(struct watchdog_device *wdd,
+				   unsigned int new_timeout)
+{
+	wdd->timeout = new_timeout;
+
+	return 0;
+}
+
+static const struct watchdog_info m41t93_wdt_info = {
+	.identity = "m41t93 rtc Watchdog",
+	.options = WDIOF_ALARMONLY,
+};
+
+static const struct watchdog_ops m41t93_watchdog_ops = {
+	.owner = THIS_MODULE,
+	.start = m41t93_wdt_start,
+	.stop = m41t93_wdt_stop,
+	.ping = m41t93_wdt_ping,
+	.set_timeout = m41t93_wdt_set_timeout,
+};
+
+static int m41t93_watchdog_register(struct device *dev, struct m41t93_data *m41t93)
+{
+	int ret;
+
+	m41t93->wdd.parent = dev;
+	m41t93->wdd.info = &m41t93_wdt_info;
+	m41t93->wdd.ops = &m41t93_watchdog_ops;
+	m41t93->wdd.min_timeout = 0;
+	m41t93->wdd.max_timeout = 10;
+	m41t93->wdd.timeout = 3; /* Default timeout is 3 sec */
+	m41t93->wdd.status = WATCHDOG_NOWAYOUT_INIT_STATUS;
+
+	watchdog_set_drvdata(&m41t93->wdd, m41t93);
+
+	ret = devm_watchdog_register_device(dev, &m41t93->wdd);
+	if (ret) {
+		dev_warn(dev, "Failed to register watchdog\n");
+		return ret;
+	}
+
+	/* Disable watchdog at start */
+	ret = m41t93_wdt_stop(&m41t93->wdd);
+
+	return ret;
+}
+
 static struct spi_driver m41t93_driver;
 
 static const struct regmap_config regmap_config = {
@@ -470,6 +560,9 @@ static int m41t93_probe(struct spi_device *spi)
 	if (ret)
 		dev_warn(&spi->dev, "Unable to register clock\n");
 #endif
+	ret = m41t93_watchdog_register(&spi->dev, m41t93);
+	if (ret)
+		dev_warn(&spi->dev, "Unable to register watchdog\n");
 
 	return 0;
 }
-- 
2.34.1
Re: [PATCH 7/7] rtc: m41t93: Add watchdog support
Posted by kernel test robot 4 weeks ago
Hi Akhilesh,

kernel test robot noticed the following build errors:

[auto build test ERROR on abelloni/rtc-next]
[also build test ERROR on linus/master v6.17-rc4 next-20250904]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Akhilesh-Patil/rtc-m41t93-add-device-tree-support/20250903-223155
base:   https://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git rtc-next
patch link:    https://lore.kernel.org/r/694706ad8577a36ef8948e0d9ca7ea561900fbc2.1756908788.git.akhilesh%40ee.iitb.ac.in
patch subject: [PATCH 7/7] rtc: m41t93: Add watchdog support
config: x86_64-randconfig-007-20250904 (https://download.01.org/0day-ci/archive/20250905/202509050759.dwYECwEA-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250905/202509050759.dwYECwEA-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202509050759.dwYECwEA-lkp@intel.com/

All errors (new ones prefixed by >>):

>> ld.lld: error: undefined symbol: devm_watchdog_register_device
   >>> referenced by rtc-m41t93.c:490 (drivers/rtc/rtc-m41t93.c:490)
   >>>               drivers/rtc/rtc-m41t93.o:(m41t93_watchdog_register) in archive vmlinux.a

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki