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.c42
1 files changed, 24 insertions, 18 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 687b00d67c8a..46317cbc088f 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -850,18 +850,21 @@ static void clk_change_rate(struct clk *clk)
850{ 850{
851 struct clk *child; 851 struct clk *child;
852 unsigned long old_rate; 852 unsigned long old_rate;
853 unsigned long best_parent_rate = 0;
853 struct hlist_node *tmp; 854 struct hlist_node *tmp;
854 855
855 old_rate = clk->rate; 856 old_rate = clk->rate;
856 857
858 if (clk->parent)
859 best_parent_rate = clk->parent->rate;
860
857 if (clk->ops->set_rate) 861 if (clk->ops->set_rate)
858 clk->ops->set_rate(clk->hw, clk->new_rate, clk->parent->rate); 862 clk->ops->set_rate(clk->hw, clk->new_rate, best_parent_rate);
859 863
860 if (clk->ops->recalc_rate) 864 if (clk->ops->recalc_rate)
861 clk->rate = clk->ops->recalc_rate(clk->hw, 865 clk->rate = clk->ops->recalc_rate(clk->hw, best_parent_rate);
862 clk->parent->rate);
863 else 866 else
864 clk->rate = clk->parent->rate; 867 clk->rate = best_parent_rate;
865 868
866 if (clk->notifier_count && old_rate != clk->rate) 869 if (clk->notifier_count && old_rate != clk->rate)
867 __clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate); 870 __clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate);
@@ -999,7 +1002,7 @@ static struct clk *__clk_init_parent(struct clk *clk)
999 1002
1000 if (!clk->parents) 1003 if (!clk->parents)
1001 clk->parents = 1004 clk->parents =
1002 kmalloc((sizeof(struct clk*) * clk->num_parents), 1005 kzalloc((sizeof(struct clk*) * clk->num_parents),
1003 GFP_KERNEL); 1006 GFP_KERNEL);
1004 1007
1005 if (!clk->parents) 1008 if (!clk->parents)
@@ -1064,21 +1067,24 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent)
1064 1067
1065 old_parent = clk->parent; 1068 old_parent = clk->parent;
1066 1069
1067 /* find index of new parent clock using cached parent ptrs */ 1070 if (!clk->parents)
1068 for (i = 0; i < clk->num_parents; i++) 1071 clk->parents = kzalloc((sizeof(struct clk*) * clk->num_parents),
1069 if (clk->parents[i] == parent) 1072 GFP_KERNEL);
1070 break;
1071 1073
1072 /* 1074 /*
1073 * find index of new parent clock using string name comparison 1075 * find index of new parent clock using cached parent ptrs,
1074 * also try to cache the parent to avoid future calls to __clk_lookup 1076 * or if not yet cached, use string name comparison and cache
1077 * them now to avoid future calls to __clk_lookup.
1075 */ 1078 */
1076 if (i == clk->num_parents) 1079 for (i = 0; i < clk->num_parents; i++) {
1077 for (i = 0; i < clk->num_parents; i++) 1080 if (clk->parents && clk->parents[i] == parent)
1078 if (!strcmp(clk->parent_names[i], parent->name)) { 1081 break;
1082 else if (!strcmp(clk->parent_names[i], parent->name)) {
1083 if (clk->parents)
1079 clk->parents[i] = __clk_lookup(parent->name); 1084 clk->parents[i] = __clk_lookup(parent->name);
1080 break; 1085 break;
1081 } 1086 }
1087 }
1082 1088
1083 if (i == clk->num_parents) { 1089 if (i == clk->num_parents) {
1084 pr_debug("%s: clock %s is not a possible parent of clock %s\n", 1090 pr_debug("%s: clock %s is not a possible parent of clock %s\n",
@@ -1229,8 +1235,8 @@ int __clk_init(struct device *dev, struct clk *clk)
1229 * If clk->parents is not NULL we skip this entire block. This allows 1235 * If clk->parents is not NULL we skip this entire block. This allows
1230 * for clock drivers to statically initialize clk->parents. 1236 * for clock drivers to statically initialize clk->parents.
1231 */ 1237 */
1232 if (clk->num_parents && !clk->parents) { 1238 if (clk->num_parents > 1 && !clk->parents) {
1233 clk->parents = kmalloc((sizeof(struct clk*) * clk->num_parents), 1239 clk->parents = kzalloc((sizeof(struct clk*) * clk->num_parents),
1234 GFP_KERNEL); 1240 GFP_KERNEL);
1235 /* 1241 /*
1236 * __clk_lookup returns NULL for parents that have not been 1242 * __clk_lookup returns NULL for parents that have not been