Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'linux-watchdog-6.12-rc1' of git://www.linux-watchdog.org/linux-watchdog

Pull watchdog updates from Wim Van Sebroeck:

- Add Watchdog Timer driver for RZ/V2H(P)

- Add Cirrus EP93x

- Some small fixes and improvements

* tag 'linux-watchdog-6.12-rc1' of git://www.linux-watchdog.org/linux-watchdog:
watchdog: Convert comma to semicolon
watchdog: rzv2h_wdt: Add missing MODULE_LICENSE tag to fix modpost error
dt-bindings: watchdog: Add Cirrus EP93x
dt-bindings: watchdog: stm32-iwdg: Document interrupt and wakeup properties
drivers: watchdog: marvell_gti: Convert comma to semicolon
watchdog: iTCO_wdt: Convert comma to semicolon
watchdog: Add Watchdog Timer driver for RZ/V2H(P)
dt-bindings: watchdog: renesas,wdt: Document RZ/V2H(P) SoC
watchdog: imx_sc_wdt: detect if already running
watchdog: imx2_wdt: Remove __maybe_unused notations
watchdog: imx_sc_wdt: Don't disable WDT in suspend
watchdog: imx7ulp_wdt: move post_rcs_wait into struct imx_wdt_hw_feature

+388 -47
+42
Documentation/devicetree/bindings/watchdog/cirrus,ep9301-wdt.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/watchdog/cirrus,ep9301-wdt.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Cirrus Logic EP93xx Watchdog Timer 8 + 9 + maintainers: 10 + - Nikita Shubin <nikita.shubin@maquefel.me> 11 + - Alexander Sverdlin <alexander.sverdlin@gmail.com> 12 + 13 + allOf: 14 + - $ref: watchdog.yaml# 15 + 16 + properties: 17 + compatible: 18 + oneOf: 19 + - const: cirrus,ep9301-wdt 20 + - items: 21 + - enum: 22 + - cirrus,ep9302-wdt 23 + - cirrus,ep9307-wdt 24 + - cirrus,ep9312-wdt 25 + - cirrus,ep9315-wdt 26 + - const: cirrus,ep9301-wdt 27 + 28 + reg: 29 + maxItems: 1 30 + 31 + required: 32 + - compatible 33 + - reg 34 + 35 + unevaluatedProperties: false 36 + 37 + examples: 38 + - | 39 + watchdog@80940000 { 40 + compatible = "cirrus,ep9301-wdt"; 41 + reg = <0x80940000 0x08>; 42 + };
+16 -1
Documentation/devicetree/bindings/watchdog/renesas,wdt.yaml
··· 75 75 - renesas,r8a779h0-wdt # R-Car V4M 76 76 - const: renesas,rcar-gen4-wdt # R-Car Gen4 77 77 78 + - const: renesas,r9a09g057-wdt # RZ/V2H(P) 79 + 78 80 reg: 79 81 maxItems: 1 80 82 ··· 115 113 required: 116 114 - compatible 117 115 - reg 118 - - interrupts 119 116 - clocks 120 117 121 118 allOf: ··· 138 137 compatible: 139 138 contains: 140 139 enum: 140 + - renesas,r9a09g057-wdt 141 141 - renesas,rzg2l-wdt 142 142 - renesas,rzv2m-wdt 143 143 then: ··· 172 170 properties: 173 171 interrupts: 174 172 maxItems: 1 173 + 174 + - if: 175 + properties: 176 + compatible: 177 + contains: 178 + const: renesas,r9a09g057-wdt 179 + then: 180 + properties: 181 + interrupts: false 182 + interrupt-names: false 183 + else: 184 + required: 185 + - interrupts 175 186 176 187 additionalProperties: false 177 188
+6
Documentation/devicetree/bindings/watchdog/st,stm32-iwdg.yaml
··· 36 36 minItems: 1 37 37 maxItems: 2 38 38 39 + interrupts: 40 + maxItems: 1 41 + description: Pre-timeout interrupt from the watchdog. 42 + 43 + wakeup-source: true 44 + 39 45 required: 40 46 - compatible 41 47 - reg
+9
drivers/watchdog/Kconfig
··· 953 953 This driver adds watchdog support for the integrated watchdogs in the 954 954 Renesas RZ/G2L SoCs. These watchdogs can be used to reset a system. 955 955 956 + config RENESAS_RZV2HWDT 957 + tristate "Renesas RZ/V2H(P) WDT Watchdog" 958 + depends on ARCH_R9A09G057 || COMPILE_TEST 959 + depends on PM || COMPILE_TEST 960 + select WATCHDOG_CORE 961 + help 962 + This driver adds watchdog support for the integrated watchdogs in the 963 + Renesas RZ/V2H(P) SoCs. These watchdogs can be used to reset a system. 964 + 956 965 config ASPEED_WATCHDOG 957 966 tristate "Aspeed BMC watchdog support" 958 967 depends on ARCH_ASPEED || COMPILE_TEST
+1
drivers/watchdog/Makefile
··· 86 86 obj-$(CONFIG_RENESAS_RZAWDT) += rza_wdt.o 87 87 obj-$(CONFIG_RENESAS_RZN1WDT) += rzn1_wdt.o 88 88 obj-$(CONFIG_RENESAS_RZG2LWDT) += rzg2l_wdt.o 89 + obj-$(CONFIG_RENESAS_RZV2HWDT) += rzv2h_wdt.o 89 90 obj-$(CONFIG_ASPEED_WATCHDOG) += aspeed_wdt.o 90 91 obj-$(CONFIG_STM32_WATCHDOG) += stm32_iwdg.o 91 92 obj-$(CONFIG_UNIPHIER_WATCHDOG) += uniphier_wdt.o
+2 -2
drivers/watchdog/iTCO_wdt.c
··· 563 563 } 564 564 565 565 ident.firmware_version = p->iTCO_version; 566 - p->wddev.info = &ident, 567 - p->wddev.ops = &iTCO_wdt_ops, 566 + p->wddev.info = &ident; 567 + p->wddev.ops = &iTCO_wdt_ops; 568 568 p->wddev.bootstatus = 0; 569 569 p->wddev.timeout = WATCHDOG_TIMEOUT; 570 570 watchdog_set_nowayout(&p->wddev, nowayout);
+5 -5
drivers/watchdog/imx2_wdt.c
··· 379 379 } 380 380 381 381 /* Disable watchdog if it is active or non-active but still running */ 382 - static int __maybe_unused imx2_wdt_suspend(struct device *dev) 382 + static int imx2_wdt_suspend(struct device *dev) 383 383 { 384 384 struct watchdog_device *wdog = dev_get_drvdata(dev); 385 385 struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog); ··· 404 404 } 405 405 406 406 /* Enable watchdog and configure it if necessary */ 407 - static int __maybe_unused imx2_wdt_resume(struct device *dev) 407 + static int imx2_wdt_resume(struct device *dev) 408 408 { 409 409 struct watchdog_device *wdog = dev_get_drvdata(dev); 410 410 struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog); ··· 435 435 return 0; 436 436 } 437 437 438 - static SIMPLE_DEV_PM_OPS(imx2_wdt_pm_ops, imx2_wdt_suspend, 439 - imx2_wdt_resume); 438 + static DEFINE_SIMPLE_DEV_PM_OPS(imx2_wdt_pm_ops, imx2_wdt_suspend, 439 + imx2_wdt_resume); 440 440 441 441 static struct imx2_wdt_data imx_wdt = { 442 442 .wdw_supported = true, ··· 476 476 .shutdown = imx2_wdt_shutdown, 477 477 .driver = { 478 478 .name = DRIVER_NAME, 479 - .pm = &imx2_wdt_pm_ops, 479 + .pm = pm_sleep_ptr(&imx2_wdt_pm_ops), 480 480 .of_match_table = imx2_wdt_dt_ids, 481 481 }, 482 482 };
+9 -12
drivers/watchdog/imx7ulp_wdt.c
··· 55 55 56 56 struct imx_wdt_hw_feature { 57 57 bool prescaler_enable; 58 + bool post_rcs_wait; 58 59 u32 wdog_clock_rate; 59 60 }; 60 61 ··· 63 62 struct watchdog_device wdd; 64 63 void __iomem *base; 65 64 struct clk *clk; 66 - bool post_rcs_wait; 67 65 bool ext_reset; 68 66 const struct imx_wdt_hw_feature *hw; 69 67 }; ··· 95 95 ret = -ETIMEDOUT; 96 96 97 97 /* Wait 2.5 clocks after RCS done */ 98 - if (wdt->post_rcs_wait) 98 + if (wdt->hw->post_rcs_wait) 99 99 usleep_range(wait_min, wait_min + 2000); 100 100 101 101 return ret; ··· 334 334 /* The WDOG may need to do external reset through dedicated pin */ 335 335 imx7ulp_wdt->ext_reset = of_property_read_bool(dev->of_node, "fsl,ext-reset-output"); 336 336 337 - imx7ulp_wdt->post_rcs_wait = true; 338 - if (of_device_is_compatible(dev->of_node, 339 - "fsl,imx8ulp-wdt")) { 340 - dev_info(dev, "imx8ulp wdt probe\n"); 341 - imx7ulp_wdt->post_rcs_wait = false; 342 - } else { 343 - dev_info(dev, "imx7ulp wdt probe\n"); 344 - } 345 - 346 337 wdog = &imx7ulp_wdt->wdd; 347 338 wdog->info = &imx7ulp_wdt_info; 348 339 wdog->ops = &imx7ulp_wdt_ops; ··· 394 403 static const struct imx_wdt_hw_feature imx7ulp_wdt_hw = { 395 404 .prescaler_enable = false, 396 405 .wdog_clock_rate = 1000, 406 + .post_rcs_wait = true, 407 + }; 408 + 409 + static const struct imx_wdt_hw_feature imx8ulp_wdt_hw = { 410 + .prescaler_enable = false, 411 + .wdog_clock_rate = 1000, 397 412 }; 398 413 399 414 static const struct imx_wdt_hw_feature imx93_wdt_hw = { ··· 408 411 }; 409 412 410 413 static const struct of_device_id imx7ulp_wdt_dt_ids[] = { 411 - { .compatible = "fsl,imx8ulp-wdt", .data = &imx7ulp_wdt_hw, }, 412 414 { .compatible = "fsl,imx7ulp-wdt", .data = &imx7ulp_wdt_hw, }, 415 + { .compatible = "fsl,imx8ulp-wdt", .data = &imx8ulp_wdt_hw, }, 413 416 { .compatible = "fsl,imx93-wdt", .data = &imx93_wdt_hw, }, 414 417 { /* sentinel */ } 415 418 };
+22 -24
drivers/watchdog/imx_sc_wdt.c
··· 56 56 return 0; 57 57 } 58 58 59 + static bool imx_sc_wdt_is_running(void) 60 + { 61 + struct arm_smccc_res res; 62 + 63 + arm_smccc_smc(IMX_SIP_TIMER, IMX_SIP_TIMER_START_WDOG, 64 + 0, 0, 0, 0, 0, 0, &res); 65 + 66 + /* Already enabled (SC_TIMER_ERR_BUSY)? */ 67 + if (res.a0 == SC_TIMER_ERR_BUSY) 68 + return true; 69 + 70 + /* Undo only if that was us who has (successfully) enabled the WDT */ 71 + if (!res.a0) 72 + arm_smccc_smc(IMX_SIP_TIMER, IMX_SIP_TIMER_STOP_WDOG, 73 + 0, 0, 0, 0, 0, 0, &res); 74 + 75 + return false; 76 + } 77 + 59 78 static int imx_sc_wdt_start(struct watchdog_device *wdog) 60 79 { 61 80 struct arm_smccc_res res; ··· 202 183 if (ret) 203 184 return ret; 204 185 186 + if (imx_sc_wdt_is_running()) 187 + set_bit(WDOG_HW_RUNNING, &wdog->status); 188 + 205 189 watchdog_stop_on_reboot(wdog); 206 190 watchdog_stop_on_unregister(wdog); 207 191 ··· 238 216 return devm_watchdog_register_device(dev, wdog); 239 217 } 240 218 241 - static int __maybe_unused imx_sc_wdt_suspend(struct device *dev) 242 - { 243 - struct imx_sc_wdt_device *imx_sc_wdd = dev_get_drvdata(dev); 244 - 245 - if (watchdog_active(&imx_sc_wdd->wdd)) 246 - imx_sc_wdt_stop(&imx_sc_wdd->wdd); 247 - 248 - return 0; 249 - } 250 - 251 - static int __maybe_unused imx_sc_wdt_resume(struct device *dev) 252 - { 253 - struct imx_sc_wdt_device *imx_sc_wdd = dev_get_drvdata(dev); 254 - 255 - if (watchdog_active(&imx_sc_wdd->wdd)) 256 - imx_sc_wdt_start(&imx_sc_wdd->wdd); 257 - 258 - return 0; 259 - } 260 - 261 - static SIMPLE_DEV_PM_OPS(imx_sc_wdt_pm_ops, 262 - imx_sc_wdt_suspend, imx_sc_wdt_resume); 263 - 264 219 static const struct of_device_id imx_sc_wdt_dt_ids[] = { 265 220 { .compatible = "fsl,imx-sc-wdt", }, 266 221 { /* sentinel */ } ··· 249 250 .driver = { 250 251 .name = "imx-sc-wdt", 251 252 .of_match_table = imx_sc_wdt_dt_ids, 252 - .pm = &imx_sc_wdt_pm_ops, 253 253 }, 254 254 }; 255 255 module_platform_driver(imx_sc_wdt_driver);
+2 -2
drivers/watchdog/marvell_gti_wdt.c
··· 285 285 } 286 286 287 287 wdog_dev = &priv->wdev; 288 - wdog_dev->info = &gti_wdt_ident, 289 - wdog_dev->ops = &gti_wdt_ops, 288 + wdog_dev->info = &gti_wdt_ident; 289 + wdog_dev->ops = &gti_wdt_ops; 290 290 wdog_dev->parent = dev; 291 291 /* 292 292 * Watchdog counter is 24 bit where lower 8 bits are zeros
+1 -1
drivers/watchdog/pm8916_wdt.c
··· 218 218 return err; 219 219 } 220 220 221 - wdt->wdev.ops = &pm8916_wdt_ops, 221 + wdt->wdev.ops = &pm8916_wdt_ops; 222 222 wdt->wdev.parent = dev; 223 223 wdt->wdev.min_timeout = PM8916_WDT_MIN_TIMEOUT; 224 224 wdt->wdev.max_timeout = PM8916_WDT_MAX_TIMEOUT;
+273
drivers/watchdog/rzv2h_wdt.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Renesas RZ/V2H(P) WDT Watchdog Driver 4 + * 5 + * Copyright (C) 2024 Renesas Electronics Corporation. 6 + */ 7 + #include <linux/clk.h> 8 + #include <linux/delay.h> 9 + #include <linux/io.h> 10 + #include <linux/kernel.h> 11 + #include <linux/module.h> 12 + #include <linux/of.h> 13 + #include <linux/platform_device.h> 14 + #include <linux/pm_runtime.h> 15 + #include <linux/reset.h> 16 + #include <linux/units.h> 17 + #include <linux/watchdog.h> 18 + 19 + #define WDTRR 0x00 /* WDT Refresh Register RW, 8 */ 20 + #define WDTCR 0x02 /* WDT Control Register RW, 16 */ 21 + #define WDTSR 0x04 /* WDT Status Register RW, 16 */ 22 + #define WDTRCR 0x06 /* WDT Reset Control Register RW, 8 */ 23 + 24 + #define WDTCR_TOPS_1024 0x00 25 + #define WDTCR_TOPS_16384 0x03 26 + 27 + #define WDTCR_CKS_CLK_1 0x00 28 + #define WDTCR_CKS_CLK_256 0x50 29 + 30 + #define WDTCR_RPES_0 0x300 31 + #define WDTCR_RPES_75 0x000 32 + 33 + #define WDTCR_RPSS_25 0x00 34 + #define WDTCR_RPSS_100 0x3000 35 + 36 + #define WDTRCR_RSTIRQS BIT(7) 37 + 38 + #define MAX_TIMEOUT_CYCLES 16384 39 + #define CLOCK_DIV_BY_256 256 40 + 41 + #define WDT_DEFAULT_TIMEOUT 60U 42 + 43 + static bool nowayout = WATCHDOG_NOWAYOUT; 44 + module_param(nowayout, bool, 0); 45 + MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" 46 + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 47 + 48 + struct rzv2h_wdt_priv { 49 + void __iomem *base; 50 + struct clk *pclk; 51 + struct clk *oscclk; 52 + struct reset_control *rstc; 53 + struct watchdog_device wdev; 54 + }; 55 + 56 + static int rzv2h_wdt_ping(struct watchdog_device *wdev) 57 + { 58 + struct rzv2h_wdt_priv *priv = watchdog_get_drvdata(wdev); 59 + 60 + /* 61 + * The down-counter is refreshed and starts counting operation on 62 + * a write of the values 00h and FFh to the WDTRR register. 63 + */ 64 + writeb(0x0, priv->base + WDTRR); 65 + writeb(0xFF, priv->base + WDTRR); 66 + 67 + return 0; 68 + } 69 + 70 + static void rzv2h_wdt_setup(struct watchdog_device *wdev, u16 wdtcr) 71 + { 72 + struct rzv2h_wdt_priv *priv = watchdog_get_drvdata(wdev); 73 + 74 + /* Configure the timeout, clock division ratio, and window start and end positions. */ 75 + writew(wdtcr, priv->base + WDTCR); 76 + 77 + /* Enable interrupt output to the ICU. */ 78 + writeb(0, priv->base + WDTRCR); 79 + 80 + /* Clear underflow flag and refresh error flag. */ 81 + writew(0, priv->base + WDTSR); 82 + } 83 + 84 + static int rzv2h_wdt_start(struct watchdog_device *wdev) 85 + { 86 + struct rzv2h_wdt_priv *priv = watchdog_get_drvdata(wdev); 87 + int ret; 88 + 89 + ret = pm_runtime_resume_and_get(wdev->parent); 90 + if (ret) 91 + return ret; 92 + 93 + ret = reset_control_deassert(priv->rstc); 94 + if (ret) { 95 + pm_runtime_put(wdev->parent); 96 + return ret; 97 + } 98 + 99 + /* delay to handle clock halt after de-assert operation */ 100 + udelay(3); 101 + 102 + /* 103 + * WDTCR 104 + * - CKS[7:4] - Clock Division Ratio Select - 0101b: oscclk/256 105 + * - RPSS[13:12] - Window Start Position Select - 11b: 100% 106 + * - RPES[9:8] - Window End Position Select - 11b: 0% 107 + * - TOPS[1:0] - Timeout Period Select - 11b: 16384 cycles (3FFFh) 108 + */ 109 + rzv2h_wdt_setup(wdev, WDTCR_CKS_CLK_256 | WDTCR_RPSS_100 | 110 + WDTCR_RPES_0 | WDTCR_TOPS_16384); 111 + 112 + /* 113 + * Down counting starts after writing the sequence 00h -> FFh to the 114 + * WDTRR register. Hence, call the ping operation after loading the counter. 115 + */ 116 + rzv2h_wdt_ping(wdev); 117 + 118 + return 0; 119 + } 120 + 121 + static int rzv2h_wdt_stop(struct watchdog_device *wdev) 122 + { 123 + struct rzv2h_wdt_priv *priv = watchdog_get_drvdata(wdev); 124 + int ret; 125 + 126 + ret = reset_control_assert(priv->rstc); 127 + if (ret) 128 + return ret; 129 + 130 + ret = pm_runtime_put(wdev->parent); 131 + if (ret < 0) 132 + return ret; 133 + 134 + return 0; 135 + } 136 + 137 + static const struct watchdog_info rzv2h_wdt_ident = { 138 + .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT, 139 + .identity = "Renesas RZ/V2H WDT Watchdog", 140 + }; 141 + 142 + static int rzv2h_wdt_restart(struct watchdog_device *wdev, 143 + unsigned long action, void *data) 144 + { 145 + struct rzv2h_wdt_priv *priv = watchdog_get_drvdata(wdev); 146 + int ret; 147 + 148 + if (!watchdog_active(wdev)) { 149 + ret = clk_enable(priv->pclk); 150 + if (ret) 151 + return ret; 152 + 153 + ret = clk_enable(priv->oscclk); 154 + if (ret) { 155 + clk_disable(priv->pclk); 156 + return ret; 157 + } 158 + 159 + ret = reset_control_deassert(priv->rstc); 160 + if (ret) { 161 + clk_disable(priv->oscclk); 162 + clk_disable(priv->pclk); 163 + return ret; 164 + } 165 + } else { 166 + /* 167 + * Writing to the WDT Control Register (WDTCR) or WDT Reset 168 + * Control Register (WDTRCR) is possible once between the 169 + * release from the reset state and the first refresh operation. 170 + * Therefore, issue a reset if the watchdog is active. 171 + */ 172 + ret = reset_control_reset(priv->rstc); 173 + if (ret) 174 + return ret; 175 + } 176 + 177 + /* delay to handle clock halt after de-assert operation */ 178 + udelay(3); 179 + 180 + /* 181 + * WDTCR 182 + * - CKS[7:4] - Clock Division Ratio Select - 0000b: oscclk/1 183 + * - RPSS[13:12] - Window Start Position Select - 00b: 25% 184 + * - RPES[9:8] - Window End Position Select - 00b: 75% 185 + * - TOPS[1:0] - Timeout Period Select - 00b: 1024 cycles (03FFh) 186 + */ 187 + rzv2h_wdt_setup(wdev, WDTCR_CKS_CLK_1 | WDTCR_RPSS_25 | 188 + WDTCR_RPES_75 | WDTCR_TOPS_1024); 189 + 190 + rzv2h_wdt_ping(wdev); 191 + 192 + /* wait for underflow to trigger... */ 193 + udelay(5); 194 + 195 + return 0; 196 + } 197 + 198 + static const struct watchdog_ops rzv2h_wdt_ops = { 199 + .owner = THIS_MODULE, 200 + .start = rzv2h_wdt_start, 201 + .stop = rzv2h_wdt_stop, 202 + .ping = rzv2h_wdt_ping, 203 + .restart = rzv2h_wdt_restart, 204 + }; 205 + 206 + static int rzv2h_wdt_probe(struct platform_device *pdev) 207 + { 208 + struct device *dev = &pdev->dev; 209 + struct rzv2h_wdt_priv *priv; 210 + int ret; 211 + 212 + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 213 + if (!priv) 214 + return -ENOMEM; 215 + 216 + priv->base = devm_platform_ioremap_resource(pdev, 0); 217 + if (IS_ERR(priv->base)) 218 + return PTR_ERR(priv->base); 219 + 220 + priv->pclk = devm_clk_get_prepared(&pdev->dev, "pclk"); 221 + if (IS_ERR(priv->pclk)) 222 + return dev_err_probe(&pdev->dev, PTR_ERR(priv->pclk), "no pclk"); 223 + 224 + priv->oscclk = devm_clk_get_prepared(&pdev->dev, "oscclk"); 225 + if (IS_ERR(priv->oscclk)) 226 + return dev_err_probe(&pdev->dev, PTR_ERR(priv->oscclk), "no oscclk"); 227 + 228 + priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); 229 + if (IS_ERR(priv->rstc)) 230 + return dev_err_probe(&pdev->dev, PTR_ERR(priv->rstc), 231 + "failed to get cpg reset"); 232 + 233 + priv->wdev.max_hw_heartbeat_ms = (MILLI * MAX_TIMEOUT_CYCLES * CLOCK_DIV_BY_256) / 234 + clk_get_rate(priv->oscclk); 235 + dev_dbg(dev, "max hw timeout of %dms\n", priv->wdev.max_hw_heartbeat_ms); 236 + 237 + ret = devm_pm_runtime_enable(&pdev->dev); 238 + if (ret) 239 + return ret; 240 + 241 + priv->wdev.min_timeout = 1; 242 + priv->wdev.timeout = WDT_DEFAULT_TIMEOUT; 243 + priv->wdev.info = &rzv2h_wdt_ident; 244 + priv->wdev.ops = &rzv2h_wdt_ops; 245 + priv->wdev.parent = dev; 246 + watchdog_set_drvdata(&priv->wdev, priv); 247 + watchdog_set_nowayout(&priv->wdev, nowayout); 248 + watchdog_stop_on_unregister(&priv->wdev); 249 + 250 + ret = watchdog_init_timeout(&priv->wdev, 0, dev); 251 + if (ret) 252 + dev_warn(dev, "Specified timeout invalid, using default"); 253 + 254 + return devm_watchdog_register_device(&pdev->dev, &priv->wdev); 255 + } 256 + 257 + static const struct of_device_id rzv2h_wdt_ids[] = { 258 + { .compatible = "renesas,r9a09g057-wdt", }, 259 + { /* sentinel */ } 260 + }; 261 + MODULE_DEVICE_TABLE(of, rzv2h_wdt_ids); 262 + 263 + static struct platform_driver rzv2h_wdt_driver = { 264 + .driver = { 265 + .name = "rzv2h_wdt", 266 + .of_match_table = rzv2h_wdt_ids, 267 + }, 268 + .probe = rzv2h_wdt_probe, 269 + }; 270 + module_platform_driver(rzv2h_wdt_driver); 271 + MODULE_AUTHOR("Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>"); 272 + MODULE_DESCRIPTION("Renesas RZ/V2H(P) WDT Watchdog Driver"); 273 + MODULE_LICENSE("GPL");