Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

spi/omap100k: Convert to runtime PM

Currently the omap100k driver uses prepare and unprepare transfer hardware
to enable and disable clocks for the IP block. Since these functions are
called along with runtime PM and end up duplicating its functionality in a
less flexible fashion we are trying to phase them out so convert this
driver to do runtime PM instead.

While doing so add missing error handling and remove a redundant NULL
assignment.

Signed-off-by: Mark Brown <broonie@kernel.org>

+77 -24
+77 -24
drivers/spi/spi-omap-100k.c
··· 24 24 #include <linux/device.h> 25 25 #include <linux/delay.h> 26 26 #include <linux/platform_device.h> 27 + #include <linux/pm_runtime.h> 27 28 #include <linux/err.h> 28 29 #include <linux/clk.h> 29 30 #include <linux/io.h> ··· 295 294 return ret; 296 295 } 297 296 298 - static int omap1_spi100k_prepare_hardware(struct spi_master *master) 299 - { 300 - struct omap1_spi100k *spi100k = spi_master_get_devdata(master); 301 - 302 - clk_prepare_enable(spi100k->ick); 303 - clk_prepare_enable(spi100k->fck); 304 - 305 - return 0; 306 - } 307 - 308 297 static int omap1_spi100k_transfer_one_message(struct spi_master *master, 309 298 struct spi_message *m) 310 299 { ··· 363 372 return status; 364 373 } 365 374 366 - static int omap1_spi100k_unprepare_hardware(struct spi_master *master) 367 - { 368 - struct omap1_spi100k *spi100k = spi_master_get_devdata(master); 369 - 370 - clk_disable_unprepare(spi100k->ick); 371 - clk_disable_unprepare(spi100k->fck); 372 - 373 - return 0; 374 - } 375 - 376 375 static int omap1_spi100k_probe(struct platform_device *pdev) 377 376 { 378 377 struct spi_master *master; ··· 383 402 384 403 master->setup = omap1_spi100k_setup; 385 404 master->transfer_one_message = omap1_spi100k_transfer_one_message; 386 - master->prepare_transfer_hardware = omap1_spi100k_prepare_hardware; 387 - master->unprepare_transfer_hardware = omap1_spi100k_unprepare_hardware; 388 - master->cleanup = NULL; 389 405 master->num_chipselect = 2; 390 406 master->mode_bits = MODEBITS; 391 407 master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); 392 408 master->min_speed_hz = OMAP1_SPI100K_MAX_FREQ/(1<<16); 393 409 master->max_speed_hz = OMAP1_SPI100K_MAX_FREQ; 410 + master->auto_runtime_pm = true; 394 411 395 412 spi100k = spi_master_get_devdata(master); 396 413 ··· 413 434 goto err; 414 435 } 415 436 437 + status = clk_prepare_enable(spi100k->ick); 438 + if (status != 0) { 439 + dev_err(&pdev->dev, "failed to enable ick: %d\n", status); 440 + goto err; 441 + } 442 + 443 + status = clk_prepare_enable(spi100k->fck); 444 + if (status != 0) { 445 + dev_err(&pdev->dev, "failed to enable fck: %d\n", status); 446 + goto err_ick; 447 + } 448 + 449 + pm_runtime_enable(&pdev->dev); 450 + pm_runtime_set_active(&pdev->dev); 451 + 416 452 status = devm_spi_register_master(&pdev->dev, master); 417 453 if (status < 0) 418 - goto err; 454 + goto err_fck; 419 455 420 456 return status; 421 457 458 + err_fck: 459 + clk_disable_unprepare(spi100k->fck); 460 + err_ick: 461 + clk_disable_unprepare(spi100k->ick); 422 462 err: 423 463 spi_master_put(master); 424 464 return status; 425 465 } 426 466 467 + static int omap1_spi100k_remove(struct platform_device *pdev) 468 + { 469 + struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); 470 + struct omap1_spi100k *spi100k = spi_master_get_devdata(master); 471 + 472 + pm_runtime_disable(&pdev->dev); 473 + 474 + clk_disable_unprepare(spi100k->fck); 475 + clk_disable_unprepare(spi100k->ick); 476 + 477 + return 0; 478 + } 479 + 480 + #ifdef CONFIG_PM 481 + static int omap1_spi100k_runtime_suspend(struct device *dev) 482 + { 483 + struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); 484 + struct omap1_spi100k *spi100k = spi_master_get_devdata(master); 485 + 486 + clk_disable_unprepare(spi100k->ick); 487 + clk_disable_unprepare(spi100k->fck); 488 + 489 + return 0; 490 + } 491 + 492 + static int omap1_spi100k_runtime_resume(struct device *dev) 493 + { 494 + struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); 495 + struct omap1_spi100k *spi100k = spi_master_get_devdata(master); 496 + int ret; 497 + 498 + ret = clk_prepare_enable(spi100k->ick); 499 + if (ret != 0) { 500 + dev_err(dev, "Failed to enable ick: %d\n", ret); 501 + return ret; 502 + } 503 + 504 + ret = clk_prepare_enable(spi100k->fck); 505 + if (ret != 0) { 506 + dev_err(dev, "Failed to enable fck: %d\n", ret); 507 + clk_disable_unprepare(spi100k->ick); 508 + return ret; 509 + } 510 + 511 + return 0; 512 + } 513 + #endif 514 + 515 + static const struct dev_pm_ops omap1_spi100k_pm = { 516 + SET_RUNTIME_PM_OPS(omap1_spi100k_runtime_suspend, 517 + omap1_spi100k_runtime_resume, NULL) 518 + }; 519 + 427 520 static struct platform_driver omap1_spi100k_driver = { 428 521 .driver = { 429 522 .name = "omap1_spi100k", 523 + .pm = &omap1_spi100k_pm, 430 524 }, 431 525 .probe = omap1_spi100k_probe, 526 + .remove = omap1_spi100k_remove, 432 527 }; 433 528 434 529 module_platform_driver(omap1_spi100k_driver);