summaryrefslogtreecommitdiffstats
path: root/drivers/clk/clk.c
diff options
context:
space:
mode:
authorStephen Boyd <sboyd@kernel.org>2018-12-11 11:32:04 -0500
committerStephen Boyd <sboyd@kernel.org>2019-03-01 14:16:14 -0500
commit1df4046a93e086f77d244ea47c21591b4acad3e2 (patch)
tree47ee347de39b70442db6653adc1fa581b4cede59 /drivers/clk/clk.c
parentd13937116f1e82bf508a6325111b322c30c85eb9 (diff)
clk: Combine __clk_get() and __clk_create_clk()
The __clk_get() function is practically a private clk implementation detail now. No architecture defines it, and given that new code should be using the common clk framework there isn't a need for it to keep existing just to serve clkdev purposes. Let's fold it into the __clk_create_clk() function and make that a little more generic by renaming it to clk_hw_create_clk(). This will allow the framework to create a struct clk handle to a particular clk_hw pointer and link it up as a consumer wherever that's needed. Doing this also lets us get rid of the __clk_free_clk() API that had to be kept in sync with __clk_put(). Splitting that API up into the "link and unlink from consumer list" phase and "free the clk pointer" phase allows us to reuse that logic in a couple places, simplifying the code. Cc: Miquel Raynal <miquel.raynal@bootlin.com> Cc: Jerome Brunet <jbrunet@baylibre.com> Cc: Russell King <linux@armlinux.org.uk> Cc: Michael Turquette <mturquette@baylibre.com> Cc: Jeffrey Hugo <jhugo@codeaurora.org> Cc: Chen-Yu Tsai <wens@csie.org> Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Diffstat (limited to 'drivers/clk/clk.c')
-rw-r--r--drivers/clk/clk.c140
1 files changed, 94 insertions, 46 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index d2477a5058ac..fef937ea44f4 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -3209,43 +3209,104 @@ unlock:
3209 return ret; 3209 return ret;
3210} 3210}
3211 3211
3212struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id, 3212/**
3213 * clk_core_link_consumer - Add a clk consumer to the list of consumers in a clk_core
3214 * @core: clk to add consumer to
3215 * @clk: consumer to link to a clk
3216 */
3217static void clk_core_link_consumer(struct clk_core *core, struct clk *clk)
3218{
3219 clk_prepare_lock();
3220 hlist_add_head(&clk->clks_node, &core->clks);
3221 clk_prepare_unlock();
3222}
3223
3224/**
3225 * clk_core_unlink_consumer - Remove a clk consumer from the list of consumers in a clk_core
3226 * @clk: consumer to unlink
3227 */
3228static void clk_core_unlink_consumer(struct clk *clk)
3229{
3230 lockdep_assert_held(&prepare_lock);
3231 hlist_del(&clk->clks_node);
3232}
3233
3234/**
3235 * alloc_clk - Allocate a clk consumer, but leave it unlinked to the clk_core
3236 * @core: clk to allocate a consumer for
3237 * @dev_id: string describing device name
3238 * @con_id: connection ID string on device
3239 *
3240 * Returns: clk consumer left unlinked from the consumer list
3241 */
3242static struct clk *alloc_clk(struct clk_core *core, const char *dev_id,
3213 const char *con_id) 3243 const char *con_id)
3214{ 3244{
3215 struct clk *clk; 3245 struct clk *clk;
3216 3246
3217 /* This is to allow this function to be chained to others */
3218 if (IS_ERR_OR_NULL(hw))
3219 return ERR_CAST(hw);
3220
3221 clk = kzalloc(sizeof(*clk), GFP_KERNEL); 3247 clk = kzalloc(sizeof(*clk), GFP_KERNEL);
3222 if (!clk) 3248 if (!clk)
3223 return ERR_PTR(-ENOMEM); 3249 return ERR_PTR(-ENOMEM);
3224 3250
3225 clk->core = hw->core; 3251 clk->core = core;
3226 clk->dev_id = dev_id; 3252 clk->dev_id = dev_id;
3227 clk->con_id = kstrdup_const(con_id, GFP_KERNEL); 3253 clk->con_id = kstrdup_const(con_id, GFP_KERNEL);
3228 clk->max_rate = ULONG_MAX; 3254 clk->max_rate = ULONG_MAX;
3229 3255
3230 clk_prepare_lock();
3231 hlist_add_head(&clk->clks_node, &hw->core->clks);
3232 clk_prepare_unlock();
3233
3234 return clk; 3256 return clk;
3235} 3257}
3236 3258
3237/* keep in sync with __clk_put */ 3259/**
3238void __clk_free_clk(struct clk *clk) 3260 * free_clk - Free a clk consumer
3261 * @clk: clk consumer to free
3262 *
3263 * Note, this assumes the clk has been unlinked from the clk_core consumer
3264 * list.
3265 */
3266static void free_clk(struct clk *clk)
3239{ 3267{
3240 clk_prepare_lock();
3241 hlist_del(&clk->clks_node);
3242 clk_prepare_unlock();
3243
3244 kfree_const(clk->con_id); 3268 kfree_const(clk->con_id);
3245 kfree(clk); 3269 kfree(clk);
3246} 3270}
3247 3271
3248/** 3272/**
3273 * clk_hw_create_clk: Allocate and link a clk consumer to a clk_core given
3274 * a clk_hw
3275 * @hw: clk_hw associated with the clk being consumed
3276 * @dev_id: string describing device name
3277 * @con_id: connection ID string on device
3278 *
3279 * This is the main function used to create a clk pointer for use by clk
3280 * consumers. It connects a consumer to the clk_core and clk_hw structures
3281 * used by the framework and clk provider respectively.
3282 */
3283struct clk *clk_hw_create_clk(struct clk_hw *hw,
3284 const char *dev_id, const char *con_id)
3285{
3286 struct clk *clk;
3287 struct clk_core *core;
3288
3289 /* This is to allow this function to be chained to others */
3290 if (IS_ERR_OR_NULL(hw))
3291 return ERR_CAST(hw);
3292
3293 core = hw->core;
3294 clk = alloc_clk(core, dev_id, con_id);
3295 if (IS_ERR(clk))
3296 return clk;
3297
3298 if (!try_module_get(core->owner)) {
3299 free_clk(clk);
3300 return ERR_PTR(-ENOENT);
3301 }
3302
3303 kref_get(&core->ref);
3304 clk_core_link_consumer(core, clk);
3305
3306 return clk;
3307}
3308
3309/**
3249 * clk_register - allocate a new clock, register it and return an opaque cookie 3310 * clk_register - allocate a new clock, register it and return an opaque cookie
3250 * @dev: device that is registering this clock 3311 * @dev: device that is registering this clock
3251 * @hw: link to hardware-specific clock data 3312 * @hw: link to hardware-specific clock data
@@ -3320,17 +3381,27 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
3320 3381
3321 INIT_HLIST_HEAD(&core->clks); 3382 INIT_HLIST_HEAD(&core->clks);
3322 3383
3323 hw->clk = __clk_create_clk(hw, NULL, NULL); 3384 /*
3385 * Don't call clk_hw_create_clk() here because that would pin the
3386 * provider module to itself and prevent it from ever being removed.
3387 */
3388 hw->clk = alloc_clk(core, NULL, NULL);
3324 if (IS_ERR(hw->clk)) { 3389 if (IS_ERR(hw->clk)) {
3325 ret = PTR_ERR(hw->clk); 3390 ret = PTR_ERR(hw->clk);
3326 goto fail_parents; 3391 goto fail_parents;
3327 } 3392 }
3328 3393
3394 clk_core_link_consumer(hw->core, hw->clk);
3395
3329 ret = __clk_core_init(core); 3396 ret = __clk_core_init(core);
3330 if (!ret) 3397 if (!ret)
3331 return hw->clk; 3398 return hw->clk;
3332 3399
3333 __clk_free_clk(hw->clk); 3400 clk_prepare_lock();
3401 clk_core_unlink_consumer(hw->clk);
3402 clk_prepare_unlock();
3403
3404 free_clk(hw->clk);
3334 hw->clk = NULL; 3405 hw->clk = NULL;
3335 3406
3336fail_parents: 3407fail_parents:
@@ -3601,20 +3672,7 @@ EXPORT_SYMBOL_GPL(devm_clk_hw_unregister);
3601/* 3672/*
3602 * clkdev helpers 3673 * clkdev helpers
3603 */ 3674 */
3604int __clk_get(struct clk *clk)
3605{
3606 struct clk_core *core = !clk ? NULL : clk->core;
3607
3608 if (core) {
3609 if (!try_module_get(core->owner))
3610 return 0;
3611
3612 kref_get(&core->ref);
3613 }
3614 return 1;
3615}
3616 3675
3617/* keep in sync with __clk_free_clk */
3618void __clk_put(struct clk *clk) 3676void __clk_put(struct clk *clk)
3619{ 3677{
3620 struct module *owner; 3678 struct module *owner;
@@ -3648,8 +3706,7 @@ void __clk_put(struct clk *clk)
3648 3706
3649 module_put(owner); 3707 module_put(owner);
3650 3708
3651 kfree_const(clk->con_id); 3709 free_clk(clk);
3652 kfree(clk);
3653} 3710}
3654 3711
3655/*** clk rate change notifiers ***/ 3712/*** clk rate change notifiers ***/
@@ -4025,8 +4082,7 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
4025 const char *dev_id, const char *con_id) 4082 const char *dev_id, const char *con_id)
4026{ 4083{
4027 struct of_clk_provider *provider; 4084 struct of_clk_provider *provider;
4028 struct clk *clk = ERR_PTR(-EPROBE_DEFER); 4085 struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER);
4029 struct clk_hw *hw;
4030 4086
4031 if (!clkspec) 4087 if (!clkspec)
4032 return ERR_PTR(-EINVAL); 4088 return ERR_PTR(-EINVAL);
@@ -4036,21 +4092,13 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
4036 list_for_each_entry(provider, &of_clk_providers, link) { 4092 list_for_each_entry(provider, &of_clk_providers, link) {
4037 if (provider->node == clkspec->np) { 4093 if (provider->node == clkspec->np) {
4038 hw = __of_clk_get_hw_from_provider(provider, clkspec); 4094 hw = __of_clk_get_hw_from_provider(provider, clkspec);
4039 clk = __clk_create_clk(hw, dev_id, con_id); 4095 if (!IS_ERR(hw))
4040 } 4096 break;
4041
4042 if (!IS_ERR(clk)) {
4043 if (!__clk_get(clk)) {
4044 __clk_free_clk(clk);
4045 clk = ERR_PTR(-ENOENT);
4046 }
4047
4048 break;
4049 } 4097 }
4050 } 4098 }
4051 mutex_unlock(&of_clk_mutex); 4099 mutex_unlock(&of_clk_mutex);
4052 4100
4053 return clk; 4101 return clk_hw_create_clk(hw, dev_id, con_id);
4054} 4102}
4055 4103
4056/** 4104/**