diff options
author | Stephen Boyd <sboyd@kernel.org> | 2019-03-08 13:35:01 -0500 |
---|---|---|
committer | Stephen Boyd <sboyd@kernel.org> | 2019-03-08 13:35:01 -0500 |
commit | 5dc7e84268f53f08251abe1d388a019f55ddb077 (patch) | |
tree | 6f2bd70a3e7c9f00071dca20d0714a692de74c3c | |
parent | fea0b0850aad878391b1021b3b1b4044c4ec5aaf (diff) | |
parent | cf13f2896807d516df79d118d1e82f9d2db3c336 (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.c | 259 | ||||
-rw-r--r-- | drivers/clk/clk.h | 23 | ||||
-rw-r--r-- | drivers/clk/clkdev.c | 126 |
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 | ||
82 | struct clk { | 83 | struct 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 ***/ |
93 | static int clk_pm_runtime_get(struct clk_core *core) | 95 | static 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 | ||
104 | static void clk_pm_runtime_put(struct clk_core *core) | 106 | static 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); |
235 | done: | 237 | done: |
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 | ||
3215 | struct 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 | */ | ||
3222 | static 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 | */ | ||
3233 | static 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 | */ | ||
3247 | static 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 | /** |
3241 | void __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 | */ | ||
3271 | static 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 | */ | ||
3289 | struct 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 | ||
3339 | fail_parents: | 3415 | fail_parents: |
@@ -3604,20 +3680,7 @@ EXPORT_SYMBOL_GPL(devm_clk_hw_unregister); | |||
3604 | /* | 3680 | /* |
3605 | * clkdev helpers | 3681 | * clkdev helpers |
3606 | */ | 3682 | */ |
3607 | int __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 */ | ||
3621 | void __clk_put(struct clk *clk) | 3684 | void __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 | } |
4010 | EXPORT_SYMBOL(devm_of_clk_del_provider); | 4072 | EXPORT_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 | */ | ||
4081 | static 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 | |||
4012 | static struct clk_hw * | 4117 | static 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 | ||
4027 | struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec, | 4132 | static struct clk_hw * |
4028 | const char *dev_id, const char *con_id) | 4133 | of_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 | */ |
4067 | struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec) | 4162 | struct 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 | } |
4071 | EXPORT_SYMBOL_GPL(of_clk_get_from_provider); | 4168 | EXPORT_SYMBOL_GPL(of_clk_get_from_provider); |
4072 | 4169 | ||
4170 | struct 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 | |||
4187 | static 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 | |||
4196 | struct clk *of_clk_get(struct device_node *np, int index) | ||
4197 | { | ||
4198 | return __of_clk_get(np, index, np->full_name, NULL); | ||
4199 | } | ||
4200 | EXPORT_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 | */ | ||
4211 | struct 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 | } | ||
4218 | EXPORT_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 | ||
7 | struct clk_hw; | 7 | struct clk_hw; |
8 | struct device; | ||
9 | struct of_phandle_args; | ||
8 | 10 | ||
9 | #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) | 11 | #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) |
10 | struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec, | 12 | struct 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 */ | ||
15 | static 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 |
15 | struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id, | 23 | struct 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); |
17 | void __clk_free_clk(struct clk *clk); | ||
18 | int __clk_get(struct clk *clk); | ||
19 | void __clk_put(struct clk *clk); | 25 | void __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... */ |
22 | static inline struct clk * | 28 | static inline struct clk * |
23 | __clk_create_clk(struct clk_hw *hw, const char *dev_id, const char *con_id) | 29 | clk_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 | } |
27 | static inline void __clk_free_clk(struct clk *clk) { } | ||
28 | static struct clk_hw *__clk_get_hw(struct clk *clk) | 34 | static 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 | } |
32 | static inline int __clk_get(struct clk *clk) { return 1; } | ||
33 | static inline void __clk_put(struct clk *clk) { } | 38 | static 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 @@ | |||
27 | static LIST_HEAD(clocks); | 27 | static LIST_HEAD(clocks); |
28 | static DEFINE_MUTEX(clocks_mutex); | 28 | static DEFINE_MUTEX(clocks_mutex); |
29 | 29 | ||
30 | #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) | ||
31 | static 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 | |||
49 | struct clk *of_clk_get(struct device_node *np, int index) | ||
50 | { | ||
51 | return __of_clk_get(np, index, np->full_name, NULL); | ||
52 | } | ||
53 | EXPORT_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 | */ | ||
61 | static 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 | */ | ||
110 | struct 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 | } | ||
117 | EXPORT_SYMBOL(of_clk_get_by_name); | ||
118 | |||
119 | #else /* defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) */ | ||
120 | |||
121 | static 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 | ||
172 | struct clk *clk_get_sys(const char *dev_id, const char *con_id) | 73 | static 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 | |||
193 | out: | 88 | out: |
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 | |||
94 | struct clk *clk_get_sys(const char *dev_id, const char *con_id) | ||
95 | { | ||
96 | return __clk_get_sys(NULL, dev_id, con_id); | ||
97 | } | ||
198 | EXPORT_SYMBOL(clk_get_sys); | 98 | EXPORT_SYMBOL(clk_get_sys); |
199 | 99 | ||
200 | struct clk *clk_get(struct device *dev, const char *con_id) | 100 | struct 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 | } |
213 | EXPORT_SYMBOL(clk_get); | 113 | EXPORT_SYMBOL(clk_get); |
214 | 114 | ||