diff options
Diffstat (limited to 'drivers/clk/clk.c')
-rw-r--r-- | drivers/clk/clk.c | 55 |
1 files changed, 34 insertions, 21 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 5517944495d8..895b3d204e22 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c | |||
@@ -1339,8 +1339,11 @@ static int __clk_speculate_rates(struct clk *clk, unsigned long parent_rate) | |||
1339 | if (clk->notifier_count) | 1339 | if (clk->notifier_count) |
1340 | ret = __clk_notify(clk, PRE_RATE_CHANGE, clk->rate, new_rate); | 1340 | ret = __clk_notify(clk, PRE_RATE_CHANGE, clk->rate, new_rate); |
1341 | 1341 | ||
1342 | if (ret & NOTIFY_STOP_MASK) | 1342 | if (ret & NOTIFY_STOP_MASK) { |
1343 | pr_debug("%s: clk notifier callback for clock %s aborted with error %d\n", | ||
1344 | __func__, clk->name, ret); | ||
1343 | goto out; | 1345 | goto out; |
1346 | } | ||
1344 | 1347 | ||
1345 | hlist_for_each_entry(child, &clk->children, child_node) { | 1348 | hlist_for_each_entry(child, &clk->children, child_node) { |
1346 | ret = __clk_speculate_rates(child, new_rate); | 1349 | ret = __clk_speculate_rates(child, new_rate); |
@@ -2226,24 +2229,25 @@ EXPORT_SYMBOL_GPL(devm_clk_unregister); | |||
2226 | */ | 2229 | */ |
2227 | int __clk_get(struct clk *clk) | 2230 | int __clk_get(struct clk *clk) |
2228 | { | 2231 | { |
2229 | if (clk && !try_module_get(clk->owner)) | 2232 | if (clk) { |
2230 | return 0; | 2233 | if (!try_module_get(clk->owner)) |
2234 | return 0; | ||
2231 | 2235 | ||
2232 | kref_get(&clk->ref); | 2236 | kref_get(&clk->ref); |
2237 | } | ||
2233 | return 1; | 2238 | return 1; |
2234 | } | 2239 | } |
2235 | 2240 | ||
2236 | void __clk_put(struct clk *clk) | 2241 | void __clk_put(struct clk *clk) |
2237 | { | 2242 | { |
2238 | if (WARN_ON_ONCE(IS_ERR(clk))) | 2243 | if (!clk || WARN_ON_ONCE(IS_ERR(clk))) |
2239 | return; | 2244 | return; |
2240 | 2245 | ||
2241 | clk_prepare_lock(); | 2246 | clk_prepare_lock(); |
2242 | kref_put(&clk->ref, __clk_release); | 2247 | kref_put(&clk->ref, __clk_release); |
2243 | clk_prepare_unlock(); | 2248 | clk_prepare_unlock(); |
2244 | 2249 | ||
2245 | if (clk) | 2250 | module_put(clk->owner); |
2246 | module_put(clk->owner); | ||
2247 | } | 2251 | } |
2248 | 2252 | ||
2249 | /*** clk rate change notifiers ***/ | 2253 | /*** clk rate change notifiers ***/ |
@@ -2259,20 +2263,11 @@ void __clk_put(struct clk *clk) | |||
2259 | * re-enter into the clk framework by calling any top-level clk APIs; | 2263 | * re-enter into the clk framework by calling any top-level clk APIs; |
2260 | * this will cause a nested prepare_lock mutex. | 2264 | * this will cause a nested prepare_lock mutex. |
2261 | * | 2265 | * |
2262 | * Pre-change notifier callbacks will be passed the current, pre-change | 2266 | * In all notification cases cases (pre, post and abort rate change) the |
2263 | * rate of the clk via struct clk_notifier_data.old_rate. The new, | 2267 | * original clock rate is passed to the callback via struct |
2264 | * post-change rate of the clk is passed via struct | 2268 | * clk_notifier_data.old_rate and the new frequency is passed via struct |
2265 | * clk_notifier_data.new_rate. | 2269 | * clk_notifier_data.new_rate. |
2266 | * | 2270 | * |
2267 | * Post-change notifiers will pass the now-current, post-change rate of | ||
2268 | * the clk in both struct clk_notifier_data.old_rate and struct | ||
2269 | * clk_notifier_data.new_rate. | ||
2270 | * | ||
2271 | * Abort-change notifiers are effectively the opposite of pre-change | ||
2272 | * notifiers: the original pre-change clk rate is passed in via struct | ||
2273 | * clk_notifier_data.new_rate and the failed post-change rate is passed | ||
2274 | * in via struct clk_notifier_data.old_rate. | ||
2275 | * | ||
2276 | * clk_notifier_register() must be called from non-atomic context. | 2271 | * clk_notifier_register() must be called from non-atomic context. |
2277 | * Returns -EINVAL if called with null arguments, -ENOMEM upon | 2272 | * Returns -EINVAL if called with null arguments, -ENOMEM upon |
2278 | * allocation failure; otherwise, passes along the return value of | 2273 | * allocation failure; otherwise, passes along the return value of |
@@ -2472,7 +2467,7 @@ EXPORT_SYMBOL_GPL(of_clk_del_provider); | |||
2472 | struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec) | 2467 | struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec) |
2473 | { | 2468 | { |
2474 | struct of_clk_provider *provider; | 2469 | struct of_clk_provider *provider; |
2475 | struct clk *clk = ERR_PTR(-ENOENT); | 2470 | struct clk *clk = ERR_PTR(-EPROBE_DEFER); |
2476 | 2471 | ||
2477 | /* Check if we have such a provider in our array */ | 2472 | /* Check if we have such a provider in our array */ |
2478 | list_for_each_entry(provider, &of_clk_providers, link) { | 2473 | list_for_each_entry(provider, &of_clk_providers, link) { |
@@ -2505,8 +2500,12 @@ EXPORT_SYMBOL_GPL(of_clk_get_parent_count); | |||
2505 | const char *of_clk_get_parent_name(struct device_node *np, int index) | 2500 | const char *of_clk_get_parent_name(struct device_node *np, int index) |
2506 | { | 2501 | { |
2507 | struct of_phandle_args clkspec; | 2502 | struct of_phandle_args clkspec; |
2503 | struct property *prop; | ||
2508 | const char *clk_name; | 2504 | const char *clk_name; |
2505 | const __be32 *vp; | ||
2506 | u32 pv; | ||
2509 | int rc; | 2507 | int rc; |
2508 | int count; | ||
2510 | 2509 | ||
2511 | if (index < 0) | 2510 | if (index < 0) |
2512 | return NULL; | 2511 | return NULL; |
@@ -2516,8 +2515,22 @@ const char *of_clk_get_parent_name(struct device_node *np, int index) | |||
2516 | if (rc) | 2515 | if (rc) |
2517 | return NULL; | 2516 | return NULL; |
2518 | 2517 | ||
2518 | index = clkspec.args_count ? clkspec.args[0] : 0; | ||
2519 | count = 0; | ||
2520 | |||
2521 | /* if there is an indices property, use it to transfer the index | ||
2522 | * specified into an array offset for the clock-output-names property. | ||
2523 | */ | ||
2524 | of_property_for_each_u32(clkspec.np, "clock-indices", prop, vp, pv) { | ||
2525 | if (index == pv) { | ||
2526 | index = count; | ||
2527 | break; | ||
2528 | } | ||
2529 | count++; | ||
2530 | } | ||
2531 | |||
2519 | if (of_property_read_string_index(clkspec.np, "clock-output-names", | 2532 | if (of_property_read_string_index(clkspec.np, "clock-output-names", |
2520 | clkspec.args_count ? clkspec.args[0] : 0, | 2533 | index, |
2521 | &clk_name) < 0) | 2534 | &clk_name) < 0) |
2522 | clk_name = clkspec.np->name; | 2535 | clk_name = clkspec.np->name; |
2523 | 2536 | ||