.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
---|
1 | 2 | /* |
---|
2 | 3 | * drivers/char/watchdog/pnx4008_wdt.c |
---|
3 | 4 | * |
---|
.. | .. |
---|
11 | 12 | * 2005-2006 (c) MontaVista Software, Inc. |
---|
12 | 13 | * |
---|
13 | 14 | * (C) 2012 Wolfram Sang, Pengutronix |
---|
14 | | - * |
---|
15 | | - * This file is licensed under the terms of the GNU General Public License |
---|
16 | | - * version 2. This program is licensed "as is" without any warranty of any |
---|
17 | | - * kind, whether express or implied. |
---|
18 | 15 | */ |
---|
19 | 16 | |
---|
20 | 17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
---|
.. | .. |
---|
33 | 30 | #include <linux/of.h> |
---|
34 | 31 | #include <linux/delay.h> |
---|
35 | 32 | #include <linux/reboot.h> |
---|
36 | | -#include <mach/hardware.h> |
---|
37 | 33 | |
---|
38 | 34 | /* WatchDog Timer - Chapter 23 Page 207 */ |
---|
39 | 35 | |
---|
.. | .. |
---|
183 | 179 | .max_timeout = MAX_HEARTBEAT, |
---|
184 | 180 | }; |
---|
185 | 181 | |
---|
| 182 | +static void pnx4008_clk_disable_unprepare(void *data) |
---|
| 183 | +{ |
---|
| 184 | + clk_disable_unprepare(data); |
---|
| 185 | +} |
---|
| 186 | + |
---|
186 | 187 | static int pnx4008_wdt_probe(struct platform_device *pdev) |
---|
187 | 188 | { |
---|
188 | | - struct resource *r; |
---|
| 189 | + struct device *dev = &pdev->dev; |
---|
189 | 190 | int ret = 0; |
---|
190 | 191 | |
---|
191 | | - watchdog_init_timeout(&pnx4008_wdd, heartbeat, &pdev->dev); |
---|
| 192 | + watchdog_init_timeout(&pnx4008_wdd, heartbeat, dev); |
---|
192 | 193 | |
---|
193 | | - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
194 | | - wdt_base = devm_ioremap_resource(&pdev->dev, r); |
---|
| 194 | + wdt_base = devm_platform_ioremap_resource(pdev, 0); |
---|
195 | 195 | if (IS_ERR(wdt_base)) |
---|
196 | 196 | return PTR_ERR(wdt_base); |
---|
197 | 197 | |
---|
198 | | - wdt_clk = devm_clk_get(&pdev->dev, NULL); |
---|
| 198 | + wdt_clk = devm_clk_get(dev, NULL); |
---|
199 | 199 | if (IS_ERR(wdt_clk)) |
---|
200 | 200 | return PTR_ERR(wdt_clk); |
---|
201 | 201 | |
---|
202 | 202 | ret = clk_prepare_enable(wdt_clk); |
---|
203 | 203 | if (ret) |
---|
204 | 204 | return ret; |
---|
| 205 | + ret = devm_add_action_or_reset(dev, pnx4008_clk_disable_unprepare, |
---|
| 206 | + wdt_clk); |
---|
| 207 | + if (ret) |
---|
| 208 | + return ret; |
---|
205 | 209 | |
---|
206 | 210 | pnx4008_wdd.bootstatus = (readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ? |
---|
207 | 211 | WDIOF_CARDRESET : 0; |
---|
208 | | - pnx4008_wdd.parent = &pdev->dev; |
---|
| 212 | + pnx4008_wdd.parent = dev; |
---|
209 | 213 | watchdog_set_nowayout(&pnx4008_wdd, nowayout); |
---|
210 | 214 | watchdog_set_restart_priority(&pnx4008_wdd, 128); |
---|
211 | 215 | |
---|
212 | | - pnx4008_wdt_stop(&pnx4008_wdd); /* disable for now */ |
---|
| 216 | + if (readl(WDTIM_CTRL(wdt_base)) & COUNT_ENAB) |
---|
| 217 | + set_bit(WDOG_HW_RUNNING, &pnx4008_wdd.status); |
---|
213 | 218 | |
---|
214 | | - ret = watchdog_register_device(&pnx4008_wdd); |
---|
215 | | - if (ret < 0) { |
---|
216 | | - dev_err(&pdev->dev, "cannot register watchdog device\n"); |
---|
217 | | - goto disable_clk; |
---|
218 | | - } |
---|
| 219 | + ret = devm_watchdog_register_device(dev, &pnx4008_wdd); |
---|
| 220 | + if (ret < 0) |
---|
| 221 | + return ret; |
---|
219 | 222 | |
---|
220 | | - dev_info(&pdev->dev, "heartbeat %d sec\n", pnx4008_wdd.timeout); |
---|
221 | | - |
---|
222 | | - return 0; |
---|
223 | | - |
---|
224 | | -disable_clk: |
---|
225 | | - clk_disable_unprepare(wdt_clk); |
---|
226 | | - return ret; |
---|
227 | | -} |
---|
228 | | - |
---|
229 | | -static int pnx4008_wdt_remove(struct platform_device *pdev) |
---|
230 | | -{ |
---|
231 | | - watchdog_unregister_device(&pnx4008_wdd); |
---|
232 | | - |
---|
233 | | - clk_disable_unprepare(wdt_clk); |
---|
| 223 | + dev_info(dev, "heartbeat %d sec\n", pnx4008_wdd.timeout); |
---|
234 | 224 | |
---|
235 | 225 | return 0; |
---|
236 | 226 | } |
---|
.. | .. |
---|
249 | 239 | .of_match_table = of_match_ptr(pnx4008_wdt_match), |
---|
250 | 240 | }, |
---|
251 | 241 | .probe = pnx4008_wdt_probe, |
---|
252 | | - .remove = pnx4008_wdt_remove, |
---|
253 | 242 | }; |
---|
254 | 243 | |
---|
255 | 244 | module_platform_driver(platform_wdt_driver); |
---|