hc
2024-05-14 bedbef8ad3e75a304af6361af235302bcc61d06b
kernel/drivers/watchdog/asm9260_wdt.c
....@@ -1,9 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Watchdog driver for Alphascale ASM9260.
34 *
45 * Copyright (c) 2014 Oleksij Rempel <linux@rempel-privat.de>
5
- *
6
- * Licensed under GPLv2 or later.
76 */
87
98 #include <linux/bitops.h>
....@@ -196,6 +195,11 @@
196195 .restart = asm9260_restart,
197196 };
198197
198
+static void asm9260_clk_disable_unprepare(void *data)
199
+{
200
+ clk_disable_unprepare(data);
201
+}
202
+
199203 static int asm9260_wdt_get_dt_clks(struct asm9260_wdt_priv *priv)
200204 {
201205 int err;
....@@ -219,26 +223,32 @@
219223 dev_err(priv->dev, "Failed to enable ahb_clk!\n");
220224 return err;
221225 }
226
+ err = devm_add_action_or_reset(priv->dev,
227
+ asm9260_clk_disable_unprepare,
228
+ priv->clk_ahb);
229
+ if (err)
230
+ return err;
222231
223232 err = clk_set_rate(priv->clk, CLOCK_FREQ);
224233 if (err) {
225
- clk_disable_unprepare(priv->clk_ahb);
226234 dev_err(priv->dev, "Failed to set rate!\n");
227235 return err;
228236 }
229237
230238 err = clk_prepare_enable(priv->clk);
231239 if (err) {
232
- clk_disable_unprepare(priv->clk_ahb);
233240 dev_err(priv->dev, "Failed to enable clk!\n");
234241 return err;
235242 }
243
+ err = devm_add_action_or_reset(priv->dev,
244
+ asm9260_clk_disable_unprepare,
245
+ priv->clk);
246
+ if (err)
247
+ return err;
236248
237249 /* wdt has internal divider */
238250 clk = clk_get_rate(priv->clk);
239251 if (!clk) {
240
- clk_disable_unprepare(priv->clk);
241
- clk_disable_unprepare(priv->clk_ahb);
242252 dev_err(priv->dev, "Failed, clk is 0!\n");
243253 return -EINVAL;
244254 }
....@@ -274,25 +284,23 @@
274284
275285 static int asm9260_wdt_probe(struct platform_device *pdev)
276286 {
287
+ struct device *dev = &pdev->dev;
277288 struct asm9260_wdt_priv *priv;
278289 struct watchdog_device *wdd;
279
- struct resource *res;
280290 int ret;
281
- const char * const mode_name[] = { "hw", "sw", "debug", };
291
+ static const char * const mode_name[] = { "hw", "sw", "debug", };
282292
283
- priv = devm_kzalloc(&pdev->dev, sizeof(struct asm9260_wdt_priv),
284
- GFP_KERNEL);
293
+ priv = devm_kzalloc(dev, sizeof(struct asm9260_wdt_priv), GFP_KERNEL);
285294 if (!priv)
286295 return -ENOMEM;
287296
288
- priv->dev = &pdev->dev;
297
+ priv->dev = dev;
289298
290
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
291
- priv->iobase = devm_ioremap_resource(&pdev->dev, res);
299
+ priv->iobase = devm_platform_ioremap_resource(pdev, 0);
292300 if (IS_ERR(priv->iobase))
293301 return PTR_ERR(priv->iobase);
294302
295
- priv->rst = devm_reset_control_get_exclusive(&pdev->dev, "wdt_rst");
303
+ priv->rst = devm_reset_control_get_exclusive(dev, "wdt_rst");
296304 if (IS_ERR(priv->rst))
297305 return PTR_ERR(priv->rst);
298306
....@@ -305,7 +313,7 @@
305313 wdd->ops = &asm9260_wdt_ops;
306314 wdd->min_timeout = 1;
307315 wdd->max_timeout = BM_WDTC_MAX(priv->wdt_freq);
308
- wdd->parent = &pdev->dev;
316
+ wdd->parent = dev;
309317
310318 watchdog_set_drvdata(wdd, priv);
311319
....@@ -315,7 +323,7 @@
315323 * the max instead.
316324 */
317325 wdd->timeout = ASM9260_WDT_DEFAULT_TIMEOUT;
318
- watchdog_init_timeout(wdd, 0, &pdev->dev);
326
+ watchdog_init_timeout(wdd, 0, dev);
319327
320328 asm9260_wdt_get_dt_mode(priv);
321329
....@@ -327,48 +335,24 @@
327335 * Not all supported platforms specify an interrupt for the
328336 * watchdog, so let's make it optional.
329337 */
330
- ret = devm_request_irq(&pdev->dev, priv->irq,
331
- asm9260_wdt_irq, 0, pdev->name, priv);
338
+ ret = devm_request_irq(dev, priv->irq, asm9260_wdt_irq, 0,
339
+ pdev->name, priv);
332340 if (ret < 0)
333
- dev_warn(&pdev->dev, "failed to request IRQ\n");
341
+ dev_warn(dev, "failed to request IRQ\n");
334342 }
335343
336344 watchdog_set_restart_priority(wdd, 128);
337345
338
- ret = watchdog_register_device(wdd);
346
+ watchdog_stop_on_reboot(wdd);
347
+ watchdog_stop_on_unregister(wdd);
348
+ ret = devm_watchdog_register_device(dev, wdd);
339349 if (ret)
340
- goto clk_off;
350
+ return ret;
341351
342352 platform_set_drvdata(pdev, priv);
343353
344
- dev_info(&pdev->dev, "Watchdog enabled (timeout: %d sec, mode: %s)\n",
354
+ dev_info(dev, "Watchdog enabled (timeout: %d sec, mode: %s)\n",
345355 wdd->timeout, mode_name[priv->mode]);
346
- return 0;
347
-
348
-clk_off:
349
- clk_disable_unprepare(priv->clk);
350
- clk_disable_unprepare(priv->clk_ahb);
351
- return ret;
352
-}
353
-
354
-static void asm9260_wdt_shutdown(struct platform_device *pdev)
355
-{
356
- struct asm9260_wdt_priv *priv = platform_get_drvdata(pdev);
357
-
358
- asm9260_wdt_disable(&priv->wdd);
359
-}
360
-
361
-static int asm9260_wdt_remove(struct platform_device *pdev)
362
-{
363
- struct asm9260_wdt_priv *priv = platform_get_drvdata(pdev);
364
-
365
- asm9260_wdt_disable(&priv->wdd);
366
-
367
- watchdog_unregister_device(&priv->wdd);
368
-
369
- clk_disable_unprepare(priv->clk);
370
- clk_disable_unprepare(priv->clk_ahb);
371
-
372356 return 0;
373357 }
374358
....@@ -384,8 +368,6 @@
384368 .of_match_table = asm9260_wdt_of_match,
385369 },
386370 .probe = asm9260_wdt_probe,
387
- .remove = asm9260_wdt_remove,
388
- .shutdown = asm9260_wdt_shutdown,
389371 };
390372 module_platform_driver(asm9260_wdt_driver);
391373