Skip to content

Commit 1df4046

Browse files
committed
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>
1 parent d139371 commit 1df4046

File tree

3 files changed

+98
-61
lines changed

3 files changed

+98
-61
lines changed

drivers/clk/clk.c

Lines changed: 94 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3209,42 +3209,103 @@ static int __clk_core_init(struct clk_core *core)
32093209
return ret;
32103210
}
32113211

3212-
struct 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+
*/
3217+
static 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+
*/
3228+
static 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+
*/
3242+
static struct clk *alloc_clk(struct clk_core *core, const char *dev_id,
32133243
const char *con_id)
32143244
{
32153245
struct clk *clk;
32163246

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-
32213247
clk = kzalloc(sizeof(*clk), GFP_KERNEL);
32223248
if (!clk)
32233249
return ERR_PTR(-ENOMEM);
32243250

3225-
clk->core = hw->core;
3251+
clk->core = core;
32263252
clk->dev_id = dev_id;
32273253
clk->con_id = kstrdup_const(con_id, GFP_KERNEL);
32283254
clk->max_rate = ULONG_MAX;
32293255

3230-
clk_prepare_lock();
3231-
hlist_add_head(&clk->clks_node, &hw->core->clks);
3232-
clk_prepare_unlock();
3233-
32343256
return clk;
32353257
}
32363258

3237-
/* keep in sync with __clk_put */
3238-
void __clk_free_clk(struct clk *clk)
3259+
/**
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+
*/
3266+
static void free_clk(struct clk *clk)
32393267
{
3240-
clk_prepare_lock();
3241-
hlist_del(&clk->clks_node);
3242-
clk_prepare_unlock();
3243-
32443268
kfree_const(clk->con_id);
32453269
kfree(clk);
32463270
}
32473271

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+
*/
3283+
struct 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+
32483309
/**
32493310
* clk_register - allocate a new clock, register it and return an opaque cookie
32503311
* @dev: device that is registering this clock
@@ -3320,17 +3381,27 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
33203381

33213382
INIT_HLIST_HEAD(&core->clks);
33223383

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);
33243389
if (IS_ERR(hw->clk)) {
33253390
ret = PTR_ERR(hw->clk);
33263391
goto fail_parents;
33273392
}
33283393

3394+
clk_core_link_consumer(hw->core, hw->clk);
3395+
33293396
ret = __clk_core_init(core);
33303397
if (!ret)
33313398
return hw->clk;
33323399

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);
33343405
hw->clk = NULL;
33353406

33363407
fail_parents:
@@ -3601,20 +3672,7 @@ EXPORT_SYMBOL_GPL(devm_clk_hw_unregister);
36013672
/*
36023673
* clkdev helpers
36033674
*/
3604-
int __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-
}
36163675

3617-
/* keep in sync with __clk_free_clk */
36183676
void __clk_put(struct clk *clk)
36193677
{
36203678
struct module *owner;
@@ -3648,8 +3706,7 @@ void __clk_put(struct clk *clk)
36483706

36493707
module_put(owner);
36503708

3651-
kfree_const(clk->con_id);
3652-
kfree(clk);
3709+
free_clk(clk);
36533710
}
36543711

36553712
/*** clk rate change notifiers ***/
@@ -4025,8 +4082,7 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
40254082
const char *dev_id, const char *con_id)
40264083
{
40274084
struct of_clk_provider *provider;
4028-
struct clk *clk = ERR_PTR(-EPROBE_DEFER);
4029-
struct clk_hw *hw;
4085+
struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER);
40304086

40314087
if (!clkspec)
40324088
return ERR_PTR(-EINVAL);
@@ -4036,21 +4092,13 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
40364092
list_for_each_entry(provider, &of_clk_providers, link) {
40374093
if (provider->node == clkspec->np) {
40384094
hw = __of_clk_get_hw_from_provider(provider, clkspec);
4039-
clk = __clk_create_clk(hw, dev_id, con_id);
4040-
}
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;
4095+
if (!IS_ERR(hw))
4096+
break;
40494097
}
40504098
}
40514099
mutex_unlock(&of_clk_mutex);
40524100

4053-
return clk;
4101+
return clk_hw_create_clk(hw, dev_id, con_id);
40544102
}
40554103

40564104
/**

drivers/clk/clk.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,20 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
1212
#endif
1313

1414
#ifdef CONFIG_COMMON_CLK
15-
struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id,
16-
const char *con_id);
17-
void __clk_free_clk(struct clk *clk);
18-
int __clk_get(struct clk *clk);
15+
struct clk *clk_hw_create_clk(struct clk_hw *hw,
16+
const char *dev_id, const char *con_id);
1917
void __clk_put(struct clk *clk);
2018
#else
2119
/* All these casts to avoid ifdefs in clkdev... */
2220
static inline struct clk *
23-
__clk_create_clk(struct clk_hw *hw, const char *dev_id, const char *con_id)
21+
clk_hw_create_clk(struct clk_hw *hw, const char *dev_id, const char *con_id)
2422
{
2523
return (struct clk *)hw;
2624
}
27-
static inline void __clk_free_clk(struct clk *clk) { }
2825
static struct clk_hw *__clk_get_hw(struct clk *clk)
2926
{
3027
return (struct clk_hw *)clk;
3128
}
32-
static inline int __clk_get(struct clk *clk) { return 1; }
3329
static inline void __clk_put(struct clk *clk) { }
3430

3531
#endif

drivers/clk/clkdev.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -174,16 +174,9 @@ struct clk *clk_get_sys(const char *dev_id, const char *con_id)
174174
if (!cl)
175175
goto out;
176176

177-
clk = __clk_create_clk(cl->clk_hw, dev_id, con_id);
177+
clk = clk_hw_create_clk(cl->clk_hw, dev_id, con_id);
178178
if (IS_ERR(clk))
179-
goto out;
180-
181-
if (!__clk_get(clk)) {
182-
__clk_free_clk(clk);
183179
cl = NULL;
184-
goto out;
185-
}
186-
187180
out:
188181
mutex_unlock(&clocks_mutex);
189182

0 commit comments

Comments
 (0)