clk-dummy.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2018-2019, 2021, The Linux Foundation. All rights reserved.
  4. */
  5. #include <linux/clk-provider.h>
  6. #include <linux/kernel.h>
  7. #include <linux/module.h>
  8. #include <linux/of.h>
  9. #include <linux/platform_device.h>
  10. #include <linux/slab.h>
  11. #include "common.h"
  12. #include "clk-debug.h"
  13. #define to_clk_dummy(_hw) container_of(_hw, struct clk_dummy, hw)
  14. #define RESET_MAX 100
  15. static int dummy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
  16. unsigned long parent_rate)
  17. {
  18. struct clk_dummy *dummy = to_clk_dummy(hw);
  19. dummy->rrate = rate;
  20. pr_debug("%s: rate %lu\n", __func__, rate);
  21. return 0;
  22. }
  23. static long dummy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
  24. unsigned long *parent_rate)
  25. {
  26. return rate;
  27. }
  28. static unsigned long dummy_clk_recalc_rate(struct clk_hw *hw,
  29. unsigned long parent_rate)
  30. {
  31. struct clk_dummy *dummy = to_clk_dummy(hw);
  32. pr_debug("%s: returning a clock rate of %lu\n",
  33. __func__, dummy->rrate);
  34. return dummy->rrate;
  35. }
  36. const struct clk_ops clk_dummy_ops = {
  37. .set_rate = dummy_clk_set_rate,
  38. .round_rate = dummy_clk_round_rate,
  39. .recalc_rate = dummy_clk_recalc_rate,
  40. .debug_init = clk_debug_measure_add,
  41. };
  42. EXPORT_SYMBOL(clk_dummy_ops);
  43. static int dummy_reset_assert(struct reset_controller_dev *rcdev,
  44. unsigned long id)
  45. {
  46. return 0;
  47. }
  48. static int dummy_reset_deassert(struct reset_controller_dev *rcdev,
  49. unsigned long id)
  50. {
  51. return 0;
  52. }
  53. static struct reset_control_ops dummy_reset_ops = {
  54. .assert = dummy_reset_assert,
  55. .deassert = dummy_reset_deassert,
  56. };
  57. /**
  58. * clk_register_dummy - register dummy clock with the
  59. * clock framework
  60. * @dev: device that is registering this clock
  61. * @name: name of this clock
  62. * @flags: framework-specific flags
  63. * @node: device node
  64. */
  65. static struct clk *clk_register_dummy(struct device *dev, const char *name,
  66. unsigned long flags, struct device_node *node)
  67. {
  68. struct clk_dummy *dummy;
  69. struct clk *clk;
  70. struct clk_init_data init = {};
  71. /* allocate dummy clock */
  72. dummy = devm_kzalloc(dev, sizeof(*dummy), GFP_KERNEL);
  73. if (!dummy)
  74. return ERR_PTR(-ENOMEM);
  75. init.name = name;
  76. init.ops = &clk_dummy_ops;
  77. init.flags = flags;
  78. init.num_parents = 0;
  79. dummy->hw.init = &init;
  80. /* register the clock */
  81. clk = devm_clk_register(dev, &dummy->hw);
  82. if (IS_ERR(clk))
  83. return clk;
  84. dummy->reset.of_node = node;
  85. dummy->reset.ops = &dummy_reset_ops;
  86. dummy->reset.nr_resets = RESET_MAX;
  87. if (devm_reset_controller_register(dev, &dummy->reset))
  88. pr_err("Failed to register reset controller for %s\n", name);
  89. else
  90. pr_info("Successfully registered dummy reset controller for %s\n", name);
  91. return clk;
  92. }
  93. static int dummy_clk_probe(struct platform_device *pdev)
  94. {
  95. struct device_node *node = pdev->dev.of_node;
  96. const char *clk_name = "dummy_clk";
  97. struct clk *clk;
  98. int ret;
  99. of_property_read_string(node, "clock-output-names", &clk_name);
  100. clk = clk_register_dummy(&pdev->dev, clk_name, 0, node);
  101. if (!IS_ERR(clk)) {
  102. ret = of_clk_add_provider(node, of_clk_src_simple_get, clk);
  103. if (ret)
  104. return ret;
  105. } else {
  106. ret = PTR_ERR(clk);
  107. pr_err("Failed to register dummy clock controller for %s, ret=%d\n",
  108. clk_name, ret);
  109. return ret;
  110. }
  111. dev_info(&pdev->dev, "Successfully registered dummy clock controller for %s\n",
  112. clk_name);
  113. return 0;
  114. }
  115. static int dummy_clk_remove(struct platform_device *pdev)
  116. {
  117. of_clk_del_provider(pdev->dev.of_node);
  118. return 0;
  119. }
  120. static const struct of_device_id dummy_clk_match_table[] = {
  121. { .compatible = "qcom,dummycc" },
  122. { }
  123. };
  124. MODULE_DEVICE_TABLE(of, dummy_clk_match_table);
  125. static struct platform_driver dummy_clk_driver = {
  126. .probe = dummy_clk_probe,
  127. .remove = dummy_clk_remove,
  128. .driver = {
  129. .name = "clk-dummy",
  130. .of_match_table = dummy_clk_match_table,
  131. },
  132. };
  133. static int __init dummy_clk_init(void)
  134. {
  135. return platform_driver_register(&dummy_clk_driver);
  136. }
  137. arch_initcall(dummy_clk_init);
  138. static void __exit dummy_clk_exit(void)
  139. {
  140. platform_driver_unregister(&dummy_clk_driver);
  141. }
  142. module_exit(dummy_clk_exit);
  143. MODULE_DESCRIPTION("QTI Dummy Clock Driver");
  144. MODULE_LICENSE("GPL v2");