xref: /openbmc/linux/drivers/watchdog/rzg2l_wdt.c (revision 9144f784f852f9a125cabe9927b986d909bfa439)
12cbc5cd0SBiju Das // SPDX-License-Identifier: GPL-2.0
22cbc5cd0SBiju Das /*
32cbc5cd0SBiju Das  * Renesas RZ/G2L WDT Watchdog Driver
42cbc5cd0SBiju Das  *
52cbc5cd0SBiju Das  * Copyright (C) 2021 Renesas Electronics Corporation
62cbc5cd0SBiju Das  */
72cbc5cd0SBiju Das #include <linux/bitops.h>
82cbc5cd0SBiju Das #include <linux/clk.h>
92cbc5cd0SBiju Das #include <linux/delay.h>
102cbc5cd0SBiju Das #include <linux/io.h>
112cbc5cd0SBiju Das #include <linux/kernel.h>
122cbc5cd0SBiju Das #include <linux/module.h>
13cc85f87aSRob Herring #include <linux/of.h>
142cbc5cd0SBiju Das #include <linux/platform_device.h>
15*d33523b0SClaudiu Beznea #include <linux/pm_domain.h>
162cbc5cd0SBiju Das #include <linux/pm_runtime.h>
172cbc5cd0SBiju Das #include <linux/reset.h>
182cbc5cd0SBiju Das #include <linux/units.h>
192cbc5cd0SBiju Das #include <linux/watchdog.h>
202cbc5cd0SBiju Das 
212cbc5cd0SBiju Das #define WDTCNT		0x00
222cbc5cd0SBiju Das #define WDTSET		0x04
232cbc5cd0SBiju Das #define WDTTIM		0x08
242cbc5cd0SBiju Das #define WDTINT		0x0C
25f43e6ddbSBiju Das #define PECR		0x10
26f43e6ddbSBiju Das #define PEEN		0x14
272cbc5cd0SBiju Das #define WDTCNT_WDTEN	BIT(0)
282cbc5cd0SBiju Das #define WDTINT_INTDISP	BIT(0)
29f43e6ddbSBiju Das #define PEEN_FORCE	BIT(0)
302cbc5cd0SBiju Das 
312cbc5cd0SBiju Das #define WDT_DEFAULT_TIMEOUT		60U
322cbc5cd0SBiju Das 
332cbc5cd0SBiju Das /* Setting period time register only 12 bit set in WDTSET[31:20] */
342cbc5cd0SBiju Das #define WDTSET_COUNTER_MASK		(0xFFF00000)
352cbc5cd0SBiju Das #define WDTSET_COUNTER_VAL(f)		((f) << 20)
362cbc5cd0SBiju Das 
372cbc5cd0SBiju Das #define F2CYCLE_NSEC(f)			(1000000000 / (f))
382cbc5cd0SBiju Das 
39f769f979SFabrizio Castro #define RZV2M_A_NSEC			730
40f769f979SFabrizio Castro 
412cbc5cd0SBiju Das static bool nowayout = WATCHDOG_NOWAYOUT;
422cbc5cd0SBiju Das module_param(nowayout, bool, 0);
432cbc5cd0SBiju Das MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
442cbc5cd0SBiju Das 				__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
452cbc5cd0SBiju Das 
46ec122fd9SPhil Edworthy enum rz_wdt_type {
47ec122fd9SPhil Edworthy 	WDT_RZG2L,
48ec122fd9SPhil Edworthy 	WDT_RZV2M,
49ec122fd9SPhil Edworthy };
50ec122fd9SPhil Edworthy 
512cbc5cd0SBiju Das struct rzg2l_wdt_priv {
522cbc5cd0SBiju Das 	void __iomem *base;
532cbc5cd0SBiju Das 	struct watchdog_device wdev;
542cbc5cd0SBiju Das 	struct reset_control *rstc;
552cbc5cd0SBiju Das 	unsigned long osc_clk_rate;
562cbc5cd0SBiju Das 	unsigned long delay;
57e4cf8959SBiju Das 	struct clk *pclk;
58e4cf8959SBiju Das 	struct clk *osc_clk;
59ec122fd9SPhil Edworthy 	enum rz_wdt_type devtype;
602cbc5cd0SBiju Das };
612cbc5cd0SBiju Das 
rzg2l_wdt_wait_delay(struct rzg2l_wdt_priv * priv)622cbc5cd0SBiju Das static void rzg2l_wdt_wait_delay(struct rzg2l_wdt_priv *priv)
632cbc5cd0SBiju Das {
642cbc5cd0SBiju Das 	/* delay timer when change the setting register */
652cbc5cd0SBiju Das 	ndelay(priv->delay);
662cbc5cd0SBiju Das }
672cbc5cd0SBiju Das 
rzg2l_wdt_get_cycle_usec(unsigned long cycle,u32 wdttime)682cbc5cd0SBiju Das static u32 rzg2l_wdt_get_cycle_usec(unsigned long cycle, u32 wdttime)
692cbc5cd0SBiju Das {
70ea2949dfSBiju Das 	u64 timer_cycle_us = 1024 * 1024ULL * (wdttime + 1) * MICRO;
712cbc5cd0SBiju Das 
722cbc5cd0SBiju Das 	return div64_ul(timer_cycle_us, cycle);
732cbc5cd0SBiju Das }
742cbc5cd0SBiju Das 
rzg2l_wdt_write(struct rzg2l_wdt_priv * priv,u32 val,unsigned int reg)752cbc5cd0SBiju Das static void rzg2l_wdt_write(struct rzg2l_wdt_priv *priv, u32 val, unsigned int reg)
762cbc5cd0SBiju Das {
772cbc5cd0SBiju Das 	if (reg == WDTSET)
782cbc5cd0SBiju Das 		val &= WDTSET_COUNTER_MASK;
792cbc5cd0SBiju Das 
802cbc5cd0SBiju Das 	writel_relaxed(val, priv->base + reg);
812cbc5cd0SBiju Das 	/* Registers other than the WDTINT is always synchronized with WDT_CLK */
822cbc5cd0SBiju Das 	if (reg != WDTINT)
832cbc5cd0SBiju Das 		rzg2l_wdt_wait_delay(priv);
842cbc5cd0SBiju Das }
852cbc5cd0SBiju Das 
rzg2l_wdt_init_timeout(struct watchdog_device * wdev)862cbc5cd0SBiju Das static void rzg2l_wdt_init_timeout(struct watchdog_device *wdev)
872cbc5cd0SBiju Das {
882cbc5cd0SBiju Das 	struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
892cbc5cd0SBiju Das 	u32 time_out;
902cbc5cd0SBiju Das 
912cbc5cd0SBiju Das 	/* Clear Lapsed Time Register and clear Interrupt */
922cbc5cd0SBiju Das 	rzg2l_wdt_write(priv, WDTINT_INTDISP, WDTINT);
932cbc5cd0SBiju Das 	/* 2 consecutive overflow cycle needed to trigger reset */
942cbc5cd0SBiju Das 	time_out = (wdev->timeout * (MICRO / 2)) /
952cbc5cd0SBiju Das 		   rzg2l_wdt_get_cycle_usec(priv->osc_clk_rate, 0);
962cbc5cd0SBiju Das 	rzg2l_wdt_write(priv, WDTSET_COUNTER_VAL(time_out), WDTSET);
972cbc5cd0SBiju Das }
982cbc5cd0SBiju Das 
rzg2l_wdt_start(struct watchdog_device * wdev)992cbc5cd0SBiju Das static int rzg2l_wdt_start(struct watchdog_device *wdev)
1002cbc5cd0SBiju Das {
1012cbc5cd0SBiju Das 	struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
102fb452656SClaudiu Beznea 	int ret;
1032cbc5cd0SBiju Das 
104fb452656SClaudiu Beznea 	ret = pm_runtime_resume_and_get(wdev->parent);
105fb452656SClaudiu Beznea 	if (ret)
106fb452656SClaudiu Beznea 		return ret;
1072cbc5cd0SBiju Das 
1087ea100fbSClaudiu Beznea 	ret = reset_control_deassert(priv->rstc);
1097ea100fbSClaudiu Beznea 	if (ret) {
1107ea100fbSClaudiu Beznea 		pm_runtime_put(wdev->parent);
1117ea100fbSClaudiu Beznea 		return ret;
1127ea100fbSClaudiu Beznea 	}
1137ea100fbSClaudiu Beznea 
1142cbc5cd0SBiju Das 	/* Initialize time out */
1152cbc5cd0SBiju Das 	rzg2l_wdt_init_timeout(wdev);
1162cbc5cd0SBiju Das 
1172cbc5cd0SBiju Das 	/* Initialize watchdog counter register */
1182cbc5cd0SBiju Das 	rzg2l_wdt_write(priv, 0, WDTTIM);
1192cbc5cd0SBiju Das 
1202cbc5cd0SBiju Das 	/* Enable watchdog timer*/
1212cbc5cd0SBiju Das 	rzg2l_wdt_write(priv, WDTCNT_WDTEN, WDTCNT);
1222cbc5cd0SBiju Das 
1232cbc5cd0SBiju Das 	return 0;
1242cbc5cd0SBiju Das }
1252cbc5cd0SBiju Das 
rzg2l_wdt_stop(struct watchdog_device * wdev)1262cbc5cd0SBiju Das static int rzg2l_wdt_stop(struct watchdog_device *wdev)
1272cbc5cd0SBiju Das {
1282cbc5cd0SBiju Das 	struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
1298aeab1afSClaudiu Beznea 	int ret;
1302cbc5cd0SBiju Das 
1317ea100fbSClaudiu Beznea 	ret = reset_control_assert(priv->rstc);
1327ea100fbSClaudiu Beznea 	if (ret)
1337ea100fbSClaudiu Beznea 		return ret;
1348aeab1afSClaudiu Beznea 
1358aeab1afSClaudiu Beznea 	ret = pm_runtime_put(wdev->parent);
1368aeab1afSClaudiu Beznea 	if (ret < 0)
1378aeab1afSClaudiu Beznea 		return ret;
1382cbc5cd0SBiju Das 
1392cbc5cd0SBiju Das 	return 0;
1402cbc5cd0SBiju Das }
1412cbc5cd0SBiju Das 
rzg2l_wdt_set_timeout(struct watchdog_device * wdev,unsigned int timeout)1424055ee81SBiju Das static int rzg2l_wdt_set_timeout(struct watchdog_device *wdev, unsigned int timeout)
1434055ee81SBiju Das {
144fb452656SClaudiu Beznea 	int ret = 0;
145fb452656SClaudiu Beznea 
1464055ee81SBiju Das 	wdev->timeout = timeout;
1474055ee81SBiju Das 
1484055ee81SBiju Das 	/*
1494055ee81SBiju Das 	 * If the watchdog is active, reset the module for updating the WDTSET
1506ba6f0f5SLad Prabhakar 	 * register by calling rzg2l_wdt_stop() (which internally calls reset_control_reset()
1516ba6f0f5SLad Prabhakar 	 * to reset the module) so that it is updated with new timeout values.
1524055ee81SBiju Das 	 */
1534055ee81SBiju Das 	if (watchdog_active(wdev)) {
1548aeab1afSClaudiu Beznea 		ret = rzg2l_wdt_stop(wdev);
1558aeab1afSClaudiu Beznea 		if (ret)
1568aeab1afSClaudiu Beznea 			return ret;
1578aeab1afSClaudiu Beznea 
158fb452656SClaudiu Beznea 		ret = rzg2l_wdt_start(wdev);
1594055ee81SBiju Das 	}
1604055ee81SBiju Das 
161fb452656SClaudiu Beznea 	return ret;
1624055ee81SBiju Das }
1634055ee81SBiju Das 
rzg2l_wdt_restart(struct watchdog_device * wdev,unsigned long action,void * data)1642cbc5cd0SBiju Das static int rzg2l_wdt_restart(struct watchdog_device *wdev,
1652cbc5cd0SBiju Das 			     unsigned long action, void *data)
1662cbc5cd0SBiju Das {
1672cbc5cd0SBiju Das 	struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
168e145b77fSClaudiu Beznea 	int ret;
1692cbc5cd0SBiju Das 
170*d33523b0SClaudiu Beznea 	/*
171*d33523b0SClaudiu Beznea 	 * In case of RZ/G3S the watchdog device may be part of an IRQ safe power
172*d33523b0SClaudiu Beznea 	 * domain that is currently powered off. In this case we need to power
173*d33523b0SClaudiu Beznea 	 * it on before accessing registers. Along with this the clocks will be
174*d33523b0SClaudiu Beznea 	 * enabled. We don't undo the pm_runtime_resume_and_get() as the device
175*d33523b0SClaudiu Beznea 	 * need to be on for the reboot to happen.
176*d33523b0SClaudiu Beznea 	 *
177*d33523b0SClaudiu Beznea 	 * For the rest of SoCs not registering a watchdog IRQ safe power
178*d33523b0SClaudiu Beznea 	 * domain it is safe to call pm_runtime_resume_and_get() as the
179*d33523b0SClaudiu Beznea 	 * irq_safe_dev_in_sleep_domain() call in genpd_runtime_resume()
180*d33523b0SClaudiu Beznea 	 * returns non zero value and the genpd_lock() is avoided, thus, there
181*d33523b0SClaudiu Beznea 	 * will be no invalid wait context reported by lockdep.
182*d33523b0SClaudiu Beznea 	 */
183*d33523b0SClaudiu Beznea 	ret = pm_runtime_resume_and_get(wdev->parent);
184*d33523b0SClaudiu Beznea 	if (ret)
185*d33523b0SClaudiu Beznea 		return ret;
1862cbc5cd0SBiju Das 
187ec122fd9SPhil Edworthy 	if (priv->devtype == WDT_RZG2L) {
1887ea100fbSClaudiu Beznea 		ret = reset_control_deassert(priv->rstc);
1897ea100fbSClaudiu Beznea 		if (ret)
1907ea100fbSClaudiu Beznea 			return ret;
1917ea100fbSClaudiu Beznea 
192f43e6ddbSBiju Das 		/* Generate Reset (WDTRSTB) Signal on parity error */
193f43e6ddbSBiju Das 		rzg2l_wdt_write(priv, 0, PECR);
1942cbc5cd0SBiju Das 
195f43e6ddbSBiju Das 		/* Force parity error */
196f43e6ddbSBiju Das 		rzg2l_wdt_write(priv, PEEN_FORCE, PEEN);
197ec122fd9SPhil Edworthy 	} else {
198ec122fd9SPhil Edworthy 		/* RZ/V2M doesn't have parity error registers */
199e145b77fSClaudiu Beznea 		ret = reset_control_reset(priv->rstc);
200e145b77fSClaudiu Beznea 		if (ret)
201e145b77fSClaudiu Beznea 			return ret;
202ec122fd9SPhil Edworthy 
203ec122fd9SPhil Edworthy 		wdev->timeout = 0;
204ec122fd9SPhil Edworthy 
205ec122fd9SPhil Edworthy 		/* Initialize time out */
206ec122fd9SPhil Edworthy 		rzg2l_wdt_init_timeout(wdev);
207ec122fd9SPhil Edworthy 
208ec122fd9SPhil Edworthy 		/* Initialize watchdog counter register */
209ec122fd9SPhil Edworthy 		rzg2l_wdt_write(priv, 0, WDTTIM);
210ec122fd9SPhil Edworthy 
211ec122fd9SPhil Edworthy 		/* Enable watchdog timer*/
212ec122fd9SPhil Edworthy 		rzg2l_wdt_write(priv, WDTCNT_WDTEN, WDTCNT);
213ec122fd9SPhil Edworthy 
214ec122fd9SPhil Edworthy 		/* Wait 2 consecutive overflow cycles for reset */
215ec122fd9SPhil Edworthy 		mdelay(DIV_ROUND_UP(2 * 0xFFFFF * 1000, priv->osc_clk_rate));
216ec122fd9SPhil Edworthy 	}
2172cbc5cd0SBiju Das 
2182cbc5cd0SBiju Das 	return 0;
2192cbc5cd0SBiju Das }
2202cbc5cd0SBiju Das 
2212cbc5cd0SBiju Das static const struct watchdog_info rzg2l_wdt_ident = {
2222cbc5cd0SBiju Das 	.options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT,
2232cbc5cd0SBiju Das 	.identity = "Renesas RZ/G2L WDT Watchdog",
2242cbc5cd0SBiju Das };
2252cbc5cd0SBiju Das 
rzg2l_wdt_ping(struct watchdog_device * wdev)2262cbc5cd0SBiju Das static int rzg2l_wdt_ping(struct watchdog_device *wdev)
2272cbc5cd0SBiju Das {
2282cbc5cd0SBiju Das 	struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
2292cbc5cd0SBiju Das 
2302cbc5cd0SBiju Das 	rzg2l_wdt_write(priv, WDTINT_INTDISP, WDTINT);
2312cbc5cd0SBiju Das 
2322cbc5cd0SBiju Das 	return 0;
2332cbc5cd0SBiju Das }
2342cbc5cd0SBiju Das 
2352cbc5cd0SBiju Das static const struct watchdog_ops rzg2l_wdt_ops = {
2362cbc5cd0SBiju Das 	.owner = THIS_MODULE,
2372cbc5cd0SBiju Das 	.start = rzg2l_wdt_start,
2382cbc5cd0SBiju Das 	.stop = rzg2l_wdt_stop,
2392cbc5cd0SBiju Das 	.ping = rzg2l_wdt_ping,
2404055ee81SBiju Das 	.set_timeout = rzg2l_wdt_set_timeout,
2412cbc5cd0SBiju Das 	.restart = rzg2l_wdt_restart,
2422cbc5cd0SBiju Das };
2432cbc5cd0SBiju Das 
rzg2l_wdt_pm_disable(void * data)2447ea100fbSClaudiu Beznea static void rzg2l_wdt_pm_disable(void *data)
2452cbc5cd0SBiju Das {
2462cbc5cd0SBiju Das 	struct watchdog_device *wdev = data;
2472cbc5cd0SBiju Das 
2482cbc5cd0SBiju Das 	pm_runtime_disable(wdev->parent);
2492cbc5cd0SBiju Das }
2502cbc5cd0SBiju Das 
rzg2l_wdt_probe(struct platform_device * pdev)2512cbc5cd0SBiju Das static int rzg2l_wdt_probe(struct platform_device *pdev)
2522cbc5cd0SBiju Das {
2532cbc5cd0SBiju Das 	struct device *dev = &pdev->dev;
2542cbc5cd0SBiju Das 	struct rzg2l_wdt_priv *priv;
2552cbc5cd0SBiju Das 	unsigned long pclk_rate;
2562cbc5cd0SBiju Das 	int ret;
2572cbc5cd0SBiju Das 
2582cbc5cd0SBiju Das 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
2592cbc5cd0SBiju Das 	if (!priv)
2602cbc5cd0SBiju Das 		return -ENOMEM;
2612cbc5cd0SBiju Das 
2622cbc5cd0SBiju Das 	priv->base = devm_platform_ioremap_resource(pdev, 0);
2632cbc5cd0SBiju Das 	if (IS_ERR(priv->base))
2642cbc5cd0SBiju Das 		return PTR_ERR(priv->base);
2652cbc5cd0SBiju Das 
2662cbc5cd0SBiju Das 	/* Get watchdog main clock */
267e4cf8959SBiju Das 	priv->osc_clk = devm_clk_get(&pdev->dev, "oscclk");
268e4cf8959SBiju Das 	if (IS_ERR(priv->osc_clk))
269e4cf8959SBiju Das 		return dev_err_probe(&pdev->dev, PTR_ERR(priv->osc_clk), "no oscclk");
2702cbc5cd0SBiju Das 
271e4cf8959SBiju Das 	priv->osc_clk_rate = clk_get_rate(priv->osc_clk);
2722cbc5cd0SBiju Das 	if (!priv->osc_clk_rate)
2732cbc5cd0SBiju Das 		return dev_err_probe(&pdev->dev, -EINVAL, "oscclk rate is 0");
2742cbc5cd0SBiju Das 
2752cbc5cd0SBiju Das 	/* Get Peripheral clock */
276e4cf8959SBiju Das 	priv->pclk = devm_clk_get(&pdev->dev, "pclk");
277e4cf8959SBiju Das 	if (IS_ERR(priv->pclk))
278e4cf8959SBiju Das 		return dev_err_probe(&pdev->dev, PTR_ERR(priv->pclk), "no pclk");
2792cbc5cd0SBiju Das 
280e4cf8959SBiju Das 	pclk_rate = clk_get_rate(priv->pclk);
2812cbc5cd0SBiju Das 	if (!pclk_rate)
2822cbc5cd0SBiju Das 		return dev_err_probe(&pdev->dev, -EINVAL, "pclk rate is 0");
2832cbc5cd0SBiju Das 
2842cbc5cd0SBiju Das 	priv->delay = F2CYCLE_NSEC(priv->osc_clk_rate) * 6 + F2CYCLE_NSEC(pclk_rate) * 9;
2852cbc5cd0SBiju Das 
2862cbc5cd0SBiju Das 	priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
2872cbc5cd0SBiju Das 	if (IS_ERR(priv->rstc))
2882cbc5cd0SBiju Das 		return dev_err_probe(&pdev->dev, PTR_ERR(priv->rstc),
2892cbc5cd0SBiju Das 				     "failed to get cpg reset");
2902cbc5cd0SBiju Das 
291ec122fd9SPhil Edworthy 	priv->devtype = (uintptr_t)of_device_get_match_data(dev);
292ec122fd9SPhil Edworthy 
293*d33523b0SClaudiu Beznea 	pm_runtime_irq_safe(&pdev->dev);
2942cbc5cd0SBiju Das 	pm_runtime_enable(&pdev->dev);
2952cbc5cd0SBiju Das 
2962cbc5cd0SBiju Das 	priv->wdev.info = &rzg2l_wdt_ident;
2972cbc5cd0SBiju Das 	priv->wdev.ops = &rzg2l_wdt_ops;
2982cbc5cd0SBiju Das 	priv->wdev.parent = dev;
2992cbc5cd0SBiju Das 	priv->wdev.min_timeout = 1;
3002cbc5cd0SBiju Das 	priv->wdev.max_timeout = rzg2l_wdt_get_cycle_usec(priv->osc_clk_rate, 0xfff) /
3012cbc5cd0SBiju Das 				 USEC_PER_SEC;
3022cbc5cd0SBiju Das 	priv->wdev.timeout = WDT_DEFAULT_TIMEOUT;
3032cbc5cd0SBiju Das 
3042cbc5cd0SBiju Das 	watchdog_set_drvdata(&priv->wdev, priv);
3057ea100fbSClaudiu Beznea 	ret = devm_add_action_or_reset(&pdev->dev, rzg2l_wdt_pm_disable, &priv->wdev);
3062cbc5cd0SBiju Das 	if (ret < 0)
3072cbc5cd0SBiju Das 		return ret;
3082cbc5cd0SBiju Das 
3092cbc5cd0SBiju Das 	watchdog_set_nowayout(&priv->wdev, nowayout);
3102cbc5cd0SBiju Das 	watchdog_stop_on_unregister(&priv->wdev);
3112cbc5cd0SBiju Das 
3122cbc5cd0SBiju Das 	ret = watchdog_init_timeout(&priv->wdev, 0, dev);
3132cbc5cd0SBiju Das 	if (ret)
3142cbc5cd0SBiju Das 		dev_warn(dev, "Specified timeout invalid, using default");
3152cbc5cd0SBiju Das 
3162cbc5cd0SBiju Das 	return devm_watchdog_register_device(&pdev->dev, &priv->wdev);
3172cbc5cd0SBiju Das }
3182cbc5cd0SBiju Das 
3192cbc5cd0SBiju Das static const struct of_device_id rzg2l_wdt_ids[] = {
320ec122fd9SPhil Edworthy 	{ .compatible = "renesas,rzg2l-wdt", .data = (void *)WDT_RZG2L },
321ec122fd9SPhil Edworthy 	{ .compatible = "renesas,rzv2m-wdt", .data = (void *)WDT_RZV2M },
3222cbc5cd0SBiju Das 	{ /* sentinel */ }
3232cbc5cd0SBiju Das };
3242cbc5cd0SBiju Das MODULE_DEVICE_TABLE(of, rzg2l_wdt_ids);
3252cbc5cd0SBiju Das 
3262cbc5cd0SBiju Das static struct platform_driver rzg2l_wdt_driver = {
3272cbc5cd0SBiju Das 	.driver = {
3282cbc5cd0SBiju Das 		.name = "rzg2l_wdt",
3292cbc5cd0SBiju Das 		.of_match_table = rzg2l_wdt_ids,
3302cbc5cd0SBiju Das 	},
3312cbc5cd0SBiju Das 	.probe = rzg2l_wdt_probe,
3322cbc5cd0SBiju Das };
3332cbc5cd0SBiju Das module_platform_driver(rzg2l_wdt_driver);
3342cbc5cd0SBiju Das 
3352cbc5cd0SBiju Das MODULE_DESCRIPTION("Renesas RZ/G2L WDT Watchdog Driver");
3362cbc5cd0SBiju Das MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>");
3372cbc5cd0SBiju Das MODULE_LICENSE("GPL v2");
338