@@ -690,14 +690,20 @@ struct clk *__clk_lookup(const char *name)
690
690
return NULL ;
691
691
}
692
692
693
- /*
694
- * Helper for finding best parent to provide a given frequency. This can be used
695
- * directly as a determine_rate callback (e.g. for a mux), or from a more
696
- * complex clock that may combine a mux with other operations.
697
- */
698
- long __clk_mux_determine_rate (struct clk_hw * hw , unsigned long rate ,
699
- unsigned long * best_parent_rate ,
700
- struct clk_hw * * best_parent_p )
693
+ static bool mux_is_better_rate (unsigned long rate , unsigned long now ,
694
+ unsigned long best , unsigned long flags )
695
+ {
696
+ if (flags & CLK_MUX_ROUND_CLOSEST )
697
+ return abs (now - rate ) < abs (best - rate );
698
+
699
+ return now <= rate && now > best ;
700
+ }
701
+
702
+ static long
703
+ clk_mux_determine_rate_flags (struct clk_hw * hw , unsigned long rate ,
704
+ unsigned long * best_parent_rate ,
705
+ struct clk_hw * * best_parent_p ,
706
+ unsigned long flags )
701
707
{
702
708
struct clk * clk = hw -> clk , * parent , * best_parent = NULL ;
703
709
int i , num_parents ;
@@ -725,7 +731,7 @@ long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
725
731
parent_rate = __clk_round_rate (parent , rate );
726
732
else
727
733
parent_rate = __clk_get_rate (parent );
728
- if (parent_rate <= rate && parent_rate > best ) {
734
+ if (mux_is_better_rate ( rate , parent_rate , best , flags ) ) {
729
735
best_parent = parent ;
730
736
best = parent_rate ;
731
737
}
@@ -738,8 +744,31 @@ long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
738
744
739
745
return best ;
740
746
}
747
+
748
+ /*
749
+ * Helper for finding best parent to provide a given frequency. This can be used
750
+ * directly as a determine_rate callback (e.g. for a mux), or from a more
751
+ * complex clock that may combine a mux with other operations.
752
+ */
753
+ long __clk_mux_determine_rate (struct clk_hw * hw , unsigned long rate ,
754
+ unsigned long * best_parent_rate ,
755
+ struct clk_hw * * best_parent_p )
756
+ {
757
+ return clk_mux_determine_rate_flags (hw , rate , best_parent_rate ,
758
+ best_parent_p , 0 );
759
+ }
741
760
EXPORT_SYMBOL_GPL (__clk_mux_determine_rate );
742
761
762
+ long __clk_mux_determine_rate_closest (struct clk_hw * hw , unsigned long rate ,
763
+ unsigned long * best_parent_rate ,
764
+ struct clk_hw * * best_parent_p )
765
+ {
766
+ return clk_mux_determine_rate_flags (hw , rate , best_parent_rate ,
767
+ best_parent_p ,
768
+ CLK_MUX_ROUND_CLOSEST );
769
+ }
770
+ EXPORT_SYMBOL_GPL (__clk_mux_determine_rate_closest );
771
+
743
772
/*** clk api ***/
744
773
745
774
void __clk_unprepare (struct clk * clk )
0 commit comments