hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/watchdog/imgpdc_wdt.c
....@@ -1,11 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Imagination Technologies PowerDown Controller Watchdog Timer.
34 *
45 * Copyright (c) 2014 Imagination Technologies Ltd.
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 * Based on drivers/watchdog/sunxi_wdt.c Copyright (c) 2013 Carlo Caione
118 * 2012 Henrik Nordstrom
....@@ -178,59 +175,69 @@
178175 .restart = pdc_wdt_restart,
179176 };
180177
178
+static void pdc_clk_disable_unprepare(void *data)
179
+{
180
+ clk_disable_unprepare(data);
181
+}
182
+
181183 static int pdc_wdt_probe(struct platform_device *pdev)
182184 {
185
+ struct device *dev = &pdev->dev;
183186 u64 div;
184187 int ret, val;
185188 unsigned long clk_rate;
186
- struct resource *res;
187189 struct pdc_wdt_dev *pdc_wdt;
188190
189
- pdc_wdt = devm_kzalloc(&pdev->dev, sizeof(*pdc_wdt), GFP_KERNEL);
191
+ pdc_wdt = devm_kzalloc(dev, sizeof(*pdc_wdt), GFP_KERNEL);
190192 if (!pdc_wdt)
191193 return -ENOMEM;
192194
193
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
194
- pdc_wdt->base = devm_ioremap_resource(&pdev->dev, res);
195
+ pdc_wdt->base = devm_platform_ioremap_resource(pdev, 0);
195196 if (IS_ERR(pdc_wdt->base))
196197 return PTR_ERR(pdc_wdt->base);
197198
198
- pdc_wdt->sys_clk = devm_clk_get(&pdev->dev, "sys");
199
+ pdc_wdt->sys_clk = devm_clk_get(dev, "sys");
199200 if (IS_ERR(pdc_wdt->sys_clk)) {
200
- dev_err(&pdev->dev, "failed to get the sys clock\n");
201
+ dev_err(dev, "failed to get the sys clock\n");
201202 return PTR_ERR(pdc_wdt->sys_clk);
202203 }
203204
204
- pdc_wdt->wdt_clk = devm_clk_get(&pdev->dev, "wdt");
205
+ pdc_wdt->wdt_clk = devm_clk_get(dev, "wdt");
205206 if (IS_ERR(pdc_wdt->wdt_clk)) {
206
- dev_err(&pdev->dev, "failed to get the wdt clock\n");
207
+ dev_err(dev, "failed to get the wdt clock\n");
207208 return PTR_ERR(pdc_wdt->wdt_clk);
208209 }
209210
210211 ret = clk_prepare_enable(pdc_wdt->sys_clk);
211212 if (ret) {
212
- dev_err(&pdev->dev, "could not prepare or enable sys clock\n");
213
+ dev_err(dev, "could not prepare or enable sys clock\n");
213214 return ret;
214215 }
216
+ ret = devm_add_action_or_reset(dev, pdc_clk_disable_unprepare,
217
+ pdc_wdt->sys_clk);
218
+ if (ret)
219
+ return ret;
215220
216221 ret = clk_prepare_enable(pdc_wdt->wdt_clk);
217222 if (ret) {
218
- dev_err(&pdev->dev, "could not prepare or enable wdt clock\n");
219
- goto disable_sys_clk;
223
+ dev_err(dev, "could not prepare or enable wdt clock\n");
224
+ return ret;
220225 }
226
+ ret = devm_add_action_or_reset(dev, pdc_clk_disable_unprepare,
227
+ pdc_wdt->wdt_clk);
228
+ if (ret)
229
+ return ret;
221230
222231 /* We use the clock rate to calculate the max timeout */
223232 clk_rate = clk_get_rate(pdc_wdt->wdt_clk);
224233 if (clk_rate == 0) {
225
- dev_err(&pdev->dev, "failed to get clock rate\n");
226
- ret = -EINVAL;
227
- goto disable_wdt_clk;
234
+ dev_err(dev, "failed to get clock rate\n");
235
+ return -EINVAL;
228236 }
229237
230238 if (order_base_2(clk_rate) > PDC_WDT_CONFIG_DELAY_MASK + 1) {
231
- dev_err(&pdev->dev, "invalid clock rate\n");
232
- ret = -EINVAL;
233
- goto disable_wdt_clk;
239
+ dev_err(dev, "invalid clock rate\n");
240
+ return -EINVAL;
234241 }
235242
236243 if (order_base_2(clk_rate) == 0)
....@@ -245,10 +252,10 @@
245252 do_div(div, clk_rate);
246253 pdc_wdt->wdt_dev.max_timeout = div;
247254 pdc_wdt->wdt_dev.timeout = PDC_WDT_DEF_TIMEOUT;
248
- pdc_wdt->wdt_dev.parent = &pdev->dev;
255
+ pdc_wdt->wdt_dev.parent = dev;
249256 watchdog_set_drvdata(&pdc_wdt->wdt_dev, pdc_wdt);
250257
251
- watchdog_init_timeout(&pdc_wdt->wdt_dev, heartbeat, &pdev->dev);
258
+ watchdog_init_timeout(&pdc_wdt->wdt_dev, heartbeat, dev);
252259
253260 pdc_wdt_stop(&pdc_wdt->wdt_dev);
254261
....@@ -259,24 +266,22 @@
259266 case PDC_WDT_TICKLE_STATUS_TICKLE:
260267 case PDC_WDT_TICKLE_STATUS_TIMEOUT:
261268 pdc_wdt->wdt_dev.bootstatus |= WDIOF_CARDRESET;
262
- dev_info(&pdev->dev,
263
- "watchdog module last reset due to timeout\n");
269
+ dev_info(dev, "watchdog module last reset due to timeout\n");
264270 break;
265271 case PDC_WDT_TICKLE_STATUS_HRESET:
266
- dev_info(&pdev->dev,
272
+ dev_info(dev,
267273 "watchdog module last reset due to hard reset\n");
268274 break;
269275 case PDC_WDT_TICKLE_STATUS_SRESET:
270
- dev_info(&pdev->dev,
276
+ dev_info(dev,
271277 "watchdog module last reset due to soft reset\n");
272278 break;
273279 case PDC_WDT_TICKLE_STATUS_USER:
274
- dev_info(&pdev->dev,
280
+ dev_info(dev,
275281 "watchdog module last reset due to user reset\n");
276282 break;
277283 default:
278
- dev_info(&pdev->dev,
279
- "contains an illegal status code (%08x)\n", val);
284
+ dev_info(dev, "contains an illegal status code (%08x)\n", val);
280285 break;
281286 }
282287
....@@ -285,36 +290,9 @@
285290
286291 platform_set_drvdata(pdev, pdc_wdt);
287292
288
- ret = watchdog_register_device(&pdc_wdt->wdt_dev);
289
- if (ret)
290
- goto disable_wdt_clk;
291
-
292
- return 0;
293
-
294
-disable_wdt_clk:
295
- clk_disable_unprepare(pdc_wdt->wdt_clk);
296
-disable_sys_clk:
297
- clk_disable_unprepare(pdc_wdt->sys_clk);
298
- return ret;
299
-}
300
-
301
-static void pdc_wdt_shutdown(struct platform_device *pdev)
302
-{
303
- struct pdc_wdt_dev *pdc_wdt = platform_get_drvdata(pdev);
304
-
305
- pdc_wdt_stop(&pdc_wdt->wdt_dev);
306
-}
307
-
308
-static int pdc_wdt_remove(struct platform_device *pdev)
309
-{
310
- struct pdc_wdt_dev *pdc_wdt = platform_get_drvdata(pdev);
311
-
312
- pdc_wdt_stop(&pdc_wdt->wdt_dev);
313
- watchdog_unregister_device(&pdc_wdt->wdt_dev);
314
- clk_disable_unprepare(pdc_wdt->wdt_clk);
315
- clk_disable_unprepare(pdc_wdt->sys_clk);
316
-
317
- return 0;
293
+ watchdog_stop_on_reboot(&pdc_wdt->wdt_dev);
294
+ watchdog_stop_on_unregister(&pdc_wdt->wdt_dev);
295
+ return devm_watchdog_register_device(dev, &pdc_wdt->wdt_dev);
318296 }
319297
320298 static const struct of_device_id pdc_wdt_match[] = {
....@@ -329,8 +307,6 @@
329307 .of_match_table = pdc_wdt_match,
330308 },
331309 .probe = pdc_wdt_probe,
332
- .remove = pdc_wdt_remove,
333
- .shutdown = pdc_wdt_shutdown,
334310 };
335311 module_platform_driver(pdc_wdt_driver);
336312