aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Boyd <sboyd@kernel.org>2019-03-08 13:35:01 -0500
committerStephen Boyd <sboyd@kernel.org>2019-03-08 13:35:01 -0500
commit5dc7e84268f53f08251abe1d388a019f55ddb077 (patch)
tree6f2bd70a3e7c9f00071dca20d0714a692de74c3c
parentfea0b0850aad878391b1021b3b1b4044c4ec5aaf (diff)
parentcf13f2896807d516df79d118d1e82f9d2db3c336 (diff)
Merge branch 'clk-parent-rewrite' (early part) into clk-next
* 'clk-parent-rewrite' (early part): clk: Move of_clk_*() APIs into clk.c from clkdev.c clk: Inform the core about consumer devices clk: Introduce of_clk_get_hw_from_clkspec() clk: core: clarify the check for runtime PM clk: Combine __clk_get() and __clk_create_clk()
-rw-r--r--drivers/clk/clk.c259
-rw-r--r--drivers/clk/clk.h23
-rw-r--r--drivers/clk/clkdev.c126
3 files changed, 230 insertions, 178 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index af3882f04080..14cbf239d9b2 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -57,6 +57,7 @@ struct clk_core {
57 struct clk_core *new_child; 57 struct clk_core *new_child;
58 unsigned long flags; 58 unsigned long flags;
59 bool orphan; 59 bool orphan;
60 bool rpm_enabled;
60 unsigned int enable_count; 61 unsigned int enable_count;
61 unsigned int prepare_count; 62 unsigned int prepare_count;
62 unsigned int protect_count; 63 unsigned int protect_count;
@@ -81,6 +82,7 @@ struct clk_core {
81 82
82struct clk { 83struct clk {
83 struct clk_core *core; 84 struct clk_core *core;
85 struct device *dev;
84 const char *dev_id; 86 const char *dev_id;
85 const char *con_id; 87 const char *con_id;
86 unsigned long min_rate; 88 unsigned long min_rate;
@@ -92,9 +94,9 @@ struct clk {
92/*** runtime pm ***/ 94/*** runtime pm ***/
93static int clk_pm_runtime_get(struct clk_core *core) 95static int clk_pm_runtime_get(struct clk_core *core)
94{ 96{
95 int ret = 0; 97 int ret;
96 98
97 if (!core->dev) 99 if (!core->rpm_enabled)
98 return 0; 100 return 0;
99 101
100 ret = pm_runtime_get_sync(core->dev); 102 ret = pm_runtime_get_sync(core->dev);
@@ -103,7 +105,7 @@ static int clk_pm_runtime_get(struct clk_core *core)
103 105
104static void clk_pm_runtime_put(struct clk_core *core) 106static void clk_pm_runtime_put(struct clk_core *core)
105{ 107{
106 if (!core->dev) 108 if (!core->rpm_enabled)
107 return; 109 return;
108 110
109 pm_runtime_put_sync(core->dev); 111 pm_runtime_put_sync(core->dev);
@@ -223,7 +225,7 @@ static bool clk_core_is_enabled(struct clk_core *core)
223 * taking enable spinlock, but the below check is needed if one tries 225 * taking enable spinlock, but the below check is needed if one tries
224 * to call it from other places. 226 * to call it from other places.
225 */ 227 */
226 if (core->dev) { 228 if (core->rpm_enabled) {
227 pm_runtime_get_noresume(core->dev); 229 pm_runtime_get_noresume(core->dev);
228 if (!pm_runtime_active(core->dev)) { 230 if (!pm_runtime_active(core->dev)) {
229 ret = false; 231 ret = false;
@@ -233,7 +235,7 @@ static bool clk_core_is_enabled(struct clk_core *core)
233 235
234 ret = core->ops->is_enabled(core->hw); 236 ret = core->ops->is_enabled(core->hw);
235done: 237done:
236 if (core->dev) 238 if (core->rpm_enabled)
237 pm_runtime_put(core->dev); 239 pm_runtime_put(core->dev);
238 240
239 return ret; 241 return ret;
@@ -3212,43 +3214,106 @@ unlock:
3212 return ret; 3214 return ret;
3213} 3215}
3214 3216
3215struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id, 3217/**
3218 * clk_core_link_consumer - Add a clk consumer to the list of consumers in a clk_core
3219 * @core: clk to add consumer to
3220 * @clk: consumer to link to a clk
3221 */
3222static void clk_core_link_consumer(struct clk_core *core, struct clk *clk)
3223{
3224 clk_prepare_lock();
3225 hlist_add_head(&clk->clks_node, &core->clks);
3226 clk_prepare_unlock();
3227}
3228
3229/**
3230 * clk_core_unlink_consumer - Remove a clk consumer from the list of consumers in a clk_core
3231 * @clk: consumer to unlink
3232 */
3233static void clk_core_unlink_consumer(struct clk *clk)
3234{
3235 lockdep_assert_held(&prepare_lock);
3236 hlist_del(&clk->clks_node);
3237}
3238
3239/**
3240 * alloc_clk - Allocate a clk consumer, but leave it unlinked to the clk_core
3241 * @core: clk to allocate a consumer for
3242 * @dev_id: string describing device name
3243 * @con_id: connection ID string on device
3244 *
3245 * Returns: clk consumer left unlinked from the consumer list
3246 */
3247static struct clk *alloc_clk(struct clk_core *core, const char *dev_id,
3216 const char *con_id) 3248 const char *con_id)
3217{ 3249{
3218 struct clk *clk; 3250 struct clk *clk;
3219 3251
3220 /* This is to allow this function to be chained to others */
3221 if (IS_ERR_OR_NULL(hw))
3222 return ERR_CAST(hw);
3223
3224 clk = kzalloc(sizeof(*clk), GFP_KERNEL); 3252 clk = kzalloc(sizeof(*clk), GFP_KERNEL);
3225 if (!clk) 3253 if (!clk)
3226 return ERR_PTR(-ENOMEM); 3254 return ERR_PTR(-ENOMEM);
3227 3255
3228 clk->core = hw->core; 3256 clk->core = core;
3229 clk->dev_id = dev_id; 3257 clk->dev_id = dev_id;
3230 clk->con_id = kstrdup_const(con_id, GFP_KERNEL); 3258 clk->con_id = kstrdup_const(con_id, GFP_KERNEL);
3231 clk->max_rate = ULONG_MAX; 3259 clk->max_rate = ULONG_MAX;
3232 3260
3233 clk_prepare_lock();
3234 hlist_add_head(&clk->clks_node, &hw->core->clks);
3235 clk_prepare_unlock();
3236
3237 return clk; 3261 return clk;
3238} 3262}
3239 3263
3240/* keep in sync with __clk_put */ 3264/**
3241void __clk_free_clk(struct clk *clk) 3265 * free_clk - Free a clk consumer
3266 * @clk: clk consumer to free
3267 *
3268 * Note, this assumes the clk has been unlinked from the clk_core consumer
3269 * list.
3270 */
3271static void free_clk(struct clk *clk)
3242{ 3272{
3243 clk_prepare_lock();
3244 hlist_del(&clk->clks_node);
3245 clk_prepare_unlock();
3246
3247 kfree_const(clk->con_id); 3273 kfree_const(clk->con_id);
3248 kfree(clk); 3274 kfree(clk);
3249} 3275}
3250 3276
3251/** 3277/**
3278 * clk_hw_create_clk: Allocate and link a clk consumer to a clk_core given
3279 * a clk_hw
3280 * @dev: clk consumer device
3281 * @hw: clk_hw associated with the clk being consumed
3282 * @dev_id: string describing device name
3283 * @con_id: connection ID string on device
3284 *
3285 * This is the main function used to create a clk pointer for use by clk
3286 * consumers. It connects a consumer to the clk_core and clk_hw structures
3287 * used by the framework and clk provider respectively.
3288 */
3289struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw,
3290 const char *dev_id, const char *con_id)
3291{
3292 struct clk *clk;
3293 struct clk_core *core;
3294
3295 /* This is to allow this function to be chained to others */
3296 if (IS_ERR_OR_NULL(hw))
3297 return ERR_CAST(hw);
3298
3299 core = hw->core;
3300 clk = alloc_clk(core, dev_id, con_id);
3301 if (IS_ERR(clk))
3302 return clk;
3303 clk->dev = dev;
3304
3305 if (!try_module_get(core->owner)) {
3306 free_clk(clk);
3307 return ERR_PTR(-ENOENT);
3308 }
3309
3310 kref_get(&core->ref);
3311 clk_core_link_consumer(core, clk);
3312
3313 return clk;
3314}
3315
3316/**
3252 * clk_register - allocate a new clock, register it and return an opaque cookie 3317 * clk_register - allocate a new clock, register it and return an opaque cookie
3253 * @dev: device that is registering this clock 3318 * @dev: device that is registering this clock
3254 * @hw: link to hardware-specific clock data 3319 * @hw: link to hardware-specific clock data
@@ -3283,7 +3348,8 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
3283 core->ops = hw->init->ops; 3348 core->ops = hw->init->ops;
3284 3349
3285 if (dev && pm_runtime_enabled(dev)) 3350 if (dev && pm_runtime_enabled(dev))
3286 core->dev = dev; 3351 core->rpm_enabled = true;
3352 core->dev = dev;
3287 if (dev && dev->driver) 3353 if (dev && dev->driver)
3288 core->owner = dev->driver->owner; 3354 core->owner = dev->driver->owner;
3289 core->hw = hw; 3355 core->hw = hw;
@@ -3323,17 +3389,27 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
3323 3389
3324 INIT_HLIST_HEAD(&core->clks); 3390 INIT_HLIST_HEAD(&core->clks);
3325 3391
3326 hw->clk = __clk_create_clk(hw, NULL, NULL); 3392 /*
3393 * Don't call clk_hw_create_clk() here because that would pin the
3394 * provider module to itself and prevent it from ever being removed.
3395 */
3396 hw->clk = alloc_clk(core, NULL, NULL);
3327 if (IS_ERR(hw->clk)) { 3397 if (IS_ERR(hw->clk)) {
3328 ret = PTR_ERR(hw->clk); 3398 ret = PTR_ERR(hw->clk);
3329 goto fail_parents; 3399 goto fail_parents;
3330 } 3400 }
3331 3401
3402 clk_core_link_consumer(hw->core, hw->clk);
3403
3332 ret = __clk_core_init(core); 3404 ret = __clk_core_init(core);
3333 if (!ret) 3405 if (!ret)
3334 return hw->clk; 3406 return hw->clk;
3335 3407
3336 __clk_free_clk(hw->clk); 3408 clk_prepare_lock();
3409 clk_core_unlink_consumer(hw->clk);
3410 clk_prepare_unlock();
3411
3412 free_clk(hw->clk);
3337 hw->clk = NULL; 3413 hw->clk = NULL;
3338 3414
3339fail_parents: 3415fail_parents:
@@ -3604,20 +3680,7 @@ EXPORT_SYMBOL_GPL(devm_clk_hw_unregister);
3604/* 3680/*
3605 * clkdev helpers 3681 * clkdev helpers
3606 */ 3682 */
3607int __clk_get(struct clk *clk)
3608{
3609 struct clk_core *core = !clk ? NULL : clk->core;
3610
3611 if (core) {
3612 if (!try_module_get(core->owner))
3613 return 0;
3614 3683
3615 kref_get(&core->ref);
3616 }
3617 return 1;
3618}
3619
3620/* keep in sync with __clk_free_clk */
3621void __clk_put(struct clk *clk) 3684void __clk_put(struct clk *clk)
3622{ 3685{
3623 struct module *owner; 3686 struct module *owner;
@@ -3651,8 +3714,7 @@ void __clk_put(struct clk *clk)
3651 3714
3652 module_put(owner); 3715 module_put(owner);
3653 3716
3654 kfree_const(clk->con_id); 3717 free_clk(clk);
3655 kfree(clk);
3656} 3718}
3657 3719
3658/*** clk rate change notifiers ***/ 3720/*** clk rate change notifiers ***/
@@ -4009,6 +4071,49 @@ void devm_of_clk_del_provider(struct device *dev)
4009} 4071}
4010EXPORT_SYMBOL(devm_of_clk_del_provider); 4072EXPORT_SYMBOL(devm_of_clk_del_provider);
4011 4073
4074/*
4075 * Beware the return values when np is valid, but no clock provider is found.
4076 * If name == NULL, the function returns -ENOENT.
4077 * If name != NULL, the function returns -EINVAL. This is because
4078 * of_parse_phandle_with_args() is called even if of_property_match_string()
4079 * returns an error.
4080 */
4081static int of_parse_clkspec(const struct device_node *np, int index,
4082 const char *name, struct of_phandle_args *out_args)
4083{
4084 int ret = -ENOENT;
4085
4086 /* Walk up the tree of devices looking for a clock property that matches */
4087 while (np) {
4088 /*
4089 * For named clocks, first look up the name in the
4090 * "clock-names" property. If it cannot be found, then index
4091 * will be an error code and of_parse_phandle_with_args() will
4092 * return -EINVAL.
4093 */
4094 if (name)
4095 index = of_property_match_string(np, "clock-names", name);
4096 ret = of_parse_phandle_with_args(np, "clocks", "#clock-cells",
4097 index, out_args);
4098 if (!ret)
4099 break;
4100 if (name && index >= 0)
4101 break;
4102
4103 /*
4104 * No matching clock found on this node. If the parent node
4105 * has a "clock-ranges" property, then we can try one of its
4106 * clocks.
4107 */
4108 np = np->parent;
4109 if (np && !of_get_property(np, "clock-ranges", NULL))
4110 break;
4111 index = 0;
4112 }
4113
4114 return ret;
4115}
4116
4012static struct clk_hw * 4117static struct clk_hw *
4013__of_clk_get_hw_from_provider(struct of_clk_provider *provider, 4118__of_clk_get_hw_from_provider(struct of_clk_provider *provider,
4014 struct of_phandle_args *clkspec) 4119 struct of_phandle_args *clkspec)
@@ -4024,36 +4129,26 @@ __of_clk_get_hw_from_provider(struct of_clk_provider *provider,
4024 return __clk_get_hw(clk); 4129 return __clk_get_hw(clk);
4025} 4130}
4026 4131
4027struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec, 4132static struct clk_hw *
4028 const char *dev_id, const char *con_id) 4133of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec)
4029{ 4134{
4030 struct of_clk_provider *provider; 4135 struct of_clk_provider *provider;
4031 struct clk *clk = ERR_PTR(-EPROBE_DEFER); 4136 struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER);
4032 struct clk_hw *hw;
4033 4137
4034 if (!clkspec) 4138 if (!clkspec)
4035 return ERR_PTR(-EINVAL); 4139 return ERR_PTR(-EINVAL);
4036 4140
4037 /* Check if we have such a provider in our array */
4038 mutex_lock(&of_clk_mutex); 4141 mutex_lock(&of_clk_mutex);
4039 list_for_each_entry(provider, &of_clk_providers, link) { 4142 list_for_each_entry(provider, &of_clk_providers, link) {
4040 if (provider->node == clkspec->np) { 4143 if (provider->node == clkspec->np) {
4041 hw = __of_clk_get_hw_from_provider(provider, clkspec); 4144 hw = __of_clk_get_hw_from_provider(provider, clkspec);
4042 clk = __clk_create_clk(hw, dev_id, con_id); 4145 if (!IS_ERR(hw))
4043 } 4146 break;
4044
4045 if (!IS_ERR(clk)) {
4046 if (!__clk_get(clk)) {
4047 __clk_free_clk(clk);
4048 clk = ERR_PTR(-ENOENT);
4049 }
4050
4051 break;
4052 } 4147 }
4053 } 4148 }
4054 mutex_unlock(&of_clk_mutex); 4149 mutex_unlock(&of_clk_mutex);
4055 4150
4056 return clk; 4151 return hw;
4057} 4152}
4058 4153
4059/** 4154/**
@@ -4066,10 +4161,62 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
4066 */ 4161 */
4067struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec) 4162struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
4068{ 4163{
4069 return __of_clk_get_from_provider(clkspec, NULL, __func__); 4164 struct clk_hw *hw = of_clk_get_hw_from_clkspec(clkspec);
4165
4166 return clk_hw_create_clk(NULL, hw, NULL, __func__);
4070} 4167}
4071EXPORT_SYMBOL_GPL(of_clk_get_from_provider); 4168EXPORT_SYMBOL_GPL(of_clk_get_from_provider);
4072 4169
4170struct clk_hw *of_clk_get_hw(struct device_node *np, int index,
4171 const char *con_id)
4172{
4173 int ret;
4174 struct clk_hw *hw;
4175 struct of_phandle_args clkspec;
4176
4177 ret = of_parse_clkspec(np, index, con_id, &clkspec);
4178 if (ret)
4179 return ERR_PTR(ret);
4180
4181 hw = of_clk_get_hw_from_clkspec(&clkspec);
4182 of_node_put(clkspec.np);
4183
4184 return hw;
4185}
4186
4187static struct clk *__of_clk_get(struct device_node *np,
4188 int index, const char *dev_id,
4189 const char *con_id)
4190{
4191 struct clk_hw *hw = of_clk_get_hw(np, index, con_id);
4192
4193 return clk_hw_create_clk(NULL, hw, dev_id, con_id);
4194}
4195
4196struct clk *of_clk_get(struct device_node *np, int index)
4197{
4198 return __of_clk_get(np, index, np->full_name, NULL);
4199}
4200EXPORT_SYMBOL(of_clk_get);
4201
4202/**
4203 * of_clk_get_by_name() - Parse and lookup a clock referenced by a device node
4204 * @np: pointer to clock consumer node
4205 * @name: name of consumer's clock input, or NULL for the first clock reference
4206 *
4207 * This function parses the clocks and clock-names properties,
4208 * and uses them to look up the struct clk from the registered list of clock
4209 * providers.
4210 */
4211struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
4212{
4213 if (!np)
4214 return ERR_PTR(-ENOENT);
4215
4216 return __of_clk_get(np, -1, np->full_name, name);
4217}
4218EXPORT_SYMBOL(of_clk_get_by_name);
4219
4073/** 4220/**
4074 * of_clk_get_parent_count() - Count the number of clocks a device node has 4221 * of_clk_get_parent_count() - Count the number of clocks a device node has
4075 * @np: device node to count 4222 * @np: device node to count
diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h
index b02f5e604e69..553f531cc232 100644
--- a/drivers/clk/clk.h
+++ b/drivers/clk/clk.h
@@ -5,31 +5,36 @@
5 */ 5 */
6 6
7struct clk_hw; 7struct clk_hw;
8struct device;
9struct of_phandle_args;
8 10
9#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) 11#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
10struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec, 12struct clk_hw *of_clk_get_hw(struct device_node *np,
11 const char *dev_id, const char *con_id); 13 int index, const char *con_id);
14#else /* !CONFIG_COMMON_CLK || !CONFIG_OF */
15static inline struct clk_hw *of_clk_get_hw(struct device_node *np,
16 int index, const char *con_id)
17{
18 return ERR_PTR(-ENOENT);
19}
12#endif 20#endif
13 21
14#ifdef CONFIG_COMMON_CLK 22#ifdef CONFIG_COMMON_CLK
15struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id, 23struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw,
16 const char *con_id); 24 const char *dev_id, const char *con_id);
17void __clk_free_clk(struct clk *clk);
18int __clk_get(struct clk *clk);
19void __clk_put(struct clk *clk); 25void __clk_put(struct clk *clk);
20#else 26#else
21/* All these casts to avoid ifdefs in clkdev... */ 27/* All these casts to avoid ifdefs in clkdev... */
22static inline struct clk * 28static inline struct clk *
23__clk_create_clk(struct clk_hw *hw, const char *dev_id, const char *con_id) 29clk_hw_create_clk(struct device *dev, struct clk_hw *hw, const char *dev_id,
30 const char *con_id)
24{ 31{
25 return (struct clk *)hw; 32 return (struct clk *)hw;
26} 33}
27static inline void __clk_free_clk(struct clk *clk) { }
28static struct clk_hw *__clk_get_hw(struct clk *clk) 34static struct clk_hw *__clk_get_hw(struct clk *clk)
29{ 35{
30 return (struct clk_hw *)clk; 36 return (struct clk_hw *)clk;
31} 37}
32static inline int __clk_get(struct clk *clk) { return 1; }
33static inline void __clk_put(struct clk *clk) { } 38static inline void __clk_put(struct clk *clk) { }
34 39
35#endif 40#endif
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 4cfe39636105..8c4435c53f09 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -27,105 +27,6 @@
27static LIST_HEAD(clocks); 27static LIST_HEAD(clocks);
28static DEFINE_MUTEX(clocks_mutex); 28static DEFINE_MUTEX(clocks_mutex);
29 29
30#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
31static struct clk *__of_clk_get(struct device_node *np, int index,
32 const char *dev_id, const char *con_id)
33{
34 struct of_phandle_args clkspec;
35 struct clk *clk;
36 int rc;
37
38 rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", index,
39 &clkspec);
40 if (rc)
41 return ERR_PTR(rc);
42
43 clk = __of_clk_get_from_provider(&clkspec, dev_id, con_id);
44 of_node_put(clkspec.np);
45
46 return clk;
47}
48
49struct clk *of_clk_get(struct device_node *np, int index)
50{
51 return __of_clk_get(np, index, np->full_name, NULL);
52}
53EXPORT_SYMBOL(of_clk_get);
54
55/*
56 * Beware the return values when np is valid, but no clock provider is found.
57 * If name == NULL, the function returns -ENOENT.
58 * If name != NULL, the function returns -EINVAL. This is because __of_clk_get()
59 * is called even if of_property_match_string() returns an error.
60 */
61static struct clk *__of_clk_get_by_name(struct device_node *np,
62 const char *dev_id,
63 const char *name)
64{
65 struct clk *clk = ERR_PTR(-ENOENT);
66
67 /* Walk up the tree of devices looking for a clock that matches */
68 while (np) {
69 int index = 0;
70
71 /*
72 * For named clocks, first look up the name in the
73 * "clock-names" property. If it cannot be found, then
74 * index will be an error code, and of_clk_get() will fail.
75 */
76 if (name)
77 index = of_property_match_string(np, "clock-names", name);
78 clk = __of_clk_get(np, index, dev_id, name);
79 if (!IS_ERR(clk)) {
80 break;
81 } else if (name && index >= 0) {
82 if (PTR_ERR(clk) != -EPROBE_DEFER)
83 pr_err("ERROR: could not get clock %pOF:%s(%i)\n",
84 np, name ? name : "", index);
85 return clk;
86 }
87
88 /*
89 * No matching clock found on this node. If the parent node
90 * has a "clock-ranges" property, then we can try one of its
91 * clocks.
92 */
93 np = np->parent;
94 if (np && !of_get_property(np, "clock-ranges", NULL))
95 break;
96 }
97
98 return clk;
99}
100
101/**
102 * of_clk_get_by_name() - Parse and lookup a clock referenced by a device node
103 * @np: pointer to clock consumer node
104 * @name: name of consumer's clock input, or NULL for the first clock reference
105 *
106 * This function parses the clocks and clock-names properties,
107 * and uses them to look up the struct clk from the registered list of clock
108 * providers.
109 */
110struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
111{
112 if (!np)
113 return ERR_PTR(-ENOENT);
114
115 return __of_clk_get_by_name(np, np->full_name, name);
116}
117EXPORT_SYMBOL(of_clk_get_by_name);
118
119#else /* defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) */
120
121static struct clk *__of_clk_get_by_name(struct device_node *np,
122 const char *dev_id,
123 const char *name)
124{
125 return ERR_PTR(-ENOENT);
126}
127#endif
128
129/* 30/*
130 * Find the correct struct clk for the device and connection ID. 31 * Find the correct struct clk for the device and connection ID.
131 * We do slightly fuzzy matching here: 32 * We do slightly fuzzy matching here:
@@ -169,7 +70,8 @@ static struct clk_lookup *clk_find(const char *dev_id, const char *con_id)
169 return cl; 70 return cl;
170} 71}
171 72
172struct clk *clk_get_sys(const char *dev_id, const char *con_id) 73static struct clk *__clk_get_sys(struct device *dev, const char *dev_id,
74 const char *con_id)
173{ 75{
174 struct clk_lookup *cl; 76 struct clk_lookup *cl;
175 struct clk *clk = NULL; 77 struct clk *clk = NULL;
@@ -180,35 +82,33 @@ struct clk *clk_get_sys(const char *dev_id, const char *con_id)
180 if (!cl) 82 if (!cl)
181 goto out; 83 goto out;
182 84
183 clk = __clk_create_clk(cl->clk_hw, dev_id, con_id); 85 clk = clk_hw_create_clk(dev, cl->clk_hw, dev_id, con_id);
184 if (IS_ERR(clk)) 86 if (IS_ERR(clk))
185 goto out;
186
187 if (!__clk_get(clk)) {
188 __clk_free_clk(clk);
189 cl = NULL; 87 cl = NULL;
190 goto out;
191 }
192
193out: 88out:
194 mutex_unlock(&clocks_mutex); 89 mutex_unlock(&clocks_mutex);
195 90
196 return cl ? clk : ERR_PTR(-ENOENT); 91 return cl ? clk : ERR_PTR(-ENOENT);
197} 92}
93
94struct clk *clk_get_sys(const char *dev_id, const char *con_id)
95{
96 return __clk_get_sys(NULL, dev_id, con_id);
97}
198EXPORT_SYMBOL(clk_get_sys); 98EXPORT_SYMBOL(clk_get_sys);
199 99
200struct clk *clk_get(struct device *dev, const char *con_id) 100struct clk *clk_get(struct device *dev, const char *con_id)
201{ 101{
202 const char *dev_id = dev ? dev_name(dev) : NULL; 102 const char *dev_id = dev ? dev_name(dev) : NULL;
203 struct clk *clk; 103 struct clk_hw *hw;
204 104
205 if (dev && dev->of_node) { 105 if (dev && dev->of_node) {
206 clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id); 106 hw = of_clk_get_hw(dev->of_node, 0, con_id);
207 if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER) 107 if (!IS_ERR(hw) || PTR_ERR(hw) == -EPROBE_DEFER)
208 return clk; 108 return clk_hw_create_clk(dev, hw, dev_id, con_id);
209 } 109 }
210 110
211 return clk_get_sys(dev_id, con_id); 111 return __clk_get_sys(dev, dev_id, con_id);
212} 112}
213EXPORT_SYMBOL(clk_get); 113EXPORT_SYMBOL(clk_get);
214 114