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.11-rc1' of git://www.linux-watchdog.org/linux-watchdog

Pull watchdog updates from Wim Van Sebroeck:

- make watchdog_class const

- rework of the rzg2l_wdt driver

- other small fixes and improvements

* tag 'linux-watchdog-6.11-rc1' of git://www.linux-watchdog.org/linux-watchdog:
dt-bindings: watchdog: dlg,da9062-watchdog: Drop blank space
watchdog: rzn1: Convert comma to semicolon
watchdog: lenovo_se10_wdt: Convert comma to semicolon
dt-bindings: watchdog: renesas,wdt: Document RZ/G3S support
watchdog: rzg2l_wdt: Add suspend/resume support
watchdog: rzg2l_wdt: Rely on the reset driver for doing proper reset
watchdog: rzg2l_wdt: Remove comparison with zero
watchdog: rzg2l_wdt: Remove reset de-assert from probe
watchdog: rzg2l_wdt: Check return status of pm_runtime_put()
watchdog: rzg2l_wdt: Use pm_runtime_resume_and_get()
watchdog: rzg2l_wdt: Make the driver depend on PM
watchdog: rzg2l_wdt: Restrict the driver to ARCH_RZG2L and ARCH_R9A09G011
watchdog: imx7ulp_wdt: keep already running watchdog enabled
watchdog: starfive: Add missing clk_disable_unprepare()
watchdog: Make watchdog_class const

