aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/clk.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/clk.c')
-rw-r--r--drivers/clk/clk.c55
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 */
2227int __clk_get(struct clk *clk) 2230int __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
2236void __clk_put(struct clk *clk) 2241void __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);
2472struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec) 2467struct 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);
2505const char *of_clk_get_parent_name(struct device_node *np, int index) 2500const 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