| .. | .. |
|---|
| 274 | 274 | .set_timeout = cdns_wdt_settimeout, |
|---|
| 275 | 275 | }; |
|---|
| 276 | 276 | |
|---|
| 277 | +static void cdns_clk_disable_unprepare(void *data) |
|---|
| 278 | +{ |
|---|
| 279 | + clk_disable_unprepare(data); |
|---|
| 280 | +} |
|---|
| 281 | + |
|---|
| 277 | 282 | /************************Platform Operations*****************************/ |
|---|
| 278 | 283 | /** |
|---|
| 279 | 284 | * cdns_wdt_probe - Probe call for the device. |
|---|
| .. | .. |
|---|
| 285 | 290 | */ |
|---|
| 286 | 291 | static int cdns_wdt_probe(struct platform_device *pdev) |
|---|
| 287 | 292 | { |
|---|
| 288 | | - struct resource *res; |
|---|
| 293 | + struct device *dev = &pdev->dev; |
|---|
| 289 | 294 | int ret, irq; |
|---|
| 290 | 295 | unsigned long clock_f; |
|---|
| 291 | 296 | struct cdns_wdt *wdt; |
|---|
| 292 | 297 | struct watchdog_device *cdns_wdt_device; |
|---|
| 293 | 298 | |
|---|
| 294 | | - wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); |
|---|
| 299 | + wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL); |
|---|
| 295 | 300 | if (!wdt) |
|---|
| 296 | 301 | return -ENOMEM; |
|---|
| 297 | 302 | |
|---|
| .. | .. |
|---|
| 302 | 307 | cdns_wdt_device->min_timeout = CDNS_WDT_MIN_TIMEOUT; |
|---|
| 303 | 308 | cdns_wdt_device->max_timeout = CDNS_WDT_MAX_TIMEOUT; |
|---|
| 304 | 309 | |
|---|
| 305 | | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
|---|
| 306 | | - wdt->regs = devm_ioremap_resource(&pdev->dev, res); |
|---|
| 310 | + wdt->regs = devm_platform_ioremap_resource(pdev, 0); |
|---|
| 307 | 311 | if (IS_ERR(wdt->regs)) |
|---|
| 308 | 312 | return PTR_ERR(wdt->regs); |
|---|
| 309 | 313 | |
|---|
| 310 | 314 | /* Register the interrupt */ |
|---|
| 311 | | - wdt->rst = of_property_read_bool(pdev->dev.of_node, "reset-on-timeout"); |
|---|
| 315 | + wdt->rst = of_property_read_bool(dev->of_node, "reset-on-timeout"); |
|---|
| 312 | 316 | irq = platform_get_irq(pdev, 0); |
|---|
| 313 | 317 | if (!wdt->rst && irq >= 0) { |
|---|
| 314 | | - ret = devm_request_irq(&pdev->dev, irq, cdns_wdt_irq_handler, 0, |
|---|
| 318 | + ret = devm_request_irq(dev, irq, cdns_wdt_irq_handler, 0, |
|---|
| 315 | 319 | pdev->name, pdev); |
|---|
| 316 | 320 | if (ret) { |
|---|
| 317 | | - dev_err(&pdev->dev, |
|---|
| 321 | + dev_err(dev, |
|---|
| 318 | 322 | "cannot register interrupt handler err=%d\n", |
|---|
| 319 | 323 | ret); |
|---|
| 320 | 324 | return ret; |
|---|
| .. | .. |
|---|
| 322 | 326 | } |
|---|
| 323 | 327 | |
|---|
| 324 | 328 | /* Initialize the members of cdns_wdt structure */ |
|---|
| 325 | | - cdns_wdt_device->parent = &pdev->dev; |
|---|
| 329 | + cdns_wdt_device->parent = dev; |
|---|
| 326 | 330 | |
|---|
| 327 | | - ret = watchdog_init_timeout(cdns_wdt_device, wdt_timeout, &pdev->dev); |
|---|
| 328 | | - if (ret) { |
|---|
| 329 | | - dev_err(&pdev->dev, "unable to set timeout value\n"); |
|---|
| 330 | | - return ret; |
|---|
| 331 | | - } |
|---|
| 332 | | - |
|---|
| 331 | + watchdog_init_timeout(cdns_wdt_device, wdt_timeout, dev); |
|---|
| 333 | 332 | watchdog_set_nowayout(cdns_wdt_device, nowayout); |
|---|
| 334 | 333 | watchdog_stop_on_reboot(cdns_wdt_device); |
|---|
| 335 | 334 | watchdog_set_drvdata(cdns_wdt_device, wdt); |
|---|
| 336 | 335 | |
|---|
| 337 | | - wdt->clk = devm_clk_get(&pdev->dev, NULL); |
|---|
| 338 | | - if (IS_ERR(wdt->clk)) { |
|---|
| 339 | | - dev_err(&pdev->dev, "input clock not found\n"); |
|---|
| 340 | | - ret = PTR_ERR(wdt->clk); |
|---|
| 341 | | - return ret; |
|---|
| 342 | | - } |
|---|
| 336 | + wdt->clk = devm_clk_get(dev, NULL); |
|---|
| 337 | + if (IS_ERR(wdt->clk)) |
|---|
| 338 | + return dev_err_probe(dev, PTR_ERR(wdt->clk), |
|---|
| 339 | + "input clock not found\n"); |
|---|
| 343 | 340 | |
|---|
| 344 | 341 | ret = clk_prepare_enable(wdt->clk); |
|---|
| 345 | 342 | if (ret) { |
|---|
| 346 | | - dev_err(&pdev->dev, "unable to enable clock\n"); |
|---|
| 343 | + dev_err(dev, "unable to enable clock\n"); |
|---|
| 347 | 344 | return ret; |
|---|
| 348 | 345 | } |
|---|
| 346 | + ret = devm_add_action_or_reset(dev, cdns_clk_disable_unprepare, |
|---|
| 347 | + wdt->clk); |
|---|
| 348 | + if (ret) |
|---|
| 349 | + return ret; |
|---|
| 349 | 350 | |
|---|
| 350 | 351 | clock_f = clk_get_rate(wdt->clk); |
|---|
| 351 | 352 | if (clock_f <= CDNS_WDT_CLK_75MHZ) { |
|---|
| .. | .. |
|---|
| 358 | 359 | |
|---|
| 359 | 360 | spin_lock_init(&wdt->io_lock); |
|---|
| 360 | 361 | |
|---|
| 361 | | - ret = watchdog_register_device(cdns_wdt_device); |
|---|
| 362 | | - if (ret) { |
|---|
| 363 | | - dev_err(&pdev->dev, "Failed to register wdt device\n"); |
|---|
| 364 | | - goto err_clk_disable; |
|---|
| 365 | | - } |
|---|
| 362 | + watchdog_stop_on_reboot(cdns_wdt_device); |
|---|
| 363 | + watchdog_stop_on_unregister(cdns_wdt_device); |
|---|
| 364 | + ret = devm_watchdog_register_device(dev, cdns_wdt_device); |
|---|
| 365 | + if (ret) |
|---|
| 366 | + return ret; |
|---|
| 366 | 367 | platform_set_drvdata(pdev, wdt); |
|---|
| 367 | 368 | |
|---|
| 368 | | - dev_info(&pdev->dev, "Xilinx Watchdog Timer at %p with timeout %ds%s\n", |
|---|
| 369 | | - wdt->regs, cdns_wdt_device->timeout, |
|---|
| 370 | | - nowayout ? ", nowayout" : ""); |
|---|
| 369 | + dev_info(dev, "Xilinx Watchdog Timer with timeout %ds%s\n", |
|---|
| 370 | + cdns_wdt_device->timeout, nowayout ? ", nowayout" : ""); |
|---|
| 371 | 371 | |
|---|
| 372 | 372 | return 0; |
|---|
| 373 | | - |
|---|
| 374 | | -err_clk_disable: |
|---|
| 375 | | - clk_disable_unprepare(wdt->clk); |
|---|
| 376 | | - |
|---|
| 377 | | - return ret; |
|---|
| 378 | | -} |
|---|
| 379 | | - |
|---|
| 380 | | -/** |
|---|
| 381 | | - * cdns_wdt_remove - Probe call for the device. |
|---|
| 382 | | - * |
|---|
| 383 | | - * @pdev: handle to the platform device structure. |
|---|
| 384 | | - * Return: 0 on success, otherwise negative error. |
|---|
| 385 | | - * |
|---|
| 386 | | - * Unregister the device after releasing the resources. |
|---|
| 387 | | - */ |
|---|
| 388 | | -static int cdns_wdt_remove(struct platform_device *pdev) |
|---|
| 389 | | -{ |
|---|
| 390 | | - struct cdns_wdt *wdt = platform_get_drvdata(pdev); |
|---|
| 391 | | - |
|---|
| 392 | | - cdns_wdt_stop(&wdt->cdns_wdt_device); |
|---|
| 393 | | - watchdog_unregister_device(&wdt->cdns_wdt_device); |
|---|
| 394 | | - clk_disable_unprepare(wdt->clk); |
|---|
| 395 | | - |
|---|
| 396 | | - return 0; |
|---|
| 397 | | -} |
|---|
| 398 | | - |
|---|
| 399 | | -/** |
|---|
| 400 | | - * cdns_wdt_shutdown - Stop the device. |
|---|
| 401 | | - * |
|---|
| 402 | | - * @pdev: handle to the platform structure. |
|---|
| 403 | | - * |
|---|
| 404 | | - */ |
|---|
| 405 | | -static void cdns_wdt_shutdown(struct platform_device *pdev) |
|---|
| 406 | | -{ |
|---|
| 407 | | - struct cdns_wdt *wdt = platform_get_drvdata(pdev); |
|---|
| 408 | | - |
|---|
| 409 | | - cdns_wdt_stop(&wdt->cdns_wdt_device); |
|---|
| 410 | | - clk_disable_unprepare(wdt->clk); |
|---|
| 411 | 373 | } |
|---|
| 412 | 374 | |
|---|
| 413 | 375 | /** |
|---|
| .. | .. |
|---|
| 462 | 424 | /* Driver Structure */ |
|---|
| 463 | 425 | static struct platform_driver cdns_wdt_driver = { |
|---|
| 464 | 426 | .probe = cdns_wdt_probe, |
|---|
| 465 | | - .remove = cdns_wdt_remove, |
|---|
| 466 | | - .shutdown = cdns_wdt_shutdown, |
|---|
| 467 | 427 | .driver = { |
|---|
| 468 | 428 | .name = "cdns-wdt", |
|---|
| 469 | 429 | .of_match_table = cdns_wdt_of_match, |
|---|