clk-bulk.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright 2017 NXP
  4. *
  5. * Dong Aisheng <aisheng.dong@nxp.com>
  6. */
  7. #include <linux/clk.h>
  8. #include <linux/clk-provider.h>
  9. #include <linux/device.h>
  10. #include <linux/export.h>
  11. #include <linux/of.h>
  12. #include <linux/slab.h>
  13. static int __must_check of_clk_bulk_get(struct device_node *np, int num_clks,
  14. struct clk_bulk_data *clks)
  15. {
  16. int ret;
  17. int i;
  18. for (i = 0; i < num_clks; i++) {
  19. clks[i].id = NULL;
  20. clks[i].clk = NULL;
  21. }
  22. for (i = 0; i < num_clks; i++) {
  23. of_property_read_string_index(np, "clock-names", i, &clks[i].id);
  24. clks[i].clk = of_clk_get(np, i);
  25. if (IS_ERR(clks[i].clk)) {
  26. ret = PTR_ERR(clks[i].clk);
  27. pr_err("%pOF: Failed to get clk index: %d ret: %d\n",
  28. np, i, ret);
  29. clks[i].clk = NULL;
  30. goto err;
  31. }
  32. }
  33. return 0;
  34. err:
  35. clk_bulk_put(i, clks);
  36. return ret;
  37. }
  38. static int __must_check of_clk_bulk_get_all(struct device_node *np,
  39. struct clk_bulk_data **clks)
  40. {
  41. struct clk_bulk_data *clk_bulk;
  42. int num_clks;
  43. int ret;
  44. num_clks = of_clk_get_parent_count(np);
  45. if (!num_clks)
  46. return 0;
  47. clk_bulk = kmalloc_array(num_clks, sizeof(*clk_bulk), GFP_KERNEL);
  48. if (!clk_bulk)
  49. return -ENOMEM;
  50. ret = of_clk_bulk_get(np, num_clks, clk_bulk);
  51. if (ret) {
  52. kfree(clk_bulk);
  53. return ret;
  54. }
  55. *clks = clk_bulk;
  56. return num_clks;
  57. }
  58. void clk_bulk_put(int num_clks, struct clk_bulk_data *clks)
  59. {
  60. while (--num_clks >= 0) {
  61. clk_put(clks[num_clks].clk);
  62. clks[num_clks].clk = NULL;
  63. }
  64. }
  65. EXPORT_SYMBOL_GPL(clk_bulk_put);
  66. static int __clk_bulk_get(struct device *dev, int num_clks,
  67. struct clk_bulk_data *clks, bool optional)
  68. {
  69. int ret;
  70. int i;
  71. for (i = 0; i < num_clks; i++)
  72. clks[i].clk = NULL;
  73. for (i = 0; i < num_clks; i++) {
  74. clks[i].clk = clk_get(dev, clks[i].id);
  75. if (IS_ERR(clks[i].clk)) {
  76. ret = PTR_ERR(clks[i].clk);
  77. clks[i].clk = NULL;
  78. if (ret == -ENOENT && optional)
  79. continue;
  80. if (ret != -EPROBE_DEFER)
  81. dev_err(dev, "Failed to get clk '%s': %d\n",
  82. clks[i].id, ret);
  83. goto err;
  84. }
  85. }
  86. return 0;
  87. err:
  88. clk_bulk_put(i, clks);
  89. return ret;
  90. }
  91. int __must_check clk_bulk_get(struct device *dev, int num_clks,
  92. struct clk_bulk_data *clks)
  93. {
  94. return __clk_bulk_get(dev, num_clks, clks, false);
  95. }
  96. EXPORT_SYMBOL(clk_bulk_get);
  97. int __must_check clk_bulk_get_optional(struct device *dev, int num_clks,
  98. struct clk_bulk_data *clks)
  99. {
  100. return __clk_bulk_get(dev, num_clks, clks, true);
  101. }
  102. EXPORT_SYMBOL_GPL(clk_bulk_get_optional);
  103. void clk_bulk_put_all(int num_clks, struct clk_bulk_data *clks)
  104. {
  105. if (IS_ERR_OR_NULL(clks))
  106. return;
  107. clk_bulk_put(num_clks, clks);
  108. kfree(clks);
  109. }
  110. EXPORT_SYMBOL(clk_bulk_put_all);
  111. int __must_check clk_bulk_get_all(struct device *dev,
  112. struct clk_bulk_data **clks)
  113. {
  114. struct device_node *np = dev_of_node(dev);
  115. if (!np)
  116. return 0;
  117. return of_clk_bulk_get_all(np, clks);
  118. }
  119. EXPORT_SYMBOL(clk_bulk_get_all);
  120. #ifdef CONFIG_HAVE_CLK_PREPARE
  121. /**
  122. * clk_bulk_unprepare - undo preparation of a set of clock sources
  123. * @num_clks: the number of clk_bulk_data
  124. * @clks: the clk_bulk_data table being unprepared
  125. *
  126. * clk_bulk_unprepare may sleep, which differentiates it from clk_bulk_disable.
  127. * Returns 0 on success, -EERROR otherwise.
  128. */
  129. void clk_bulk_unprepare(int num_clks, const struct clk_bulk_data *clks)
  130. {
  131. while (--num_clks >= 0)
  132. clk_unprepare(clks[num_clks].clk);
  133. }
  134. EXPORT_SYMBOL_GPL(clk_bulk_unprepare);
  135. /**
  136. * clk_bulk_prepare - prepare a set of clocks
  137. * @num_clks: the number of clk_bulk_data
  138. * @clks: the clk_bulk_data table being prepared
  139. *
  140. * clk_bulk_prepare may sleep, which differentiates it from clk_bulk_enable.
  141. * Returns 0 on success, -EERROR otherwise.
  142. */
  143. int __must_check clk_bulk_prepare(int num_clks,
  144. const struct clk_bulk_data *clks)
  145. {
  146. int ret;
  147. int i;
  148. for (i = 0; i < num_clks; i++) {
  149. ret = clk_prepare(clks[i].clk);
  150. if (ret) {
  151. pr_err("Failed to prepare clk '%s': %d\n",
  152. clks[i].id, ret);
  153. goto err;
  154. }
  155. }
  156. return 0;
  157. err:
  158. clk_bulk_unprepare(i, clks);
  159. return ret;
  160. }
  161. EXPORT_SYMBOL_GPL(clk_bulk_prepare);
  162. #endif /* CONFIG_HAVE_CLK_PREPARE */
  163. /**
  164. * clk_bulk_disable - gate a set of clocks
  165. * @num_clks: the number of clk_bulk_data
  166. * @clks: the clk_bulk_data table being gated
  167. *
  168. * clk_bulk_disable must not sleep, which differentiates it from
  169. * clk_bulk_unprepare. clk_bulk_disable must be called before
  170. * clk_bulk_unprepare.
  171. */
  172. void clk_bulk_disable(int num_clks, const struct clk_bulk_data *clks)
  173. {
  174. while (--num_clks >= 0)
  175. clk_disable(clks[num_clks].clk);
  176. }
  177. EXPORT_SYMBOL_GPL(clk_bulk_disable);
  178. /**
  179. * clk_bulk_enable - ungate a set of clocks
  180. * @num_clks: the number of clk_bulk_data
  181. * @clks: the clk_bulk_data table being ungated
  182. *
  183. * clk_bulk_enable must not sleep
  184. * Returns 0 on success, -EERROR otherwise.
  185. */
  186. int __must_check clk_bulk_enable(int num_clks, const struct clk_bulk_data *clks)
  187. {
  188. int ret;
  189. int i;
  190. for (i = 0; i < num_clks; i++) {
  191. ret = clk_enable(clks[i].clk);
  192. if (ret) {
  193. pr_err("Failed to enable clk '%s': %d\n",
  194. clks[i].id, ret);
  195. goto err;
  196. }
  197. }
  198. return 0;
  199. err:
  200. clk_bulk_disable(i, clks);
  201. return ret;
  202. }
  203. EXPORT_SYMBOL_GPL(clk_bulk_enable);