083-0001-clk-Add-devm_-clk_hw_-register-unregister-APIs.patch 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. From 4143804c4fdef40358c654d1fb2271a1a0f1fedf Mon Sep 17 00:00:00 2001
  2. From: Stephen Boyd <sboyd@codeaurora.org>
  3. Date: Fri, 5 Feb 2016 17:02:52 -0800
  4. Subject: [PATCH] clk: Add {devm_}clk_hw_{register,unregister}() APIs
  5. We've largely split the clk consumer and provider APIs along
  6. struct clk and struct clk_hw, but clk_register() still returns a
  7. struct clk pointer for each struct clk_hw that's registered.
  8. Eventually we'd like to only allocate struct clks when there's a
  9. user, because struct clk is per-user now, so clk_register() needs
  10. to change.
  11. Let's add new APIs to register struct clk_hws, but this time
  12. we'll hide the struct clk from the caller by returning an int
  13. error code. Also add an unregistration API that takes the clk_hw
  14. structure that was passed to the registration API. This way
  15. provider drivers never have to deal with a struct clk pointer
  16. unless they're using the clk consumer APIs.
  17. Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
  18. ---
  19. Documentation/driver-model/devres.txt | 1 +
  20. drivers/clk/clk.c | 86 +++++++++++++++++++++++++++++++++++
  21. include/linux/clk-provider.h | 6 +++
  22. 3 files changed, 93 insertions(+)
  23. --- a/Documentation/driver-model/devres.txt
  24. +++ b/Documentation/driver-model/devres.txt
  25. @@ -236,6 +236,7 @@ certainly invest a bit more effort into
  26. CLOCK
  27. devm_clk_get()
  28. devm_clk_put()
  29. + devm_clk_hw_register()
  30. DMA
  31. dmam_alloc_coherent()
  32. --- a/drivers/clk/clk.c
  33. +++ b/drivers/clk/clk.c
  34. @@ -2595,6 +2595,22 @@ fail_out:
  35. }
  36. EXPORT_SYMBOL_GPL(clk_register);
  37. +/**
  38. + * clk_hw_register - register a clk_hw and return an error code
  39. + * @dev: device that is registering this clock
  40. + * @hw: link to hardware-specific clock data
  41. + *
  42. + * clk_hw_register is the primary interface for populating the clock tree with
  43. + * new clock nodes. It returns an integer equal to zero indicating success or
  44. + * less than zero indicating failure. Drivers must test for an error code after
  45. + * calling clk_hw_register().
  46. + */
  47. +int clk_hw_register(struct device *dev, struct clk_hw *hw)
  48. +{
  49. + return PTR_ERR_OR_ZERO(clk_register(dev, hw));
  50. +}
  51. +EXPORT_SYMBOL_GPL(clk_hw_register);
  52. +
  53. /* Free memory allocated for a clock. */
  54. static void __clk_release(struct kref *ref)
  55. {
  56. @@ -2696,11 +2712,26 @@ void clk_unregister(struct clk *clk)
  57. }
  58. EXPORT_SYMBOL_GPL(clk_unregister);
  59. +/**
  60. + * clk_hw_unregister - unregister a currently registered clk_hw
  61. + * @hw: hardware-specific clock data to unregister
  62. + */
  63. +void clk_hw_unregister(struct clk_hw *hw)
  64. +{
  65. + clk_unregister(hw->clk);
  66. +}
  67. +EXPORT_SYMBOL_GPL(clk_hw_unregister);
  68. +
  69. static void devm_clk_release(struct device *dev, void *res)
  70. {
  71. clk_unregister(*(struct clk **)res);
  72. }
  73. +static void devm_clk_hw_release(struct device *dev, void *res)
  74. +{
  75. + clk_hw_unregister(*(struct clk_hw **)res);
  76. +}
  77. +
  78. /**
  79. * devm_clk_register - resource managed clk_register()
  80. * @dev: device that is registering this clock
  81. @@ -2731,6 +2762,36 @@ struct clk *devm_clk_register(struct dev
  82. }
  83. EXPORT_SYMBOL_GPL(devm_clk_register);
  84. +/**
  85. + * devm_clk_hw_register - resource managed clk_hw_register()
  86. + * @dev: device that is registering this clock
  87. + * @hw: link to hardware-specific clock data
  88. + *
  89. + * Managed clk_hw_register(). Clocks returned from this function are
  90. + * automatically clk_hw_unregister()ed on driver detach. See clk_hw_register()
  91. + * for more information.
  92. + */
  93. +int devm_clk_hw_register(struct device *dev, struct clk_hw *hw)
  94. +{
  95. + struct clk_hw **hwp;
  96. + int ret;
  97. +
  98. + hwp = devres_alloc(devm_clk_hw_release, sizeof(*hwp), GFP_KERNEL);
  99. + if (!hwp)
  100. + return -ENOMEM;
  101. +
  102. + ret = clk_hw_register(dev, hw);
  103. + if (!ret) {
  104. + *hwp = hw;
  105. + devres_add(dev, hwp);
  106. + } else {
  107. + devres_free(hwp);
  108. + }
  109. +
  110. + return ret;
  111. +}
  112. +EXPORT_SYMBOL_GPL(devm_clk_hw_register);
  113. +
  114. static int devm_clk_match(struct device *dev, void *res, void *data)
  115. {
  116. struct clk *c = res;
  117. @@ -2739,6 +2800,15 @@ static int devm_clk_match(struct device
  118. return c == data;
  119. }
  120. +static int devm_clk_hw_match(struct device *dev, void *res, void *data)
  121. +{
  122. + struct clk_hw *hw = res;
  123. +
  124. + if (WARN_ON(!hw))
  125. + return 0;
  126. + return hw == data;
  127. +}
  128. +
  129. /**
  130. * devm_clk_unregister - resource managed clk_unregister()
  131. * @clk: clock to unregister
  132. @@ -2753,6 +2823,22 @@ void devm_clk_unregister(struct device *
  133. }
  134. EXPORT_SYMBOL_GPL(devm_clk_unregister);
  135. +/**
  136. + * devm_clk_hw_unregister - resource managed clk_hw_unregister()
  137. + * @dev: device that is unregistering the hardware-specific clock data
  138. + * @hw: link to hardware-specific clock data
  139. + *
  140. + * Unregister a clk_hw registered with devm_clk_hw_register(). Normally
  141. + * this function will not need to be called and the resource management
  142. + * code will ensure that the resource is freed.
  143. + */
  144. +void devm_clk_hw_unregister(struct device *dev, struct clk_hw *hw)
  145. +{
  146. + WARN_ON(devres_release(dev, devm_clk_hw_release, devm_clk_hw_match,
  147. + hw));
  148. +}
  149. +EXPORT_SYMBOL_GPL(devm_clk_hw_unregister);
  150. +
  151. /*
  152. * clkdev helpers
  153. */
  154. --- a/include/linux/clk-provider.h
  155. +++ b/include/linux/clk-provider.h
  156. @@ -639,9 +639,15 @@ void of_gpio_mux_clk_setup(struct device
  157. struct clk *clk_register(struct device *dev, struct clk_hw *hw);
  158. struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw);
  159. +int __must_check clk_hw_register(struct device *dev, struct clk_hw *hw);
  160. +int __must_check devm_clk_hw_register(struct device *dev, struct clk_hw *hw);
  161. +
  162. void clk_unregister(struct clk *clk);
  163. void devm_clk_unregister(struct device *dev, struct clk *clk);
  164. +void clk_hw_unregister(struct clk_hw *hw);
  165. +void devm_clk_hw_unregister(struct device *dev, struct clk_hw *hw);
  166. +
  167. /* helper functions */
  168. const char *__clk_get_name(const struct clk *clk);
  169. const char *clk_hw_get_name(const struct clk_hw *hw);