clk-pm.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2022, 2024, Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #include <linux/clk.h>
  7. #include <linux/of.h>
  8. #include <linux/pm.h>
  9. #include <linux/pm_runtime.h>
  10. #include <linux/suspend.h>
  11. #include "clk-regmap.h"
  12. #include "clk-pm.h"
  13. #include "common.h"
  14. /* Restores the clocks configuration while coming out of Hibernation */
  15. static int clock_pm_restore_early(struct device *dev)
  16. {
  17. clk_restore_context();
  18. clk_restore_critical_clocks(dev);
  19. return 0;
  20. }
  21. /* Restores the clocks configuration while coming out of DeepSleep */
  22. static int clock_pm_resume_early(struct device *dev)
  23. {
  24. #ifdef CONFIG_DEEPSLEEP
  25. if (pm_suspend_via_firmware()) {
  26. clk_restore_context();
  27. clk_restore_critical_clocks(dev);
  28. }
  29. #endif
  30. return 0;
  31. }
  32. static const struct dev_pm_ops clock_pm_ops = {
  33. .restore_early = clock_pm_restore_early,
  34. .resume_early = clock_pm_resume_early,
  35. };
  36. static const struct dev_pm_ops clock_pm_rt_ops = {
  37. .restore = clock_pm_restore_early,
  38. .resume = clock_pm_resume_early,
  39. SET_RUNTIME_PM_OPS(qcom_cc_runtime_suspend, qcom_cc_runtime_resume, NULL)
  40. SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
  41. pm_runtime_force_resume)
  42. };
  43. int register_qcom_clks_pm(struct platform_device *pdev, bool runtime,
  44. struct qcom_cc_desc *desc)
  45. {
  46. int ret;
  47. if (IS_ERR_OR_NULL(pdev))
  48. return PTR_ERR(pdev);
  49. if (runtime) {
  50. pdev->dev.driver->pm = &clock_pm_rt_ops;
  51. ret = qcom_cc_runtime_init(pdev, desc);
  52. if (ret)
  53. return ret;
  54. ret = pm_runtime_get_sync(&pdev->dev);
  55. if (ret)
  56. return ret;
  57. } else {
  58. pdev->dev.driver->pm = &clock_pm_ops;
  59. platform_set_drvdata(pdev, desc);
  60. }
  61. return 0;
  62. }
  63. EXPORT_SYMBOL(register_qcom_clks_pm);