hc
2024-05-14 bedbef8ad3e75a304af6361af235302bcc61d06b
kernel/drivers/watchdog/lpc18xx_wdt.c
....@@ -1,11 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * NXP LPC18xx Watchdog Timer (WDT)
34 *
45 * Copyright (c) 2015 Ariel D'Alessandro <ariel@vanguardiasur.com>
5
- *
6
- * This program is free software; you can redistribute it and/or modify it
7
- * under the terms of the GNU General Public License version 2 as published by
8
- * the Free Software Foundation.
96 *
107 * Notes
118 * -----
....@@ -200,19 +197,22 @@
200197 .restart = lpc18xx_wdt_restart,
201198 };
202199
200
+static void lpc18xx_clk_disable_unprepare(void *data)
201
+{
202
+ clk_disable_unprepare(data);
203
+}
204
+
203205 static int lpc18xx_wdt_probe(struct platform_device *pdev)
204206 {
205207 struct lpc18xx_wdt_dev *lpc18xx_wdt;
206208 struct device *dev = &pdev->dev;
207
- struct resource *res;
208209 int ret;
209210
210211 lpc18xx_wdt = devm_kzalloc(dev, sizeof(*lpc18xx_wdt), GFP_KERNEL);
211212 if (!lpc18xx_wdt)
212213 return -ENOMEM;
213214
214
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
215
- lpc18xx_wdt->base = devm_ioremap_resource(dev, res);
215
+ lpc18xx_wdt->base = devm_platform_ioremap_resource(pdev, 0);
216216 if (IS_ERR(lpc18xx_wdt->base))
217217 return PTR_ERR(lpc18xx_wdt->base);
218218
....@@ -233,19 +233,26 @@
233233 dev_err(dev, "could not prepare or enable sys clock\n");
234234 return ret;
235235 }
236
+ ret = devm_add_action_or_reset(dev, lpc18xx_clk_disable_unprepare,
237
+ lpc18xx_wdt->reg_clk);
238
+ if (ret)
239
+ return ret;
236240
237241 ret = clk_prepare_enable(lpc18xx_wdt->wdt_clk);
238242 if (ret) {
239243 dev_err(dev, "could not prepare or enable wdt clock\n");
240
- goto disable_reg_clk;
244
+ return ret;
241245 }
246
+ ret = devm_add_action_or_reset(dev, lpc18xx_clk_disable_unprepare,
247
+ lpc18xx_wdt->wdt_clk);
248
+ if (ret)
249
+ return ret;
242250
243251 /* We use the clock rate to calculate timeouts */
244252 lpc18xx_wdt->clk_rate = clk_get_rate(lpc18xx_wdt->wdt_clk);
245253 if (lpc18xx_wdt->clk_rate == 0) {
246254 dev_err(dev, "failed to get clock rate\n");
247
- ret = -EINVAL;
248
- goto disable_wdt_clk;
255
+ return -EINVAL;
249256 }
250257
251258 lpc18xx_wdt->wdt_dev.info = &lpc18xx_wdt_info;
....@@ -276,24 +283,8 @@
276283
277284 platform_set_drvdata(pdev, lpc18xx_wdt);
278285
279
- ret = watchdog_register_device(&lpc18xx_wdt->wdt_dev);
280
- if (ret)
281
- goto disable_wdt_clk;
282
-
283
- return 0;
284
-
285
-disable_wdt_clk:
286
- clk_disable_unprepare(lpc18xx_wdt->wdt_clk);
287
-disable_reg_clk:
288
- clk_disable_unprepare(lpc18xx_wdt->reg_clk);
289
- return ret;
290
-}
291
-
292
-static void lpc18xx_wdt_shutdown(struct platform_device *pdev)
293
-{
294
- struct lpc18xx_wdt_dev *lpc18xx_wdt = platform_get_drvdata(pdev);
295
-
296
- lpc18xx_wdt_stop(&lpc18xx_wdt->wdt_dev);
286
+ watchdog_stop_on_reboot(&lpc18xx_wdt->wdt_dev);
287
+ return devm_watchdog_register_device(dev, &lpc18xx_wdt->wdt_dev);
297288 }
298289
299290 static int lpc18xx_wdt_remove(struct platform_device *pdev)
....@@ -302,10 +293,6 @@
302293
303294 dev_warn(&pdev->dev, "I quit now, hardware will probably reboot!\n");
304295 del_timer_sync(&lpc18xx_wdt->timer);
305
-
306
- watchdog_unregister_device(&lpc18xx_wdt->wdt_dev);
307
- clk_disable_unprepare(lpc18xx_wdt->wdt_clk);
308
- clk_disable_unprepare(lpc18xx_wdt->reg_clk);
309296
310297 return 0;
311298 }
....@@ -323,7 +310,6 @@
323310 },
324311 .probe = lpc18xx_wdt_probe,
325312 .remove = lpc18xx_wdt_remove,
326
- .shutdown = lpc18xx_wdt_shutdown,
327313 };
328314 module_platform_driver(lpc18xx_wdt_driver);
329315