diff options
| -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 | ||