+81 -59
+1 -1
Documentation/devicetree/bindings/watchdog/dlg,da9062-watchdog.yaml
··· 28 28 Add this property to disable the watchdog during suspend. 29 29 Only use this option if you can't use the watchdog automatic suspend 30 30 function during a suspend (see register CONTROL_B). 31 - 31 + 32 32 dlg,wdt-sd: 33 33 $ref: /schemas/types.yaml#/definitions/uint32 34 34 enum: [0, 1]
+1
Documentation/devicetree/bindings/watchdog/renesas,wdt.yaml
··· 29 29 - renesas,r9a07g043-wdt # RZ/G2UL and RZ/Five 30 30 - renesas,r9a07g044-wdt # RZ/G2{L,LC} 31 31 - renesas,r9a07g054-wdt # RZ/V2L 32 + - renesas,r9a08g045-wdt # RZ/G3S 32 33 - const: renesas,rzg2l-wdt 33 34 34 35 - items:
+2 -1
drivers/watchdog/Kconfig
··· 946 946 947 947 config RENESAS_RZG2LWDT 948 948 tristate "Renesas RZ/G2L WDT Watchdog" 949 - depends on ARCH_RENESAS || COMPILE_TEST 949 + depends on ARCH_RZG2L || ARCH_R9A09G011 || COMPILE_TEST 950 + depends on PM || COMPILE_TEST 950 951 select WATCHDOG_CORE 951 952 help 952 953 This driver adds watchdog support for the integrated watchdogs in the
+5
drivers/watchdog/imx7ulp_wdt.c
··· 290 290 if (wdt->ext_reset) 291 291 val |= WDOG_CS_INT_EN; 292 292 293 + if (readl(wdt->base + WDOG_CS) & WDOG_CS_EN) { 294 + set_bit(WDOG_HW_RUNNING, &wdt->wdd.status); 295 + val |= WDOG_CS_EN; 296 + } 297 + 293 298 do { 294 299 ret = _imx7ulp_wdt_init(wdt, timeout, val); 295 300 toval = readl(wdt->base + WDOG_TOVAL);
+2 -2
drivers/watchdog/lenovo_se10_wdt.c
··· 196 196 watchdog_set_drvdata(&priv->wdd, priv); 197 197 198 198 priv->wdd.parent = dev; 199 - priv->wdd.info = &wdt_info, 200 - priv->wdd.ops = &se10_wdt_ops, 199 + priv->wdd.info = &wdt_info; 200 + priv->wdd.ops = &se10_wdt_ops; 201 201 priv->wdd.timeout = WATCHDOG_TIMEOUT; /* Set default timeout */ 202 202 priv->wdd.min_timeout = MIN_TIMEOUT; 203 203 priv->wdd.max_timeout = MAX_TIMEOUT;
+63 -50
drivers/watchdog/rzg2l_wdt.c
··· 8 8 #include <linux/clk.h> 9 9 #include <linux/delay.h> 10 10 #include <linux/io.h> 11 - #include <linux/iopoll.h> 12 11 #include <linux/kernel.h> 13 12 #include <linux/module.h> 14 13 #include <linux/of.h> ··· 53 54 struct reset_control *rstc; 54 55 unsigned long osc_clk_rate; 55 56 unsigned long delay; 56 - unsigned long minimum_assertion_period; 57 57 struct clk *pclk; 58 58 struct clk *osc_clk; 59 59 enum rz_wdt_type devtype; 60 60 }; 61 - 62 - static int rzg2l_wdt_reset(struct rzg2l_wdt_priv *priv) 63 - { 64 - int err, status; 65 - 66 - if (priv->devtype == WDT_RZV2M) { 67 - /* WDT needs TYPE-B reset control */ 68 - err = reset_control_assert(priv->rstc); 69 - if (err) 70 - return err; 71 - ndelay(priv->minimum_assertion_period); 72 - err = reset_control_deassert(priv->rstc); 73 - if (err) 74 - return err; 75 - err = read_poll_timeout(reset_control_status, status, 76 - status != 1, 0, 1000, false, 77 - priv->rstc); 78 - } else { 79 - err = reset_control_reset(priv->rstc); 80 - } 81 - 82 - return err; 83 - } 84 61 85 62 static void rzg2l_wdt_wait_delay(struct rzg2l_wdt_priv *priv) 86 63 { ··· 98 123 static int rzg2l_wdt_start(struct watchdog_device *wdev) 99 124 { 100 125 struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev); 126 + int ret; 101 127 102 - pm_runtime_get_sync(wdev->parent); 128 + ret = pm_runtime_resume_and_get(wdev->parent); 129 + if (ret) 130 + return ret; 131 + 132 + ret = reset_control_deassert(priv->rstc); 133 + if (ret) { 134 + pm_runtime_put(wdev->parent); 135 + return ret; 136 + } 103 137 104 138 /* Initialize time out */ 105 139 rzg2l_wdt_init_timeout(wdev); ··· 125 141 static int rzg2l_wdt_stop(struct watchdog_device *wdev) 126 142 { 127 143 struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev); 144 + int ret; 128 145 129 - rzg2l_wdt_reset(priv); 130 - pm_runtime_put(wdev->parent); 146 + ret = reset_control_assert(priv->rstc); 147 + if (ret) 148 + return ret; 149 + 150 + ret = pm_runtime_put(wdev->parent); 151 + if (ret < 0) 152 + return ret; 131 153 132 154 return 0; 133 155 } 134 156 135 157 static int rzg2l_wdt_set_timeout(struct watchdog_device *wdev, unsigned int timeout) 136 158 { 159 + int ret = 0; 160 + 137 161 wdev->timeout = timeout; 138 162 139 163 /* ··· 150 158 * to reset the module) so that it is updated with new timeout values. 151 159 */ 152 160 if (watchdog_active(wdev)) { 153 - rzg2l_wdt_stop(wdev); 154 - rzg2l_wdt_start(wdev); 161 + ret = rzg2l_wdt_stop(wdev); 162 + if (ret) 163 + return ret; 164 + 165 + ret = rzg2l_wdt_start(wdev); 155 166 } 156 167 157 - return 0; 168 + return ret; 158 169 } 159 170 160 171 static int rzg2l_wdt_restart(struct watchdog_device *wdev, 161 172 unsigned long action, void *data) 162 173 { 163 174 struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev); 175 + int ret; 164 176 165 177 clk_prepare_enable(priv->pclk); 166 178 clk_prepare_enable(priv->osc_clk); 167 179 168 180 if (priv->devtype == WDT_RZG2L) { 181 + ret = reset_control_deassert(priv->rstc); 182 + if (ret) 183 + return ret; 184 + 169 185 /* Generate Reset (WDTRSTB) Signal on parity error */ 170 186 rzg2l_wdt_write(priv, 0, PECR); 171 187 ··· 181 181 rzg2l_wdt_write(priv, PEEN_FORCE, PEEN); 182 182 } else { 183 183 /* RZ/V2M doesn't have parity error registers */ 184 - rzg2l_wdt_reset(priv); 184 + ret = reset_control_reset(priv->rstc); 185 + if (ret) 186 + return ret; 185 187 186 188 wdev->timeout = 0; 187 189 ··· 226 224 .restart = rzg2l_wdt_restart, 227 225 }; 228 226 229 - static void rzg2l_wdt_reset_assert_pm_disable(void *data) 227 + static void rzg2l_wdt_pm_disable(void *data) 230 228 { 231 229 struct watchdog_device *wdev = data; 232 - struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev); 233 230 234 231 pm_runtime_disable(wdev->parent); 235 - reset_control_assert(priv->rstc); 236 232 } 237 233 238 234 static int rzg2l_wdt_probe(struct platform_device *pdev) ··· 273 273 return dev_err_probe(&pdev->dev, PTR_ERR(priv->rstc), 274 274 "failed to get cpg reset"); 275 275 276 - ret = reset_control_deassert(priv->rstc); 277 - if (ret) 278 - return dev_err_probe(dev, ret, "failed to deassert"); 279 - 280 276 priv->devtype = (uintptr_t)of_device_get_match_data(dev); 281 - 282 - if (priv->devtype == WDT_RZV2M) { 283 - priv->minimum_assertion_period = RZV2M_A_NSEC + 284 - 3 * F2CYCLE_NSEC(pclk_rate) + 5 * 285 - max(F2CYCLE_NSEC(priv->osc_clk_rate), 286 - F2CYCLE_NSEC(pclk_rate)); 287 - } 288 277 289 278 pm_runtime_enable(&pdev->dev); 290 279 ··· 286 297 priv->wdev.timeout = WDT_DEFAULT_TIMEOUT; 287 298 288 299 watchdog_set_drvdata(&priv->wdev, priv); 289 - ret = devm_add_action_or_reset(&pdev->dev, 290 - rzg2l_wdt_reset_assert_pm_disable, 291 - &priv->wdev); 292 - if (ret < 0) 300 + dev_set_drvdata(dev, priv); 301 + ret = devm_add_action_or_reset(&pdev->dev, rzg2l_wdt_pm_disable, &priv->wdev); 302 + if (ret) 293 303 return ret; 294 304 295 305 watchdog_set_nowayout(&priv->wdev, nowayout); ··· 308 320 }; 309 321 MODULE_DEVICE_TABLE(of, rzg2l_wdt_ids); 310 322 323 + static int rzg2l_wdt_suspend_late(struct device *dev) 324 + { 325 + struct rzg2l_wdt_priv *priv = dev_get_drvdata(dev); 326 + 327 + if (!watchdog_active(&priv->wdev)) 328 + return 0; 329 + 330 + return rzg2l_wdt_stop(&priv->wdev); 331 + } 332 + 333 + static int rzg2l_wdt_resume_early(struct device *dev) 334 + { 335 + struct rzg2l_wdt_priv *priv = dev_get_drvdata(dev); 336 + 337 + if (!watchdog_active(&priv->wdev)) 338 + return 0; 339 + 340 + return rzg2l_wdt_start(&priv->wdev); 341 + } 342 + 343 + static const struct dev_pm_ops rzg2l_wdt_pm_ops = { 344 + LATE_SYSTEM_SLEEP_PM_OPS(rzg2l_wdt_suspend_late, rzg2l_wdt_resume_early) 345 + }; 346 + 311 347 static struct platform_driver rzg2l_wdt_driver = { 312 348 .driver = { 313 349 .name = "rzg2l_wdt", 314 350 .of_match_table = rzg2l_wdt_ids, 351 + .pm = &rzg2l_wdt_pm_ops, 315 352 }, 316 353 .probe = rzg2l_wdt_probe, 317 354 };
+3 -3
drivers/watchdog/rzn1_wdt.c
··· 140 140 } 141 141 142 142 wdt->clk_rate_khz = clk_rate / 1000; 143 - wdt->wdtdev.info = &rzn1_wdt_info, 144 - wdt->wdtdev.ops = &rzn1_wdt_ops, 145 - wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS, 143 + wdt->wdtdev.info = &rzn1_wdt_info; 144 + wdt->wdtdev.ops = &rzn1_wdt_ops; 145 + wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS; 146 146 wdt->wdtdev.parent = dev; 147 147 /* 148 148 * The period of the watchdog cannot be changed once set
+3 -1
drivers/watchdog/starfive-wdt.c
··· 152 152 return dev_err_probe(wdt->wdd.parent, ret, "failed to enable apb clock\n"); 153 153 154 154 ret = clk_prepare_enable(wdt->core_clk); 155 - if (ret) 155 + if (ret) { 156 + clk_disable_unprepare(wdt->apb_clk); 156 157 return dev_err_probe(wdt->wdd.parent, ret, "failed to enable core clock\n"); 158 + } 157 159 158 160 return 0; 159 161 }
+1 -1
drivers/watchdog/watchdog_dev.c
··· 1004 1004 .fops = &watchdog_fops, 1005 1005 }; 1006 1006 1007 - static struct class watchdog_class = { 1007 + static const struct class watchdog_class = { 1008 1008 .name = "watchdog", 1009 1009 .dev_groups = wdt_groups, 1010 1010 };