| .. | .. |
|---|
| 2 | 2 | /* |
|---|
| 3 | 3 | * Watchdog driver for IMX2 and later processors |
|---|
| 4 | 4 | * |
|---|
| 5 | | - * Copyright (C) 2010 Wolfram Sang, Pengutronix e.K. <w.sang@pengutronix.de> |
|---|
| 5 | + * Copyright (C) 2010 Wolfram Sang, Pengutronix e.K. <kernel@pengutronix.de> |
|---|
| 6 | 6 | * Copyright (C) 2014 Freescale Semiconductor, Inc. |
|---|
| 7 | 7 | * |
|---|
| 8 | 8 | * some parts adapted by similar drivers from Darius Augulis and Vladimir |
|---|
| .. | .. |
|---|
| 71 | 71 | module_param(nowayout, bool, 0); |
|---|
| 72 | 72 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" |
|---|
| 73 | 73 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); |
|---|
| 74 | | - |
|---|
| 75 | 74 | |
|---|
| 76 | 75 | static unsigned timeout; |
|---|
| 77 | 76 | module_param(timeout, uint, 0); |
|---|
| .. | .. |
|---|
| 245 | 244 | .max_register = 0x8, |
|---|
| 246 | 245 | }; |
|---|
| 247 | 246 | |
|---|
| 247 | +static void imx2_wdt_action(void *data) |
|---|
| 248 | +{ |
|---|
| 249 | + clk_disable_unprepare(data); |
|---|
| 250 | +} |
|---|
| 251 | + |
|---|
| 248 | 252 | static int __init imx2_wdt_probe(struct platform_device *pdev) |
|---|
| 249 | 253 | { |
|---|
| 254 | + struct device *dev = &pdev->dev; |
|---|
| 250 | 255 | struct imx2_wdt_device *wdev; |
|---|
| 251 | 256 | struct watchdog_device *wdog; |
|---|
| 252 | | - struct resource *res; |
|---|
| 253 | 257 | void __iomem *base; |
|---|
| 254 | 258 | int ret; |
|---|
| 255 | 259 | u32 val; |
|---|
| 256 | 260 | |
|---|
| 257 | | - wdev = devm_kzalloc(&pdev->dev, sizeof(*wdev), GFP_KERNEL); |
|---|
| 261 | + wdev = devm_kzalloc(dev, sizeof(*wdev), GFP_KERNEL); |
|---|
| 258 | 262 | if (!wdev) |
|---|
| 259 | 263 | return -ENOMEM; |
|---|
| 260 | 264 | |
|---|
| 261 | | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
|---|
| 262 | | - base = devm_ioremap_resource(&pdev->dev, res); |
|---|
| 265 | + base = devm_platform_ioremap_resource(pdev, 0); |
|---|
| 263 | 266 | if (IS_ERR(base)) |
|---|
| 264 | 267 | return PTR_ERR(base); |
|---|
| 265 | 268 | |
|---|
| 266 | | - wdev->regmap = devm_regmap_init_mmio_clk(&pdev->dev, NULL, base, |
|---|
| 269 | + wdev->regmap = devm_regmap_init_mmio_clk(dev, NULL, base, |
|---|
| 267 | 270 | &imx2_wdt_regmap_config); |
|---|
| 268 | 271 | if (IS_ERR(wdev->regmap)) { |
|---|
| 269 | | - dev_err(&pdev->dev, "regmap init failed\n"); |
|---|
| 272 | + dev_err(dev, "regmap init failed\n"); |
|---|
| 270 | 273 | return PTR_ERR(wdev->regmap); |
|---|
| 271 | 274 | } |
|---|
| 272 | 275 | |
|---|
| 273 | | - wdev->clk = devm_clk_get(&pdev->dev, NULL); |
|---|
| 276 | + wdev->clk = devm_clk_get(dev, NULL); |
|---|
| 274 | 277 | if (IS_ERR(wdev->clk)) { |
|---|
| 275 | | - dev_err(&pdev->dev, "can't get Watchdog clock\n"); |
|---|
| 278 | + dev_err(dev, "can't get Watchdog clock\n"); |
|---|
| 276 | 279 | return PTR_ERR(wdev->clk); |
|---|
| 277 | 280 | } |
|---|
| 278 | 281 | |
|---|
| .. | .. |
|---|
| 282 | 285 | wdog->min_timeout = 1; |
|---|
| 283 | 286 | wdog->timeout = IMX2_WDT_DEFAULT_TIME; |
|---|
| 284 | 287 | wdog->max_hw_heartbeat_ms = IMX2_WDT_MAX_TIME * 1000; |
|---|
| 285 | | - wdog->parent = &pdev->dev; |
|---|
| 288 | + wdog->parent = dev; |
|---|
| 286 | 289 | |
|---|
| 287 | 290 | ret = platform_get_irq(pdev, 0); |
|---|
| 288 | 291 | if (ret > 0) |
|---|
| 289 | | - if (!devm_request_irq(&pdev->dev, ret, imx2_wdt_isr, 0, |
|---|
| 290 | | - dev_name(&pdev->dev), wdog)) |
|---|
| 292 | + if (!devm_request_irq(dev, ret, imx2_wdt_isr, 0, |
|---|
| 293 | + dev_name(dev), wdog)) |
|---|
| 291 | 294 | wdog->info = &imx2_wdt_pretimeout_info; |
|---|
| 292 | 295 | |
|---|
| 293 | 296 | ret = clk_prepare_enable(wdev->clk); |
|---|
| 294 | 297 | if (ret) |
|---|
| 295 | 298 | return ret; |
|---|
| 296 | 299 | |
|---|
| 300 | + ret = devm_add_action_or_reset(dev, imx2_wdt_action, wdev->clk); |
|---|
| 301 | + if (ret) |
|---|
| 302 | + return ret; |
|---|
| 303 | + |
|---|
| 297 | 304 | regmap_read(wdev->regmap, IMX2_WDT_WRSR, &val); |
|---|
| 298 | 305 | wdog->bootstatus = val & IMX2_WDT_WRSR_TOUT ? WDIOF_CARDRESET : 0; |
|---|
| 299 | 306 | |
|---|
| 300 | | - wdev->ext_reset = of_property_read_bool(pdev->dev.of_node, |
|---|
| 307 | + wdev->ext_reset = of_property_read_bool(dev->of_node, |
|---|
| 301 | 308 | "fsl,ext-reset-output"); |
|---|
| 302 | 309 | platform_set_drvdata(pdev, wdog); |
|---|
| 303 | 310 | watchdog_set_drvdata(wdog, wdev); |
|---|
| 304 | 311 | watchdog_set_nowayout(wdog, nowayout); |
|---|
| 305 | 312 | watchdog_set_restart_priority(wdog, 128); |
|---|
| 306 | | - watchdog_init_timeout(wdog, timeout, &pdev->dev); |
|---|
| 313 | + watchdog_init_timeout(wdog, timeout, dev); |
|---|
| 307 | 314 | |
|---|
| 308 | 315 | if (imx2_wdt_is_running(wdev)) { |
|---|
| 309 | 316 | imx2_wdt_set_timeout(wdog, wdog->timeout); |
|---|
| .. | .. |
|---|
| 317 | 324 | */ |
|---|
| 318 | 325 | regmap_write(wdev->regmap, IMX2_WDT_WMCR, 0); |
|---|
| 319 | 326 | |
|---|
| 320 | | - ret = watchdog_register_device(wdog); |
|---|
| 321 | | - if (ret) { |
|---|
| 322 | | - dev_err(&pdev->dev, "cannot register watchdog device\n"); |
|---|
| 323 | | - goto disable_clk; |
|---|
| 324 | | - } |
|---|
| 325 | | - |
|---|
| 326 | | - dev_info(&pdev->dev, "timeout %d sec (nowayout=%d)\n", |
|---|
| 327 | | - wdog->timeout, nowayout); |
|---|
| 328 | | - |
|---|
| 329 | | - return 0; |
|---|
| 330 | | - |
|---|
| 331 | | -disable_clk: |
|---|
| 332 | | - clk_disable_unprepare(wdev->clk); |
|---|
| 333 | | - return ret; |
|---|
| 334 | | -} |
|---|
| 335 | | - |
|---|
| 336 | | -static int __exit imx2_wdt_remove(struct platform_device *pdev) |
|---|
| 337 | | -{ |
|---|
| 338 | | - struct watchdog_device *wdog = platform_get_drvdata(pdev); |
|---|
| 339 | | - struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog); |
|---|
| 340 | | - |
|---|
| 341 | | - watchdog_unregister_device(wdog); |
|---|
| 342 | | - |
|---|
| 343 | | - if (imx2_wdt_is_running(wdev)) { |
|---|
| 344 | | - imx2_wdt_ping(wdog); |
|---|
| 345 | | - dev_crit(&pdev->dev, "Device removed: Expect reboot!\n"); |
|---|
| 346 | | - } |
|---|
| 347 | | - return 0; |
|---|
| 327 | + return devm_watchdog_register_device(dev, wdog); |
|---|
| 348 | 328 | } |
|---|
| 349 | 329 | |
|---|
| 350 | 330 | static void imx2_wdt_shutdown(struct platform_device *pdev) |
|---|
| .. | .. |
|---|
| 363 | 343 | } |
|---|
| 364 | 344 | } |
|---|
| 365 | 345 | |
|---|
| 366 | | -#ifdef CONFIG_PM_SLEEP |
|---|
| 367 | 346 | /* Disable watchdog if it is active or non-active but still running */ |
|---|
| 368 | | -static int imx2_wdt_suspend(struct device *dev) |
|---|
| 347 | +static int __maybe_unused imx2_wdt_suspend(struct device *dev) |
|---|
| 369 | 348 | { |
|---|
| 370 | 349 | struct watchdog_device *wdog = dev_get_drvdata(dev); |
|---|
| 371 | 350 | struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog); |
|---|
| .. | .. |
|---|
| 386 | 365 | } |
|---|
| 387 | 366 | |
|---|
| 388 | 367 | /* Enable watchdog and configure it if necessary */ |
|---|
| 389 | | -static int imx2_wdt_resume(struct device *dev) |
|---|
| 368 | +static int __maybe_unused imx2_wdt_resume(struct device *dev) |
|---|
| 390 | 369 | { |
|---|
| 391 | 370 | struct watchdog_device *wdog = dev_get_drvdata(dev); |
|---|
| 392 | 371 | struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog); |
|---|
| .. | .. |
|---|
| 411 | 390 | |
|---|
| 412 | 391 | return 0; |
|---|
| 413 | 392 | } |
|---|
| 414 | | -#endif |
|---|
| 415 | 393 | |
|---|
| 416 | 394 | static SIMPLE_DEV_PM_OPS(imx2_wdt_pm_ops, imx2_wdt_suspend, |
|---|
| 417 | 395 | imx2_wdt_resume); |
|---|
| .. | .. |
|---|
| 423 | 401 | MODULE_DEVICE_TABLE(of, imx2_wdt_dt_ids); |
|---|
| 424 | 402 | |
|---|
| 425 | 403 | static struct platform_driver imx2_wdt_driver = { |
|---|
| 426 | | - .remove = __exit_p(imx2_wdt_remove), |
|---|
| 427 | 404 | .shutdown = imx2_wdt_shutdown, |
|---|
| 428 | 405 | .driver = { |
|---|
| 429 | 406 | .name = DRIVER_NAME, |
|---|