summaryrefslogtreecommitdiffstats
path: root/drivers/clk/clk.c
diff options
context:
space:
mode:
authorStephen Boyd <sboyd@codeaurora.org>2015-07-28 14:51:30 -0400
committerStephen Boyd <sboyd@codeaurora.org>2015-07-28 14:51:30 -0400
commit19aab273083fa10c2262b8c8e3315bacb054d75d (patch)
tree65097982915b51acdf8d5576d63153085b779ceb /drivers/clk/clk.c
parent86665d2897209429a7e4a003764b9fc5034dbfa1 (diff)
parent57d866e606ddf2a0cd51f7140cfd8df1fdaa48f6 (diff)
Merge branch 'clk-determine-rate-struct' into clk-next
* clk-determine-rate-struct: clk: fix some determine_rate implementations clk: change clk_ops' ->determine_rate() prototype
Diffstat (limited to 'drivers/clk/clk.c')
-rw-r--r--drivers/clk/clk.c179
1 files changed, 99 insertions, 80 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 7873151a7ff8..bd6dfbe04cf0 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -436,28 +436,31 @@ static bool mux_is_better_rate(unsigned long rate, unsigned long now,
436 return now <= rate && now > best; 436 return now <= rate && now > best;
437} 437}
438 438
439static long 439static int
440clk_mux_determine_rate_flags(struct clk_hw *hw, unsigned long rate, 440clk_mux_determine_rate_flags(struct clk_hw *hw, struct clk_rate_request *req,
441 unsigned long min_rate,
442 unsigned long max_rate,
443 unsigned long *best_parent_rate,
444 struct clk_hw **best_parent_p,
445 unsigned long flags) 441 unsigned long flags)
446{ 442{
447 struct clk_core *core = hw->core, *parent, *best_parent = NULL; 443 struct clk_core *core = hw->core, *parent, *best_parent = NULL;
448 int i, num_parents; 444 int i, num_parents, ret;
449 unsigned long parent_rate, best = 0; 445 unsigned long best = 0;
446 struct clk_rate_request parent_req = *req;
450 447
451 /* if NO_REPARENT flag set, pass through to current parent */ 448 /* if NO_REPARENT flag set, pass through to current parent */
452 if (core->flags & CLK_SET_RATE_NO_REPARENT) { 449 if (core->flags & CLK_SET_RATE_NO_REPARENT) {
453 parent = core->parent; 450 parent = core->parent;
454 if (core->flags & CLK_SET_RATE_PARENT) 451 if (core->flags & CLK_SET_RATE_PARENT) {
455 best = __clk_determine_rate(parent ? parent->hw : NULL, 452 ret = __clk_determine_rate(parent ? parent->hw : NULL,
456 rate, min_rate, max_rate); 453 &parent_req);
457 else if (parent) 454 if (ret)
455 return ret;
456
457 best = parent_req.rate;
458 } else if (parent) {
458 best = clk_core_get_rate_nolock(parent); 459 best = clk_core_get_rate_nolock(parent);
459 else 460 } else {
460 best = clk_core_get_rate_nolock(core); 461 best = clk_core_get_rate_nolock(core);
462 }
463
461 goto out; 464 goto out;
462 } 465 }
463 466
@@ -467,24 +470,33 @@ clk_mux_determine_rate_flags(struct clk_hw *hw, unsigned long rate,
467 parent = clk_core_get_parent_by_index(core, i); 470 parent = clk_core_get_parent_by_index(core, i);
468 if (!parent) 471 if (!parent)
469 continue; 472 continue;
470 if (core->flags & CLK_SET_RATE_PARENT) 473
471 parent_rate = __clk_determine_rate(parent->hw, rate, 474 if (core->flags & CLK_SET_RATE_PARENT) {
472 min_rate, 475 parent_req = *req;
473 max_rate); 476 ret = __clk_determine_rate(parent->hw, &parent_req);
474 else 477 if (ret)
475 parent_rate = clk_core_get_rate_nolock(parent); 478 continue;
476 if (mux_is_better_rate(rate, parent_rate, best, flags)) { 479 } else {
480 parent_req.rate = clk_core_get_rate_nolock(parent);
481 }
482
483 if (mux_is_better_rate(req->rate, parent_req.rate,
484 best, flags)) {
477 best_parent = parent; 485 best_parent = parent;
478 best = parent_rate; 486 best = parent_req.rate;
479 } 487 }
480 } 488 }
481 489
490 if (!best_parent)
491 return -EINVAL;
492
482out: 493out:
483 if (best_parent) 494 if (best_parent)
484 *best_parent_p = best_parent->hw; 495 req->best_parent_hw = best_parent->hw;
485 *best_parent_rate = best; 496 req->best_parent_rate = best;
497 req->rate = best;
486 498
487 return best; 499 return 0;
488} 500}
489 501
490struct clk *__clk_lookup(const char *name) 502struct clk *__clk_lookup(const char *name)
@@ -515,28 +527,17 @@ static void clk_core_get_boundaries(struct clk_core *core,
515 * directly as a determine_rate callback (e.g. for a mux), or from a more 527 * directly as a determine_rate callback (e.g. for a mux), or from a more
516 * complex clock that may combine a mux with other operations. 528 * complex clock that may combine a mux with other operations.
517 */ 529 */
518long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate, 530int __clk_mux_determine_rate(struct clk_hw *hw,
519 unsigned long min_rate, 531 struct clk_rate_request *req)
520 unsigned long max_rate,
521 unsigned long *best_parent_rate,
522 struct clk_hw **best_parent_p)
523{ 532{
524 return clk_mux_determine_rate_flags(hw, rate, min_rate, max_rate, 533 return clk_mux_determine_rate_flags(hw, req, 0);
525 best_parent_rate,
526 best_parent_p, 0);
527} 534}
528EXPORT_SYMBOL_GPL(__clk_mux_determine_rate); 535EXPORT_SYMBOL_GPL(__clk_mux_determine_rate);
529 536
530long __clk_mux_determine_rate_closest(struct clk_hw *hw, unsigned long rate, 537int __clk_mux_determine_rate_closest(struct clk_hw *hw,
531 unsigned long min_rate, 538 struct clk_rate_request *req)
532 unsigned long max_rate,
533 unsigned long *best_parent_rate,
534 struct clk_hw **best_parent_p)
535{ 539{
536 return clk_mux_determine_rate_flags(hw, rate, min_rate, max_rate, 540 return clk_mux_determine_rate_flags(hw, req, CLK_MUX_ROUND_CLOSEST);
537 best_parent_rate,
538 best_parent_p,
539 CLK_MUX_ROUND_CLOSEST);
540} 541}
541EXPORT_SYMBOL_GPL(__clk_mux_determine_rate_closest); 542EXPORT_SYMBOL_GPL(__clk_mux_determine_rate_closest);
542 543
@@ -759,14 +760,11 @@ int clk_enable(struct clk *clk)
759} 760}
760EXPORT_SYMBOL_GPL(clk_enable); 761EXPORT_SYMBOL_GPL(clk_enable);
761 762
762static unsigned long clk_core_round_rate_nolock(struct clk_core *core, 763static int clk_core_round_rate_nolock(struct clk_core *core,
763 unsigned long rate, 764 struct clk_rate_request *req)
764 unsigned long min_rate,
765 unsigned long max_rate)
766{ 765{
767 unsigned long parent_rate = 0;
768 struct clk_core *parent; 766 struct clk_core *parent;
769 struct clk_hw *parent_hw; 767 long rate;
770 768
771 lockdep_assert_held(&prepare_lock); 769 lockdep_assert_held(&prepare_lock);
772 770
@@ -774,21 +772,30 @@ static unsigned long clk_core_round_rate_nolock(struct clk_core *core,
774 return 0; 772 return 0;
775 773
776 parent = core->parent; 774 parent = core->parent;
777 if (parent) 775 if (parent) {
778 parent_rate = parent->rate; 776 req->best_parent_hw = parent->hw;
777 req->best_parent_rate = parent->rate;
778 } else {
779 req->best_parent_hw = NULL;
780 req->best_parent_rate = 0;
781 }
779 782
780 if (core->ops->determine_rate) { 783 if (core->ops->determine_rate) {
781 parent_hw = parent ? parent->hw : NULL; 784 return core->ops->determine_rate(core->hw, req);
782 return core->ops->determine_rate(core->hw, rate, 785 } else if (core->ops->round_rate) {
783 min_rate, max_rate, 786 rate = core->ops->round_rate(core->hw, req->rate,
784 &parent_rate, &parent_hw); 787 &req->best_parent_rate);
785 } else if (core->ops->round_rate) 788 if (rate < 0)
786 return core->ops->round_rate(core->hw, rate, &parent_rate); 789 return rate;
787 else if (core->flags & CLK_SET_RATE_PARENT) 790
788 return clk_core_round_rate_nolock(core->parent, rate, min_rate, 791 req->rate = rate;
789 max_rate); 792 } else if (core->flags & CLK_SET_RATE_PARENT) {
790 else 793 return clk_core_round_rate_nolock(parent, req);
791 return core->rate; 794 } else {
795 req->rate = core->rate;
796 }
797
798 return 0;
792} 799}
793 800
794/** 801/**
@@ -800,15 +807,14 @@ static unsigned long clk_core_round_rate_nolock(struct clk_core *core,
800 * 807 *
801 * Useful for clk_ops such as .set_rate and .determine_rate. 808 * Useful for clk_ops such as .set_rate and .determine_rate.
802 */ 809 */
803unsigned long __clk_determine_rate(struct clk_hw *hw, 810int __clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
804 unsigned long rate,
805 unsigned long min_rate,
806 unsigned long max_rate)
807{ 811{
808 if (!hw) 812 if (!hw) {
813 req->rate = 0;
809 return 0; 814 return 0;
815 }
810 816
811 return clk_core_round_rate_nolock(hw->core, rate, min_rate, max_rate); 817 return clk_core_round_rate_nolock(hw->core, req);
812} 818}
813EXPORT_SYMBOL_GPL(__clk_determine_rate); 819EXPORT_SYMBOL_GPL(__clk_determine_rate);
814 820
@@ -821,15 +827,20 @@ EXPORT_SYMBOL_GPL(__clk_determine_rate);
821 */ 827 */
822unsigned long __clk_round_rate(struct clk *clk, unsigned long rate) 828unsigned long __clk_round_rate(struct clk *clk, unsigned long rate)
823{ 829{
824 unsigned long min_rate; 830 struct clk_rate_request req;
825 unsigned long max_rate; 831 int ret;
826 832
827 if (!clk) 833 if (!clk)
828 return 0; 834 return 0;
829 835
830 clk_core_get_boundaries(clk->core, &min_rate, &max_rate); 836 clk_core_get_boundaries(clk->core, &req.min_rate, &req.max_rate);
837 req.rate = rate;
838
839 ret = clk_core_round_rate_nolock(clk->core, &req);
840 if (ret)
841 return 0;
831 842
832 return clk_core_round_rate_nolock(clk->core, rate, min_rate, max_rate); 843 return req.rate;
833} 844}
834EXPORT_SYMBOL_GPL(__clk_round_rate); 845EXPORT_SYMBOL_GPL(__clk_round_rate);
835 846
@@ -1249,7 +1260,6 @@ static struct clk_core *clk_calc_new_rates(struct clk_core *core,
1249{ 1260{
1250 struct clk_core *top = core; 1261 struct clk_core *top = core;
1251 struct clk_core *old_parent, *parent; 1262 struct clk_core *old_parent, *parent;
1252 struct clk_hw *parent_hw;
1253 unsigned long best_parent_rate = 0; 1263 unsigned long best_parent_rate = 0;
1254 unsigned long new_rate; 1264 unsigned long new_rate;
1255 unsigned long min_rate; 1265 unsigned long min_rate;
@@ -1270,20 +1280,29 @@ static struct clk_core *clk_calc_new_rates(struct clk_core *core,
1270 1280
1271 /* find the closest rate and parent clk/rate */ 1281 /* find the closest rate and parent clk/rate */
1272 if (core->ops->determine_rate) { 1282 if (core->ops->determine_rate) {
1273 parent_hw = parent ? parent->hw : NULL; 1283 struct clk_rate_request req;
1274 ret = core->ops->determine_rate(core->hw, rate, 1284
1275 min_rate, 1285 req.rate = rate;
1276 max_rate, 1286 req.min_rate = min_rate;
1277 &best_parent_rate, 1287 req.max_rate = max_rate;
1278 &parent_hw); 1288 if (parent) {
1289 req.best_parent_hw = parent->hw;
1290 req.best_parent_rate = parent->rate;
1291 } else {
1292 req.best_parent_hw = NULL;
1293 req.best_parent_rate = 0;
1294 }
1295
1296 ret = core->ops->determine_rate(core->hw, &req);
1279 if (ret < 0) 1297 if (ret < 0)
1280 return NULL; 1298 return NULL;
1281 1299
1282 new_rate = ret; 1300 best_parent_rate = req.best_parent_rate;
1283 parent = parent_hw ? parent_hw->core : NULL; 1301 new_rate = req.rate;
1302 parent = req.best_parent_hw ? req.best_parent_hw->core : NULL;
1284 } else if (core->ops->round_rate) { 1303 } else if (core->ops->round_rate) {
1285 ret = core->ops->round_rate(core->hw, rate, 1304 ret = core->ops->round_rate(core->hw, rate,
1286 &best_parent_rate); 1305 &best_parent_rate);
1287 if (ret < 0) 1306 if (ret < 0)
1288 return NULL; 1307 return NULL;
1289 1308