gate-link.c 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (c) 2024 Collabora Ltd.
  4. * Author: Sebastian Reichel <sebastian.reichel@collabora.com>
  5. */
  6. #include <linux/clk.h>
  7. #include <linux/platform_device.h>
  8. #include <linux/pm_clock.h>
  9. #include <linux/pm_runtime.h>
  10. #include <linux/property.h>
  11. #include "clk.h"
  12. static int rk_clk_gate_link_register(struct device *dev,
  13. struct rockchip_clk_provider *ctx,
  14. struct rockchip_clk_branch *clkbr)
  15. {
  16. unsigned long flags = clkbr->flags | CLK_SET_RATE_PARENT;
  17. struct clk *clk;
  18. clk = clk_register_gate(dev, clkbr->name, clkbr->parent_names[0],
  19. flags, ctx->reg_base + clkbr->gate_offset,
  20. clkbr->gate_shift, clkbr->gate_flags,
  21. &ctx->lock);
  22. if (IS_ERR(clk))
  23. return PTR_ERR(clk);
  24. rockchip_clk_set_lookup(ctx, clk, clkbr->id);
  25. return 0;
  26. }
  27. static int rk_clk_gate_link_probe(struct platform_device *pdev)
  28. {
  29. struct rockchip_gate_link_platdata *pdata;
  30. struct device *dev = &pdev->dev;
  31. struct clk *linked_clk;
  32. int ret;
  33. pdata = dev_get_platdata(dev);
  34. if (!pdata)
  35. return dev_err_probe(dev, -ENODEV, "missing platform data");
  36. ret = devm_pm_runtime_enable(dev);
  37. if (ret)
  38. return ret;
  39. ret = devm_pm_clk_create(dev);
  40. if (ret)
  41. return ret;
  42. linked_clk = rockchip_clk_get_lookup(pdata->ctx, pdata->clkbr->linked_clk_id);
  43. ret = pm_clk_add_clk(dev, linked_clk);
  44. if (ret)
  45. return ret;
  46. ret = rk_clk_gate_link_register(dev, pdata->ctx, pdata->clkbr);
  47. if (ret)
  48. goto err;
  49. return 0;
  50. err:
  51. pm_clk_remove_clk(dev, linked_clk);
  52. return ret;
  53. }
  54. static const struct dev_pm_ops rk_clk_gate_link_pm_ops = {
  55. SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
  56. };
  57. static struct platform_driver rk_clk_gate_link_driver = {
  58. .probe = rk_clk_gate_link_probe,
  59. .driver = {
  60. .name = "rockchip-gate-link-clk",
  61. .pm = &rk_clk_gate_link_pm_ops,
  62. .suppress_bind_attrs = true,
  63. },
  64. };
  65. static int __init rk_clk_gate_link_drv_register(void)
  66. {
  67. return platform_driver_register(&rk_clk_gate_link_driver);
  68. }
  69. core_initcall(rk_clk_gate_link_drv_register);