diff options
Diffstat (limited to 'drivers/clk/clk.c')
| -rw-r--r-- | drivers/clk/clk.c | 38 | 
1 files changed, 22 insertions, 16 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 687b00d67c8..9a1eb0cfa95 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -850,18 +850,21 @@ static void clk_change_rate(struct clk *clk)  {  	struct clk *child;  	unsigned long old_rate; +	unsigned long best_parent_rate = 0;  	struct hlist_node *tmp;  	old_rate = clk->rate; +	if (clk->parent) +		best_parent_rate = clk->parent->rate; +  	if (clk->ops->set_rate) -		clk->ops->set_rate(clk->hw, clk->new_rate, clk->parent->rate); +		clk->ops->set_rate(clk->hw, clk->new_rate, best_parent_rate);  	if (clk->ops->recalc_rate) -		clk->rate = clk->ops->recalc_rate(clk->hw, -				clk->parent->rate); +		clk->rate = clk->ops->recalc_rate(clk->hw, best_parent_rate);  	else -		clk->rate = clk->parent->rate; +		clk->rate = best_parent_rate;  	if (clk->notifier_count && old_rate != clk->rate)  		__clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate); @@ -999,7 +1002,7 @@ static struct clk *__clk_init_parent(struct clk *clk)  	if (!clk->parents)  		clk->parents = -			kmalloc((sizeof(struct clk*) * clk->num_parents), +			kzalloc((sizeof(struct clk*) * clk->num_parents),  					GFP_KERNEL);  	if (!clk->parents) @@ -1064,21 +1067,24 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent)  	old_parent = clk->parent; -	/* find index of new parent clock using cached parent ptrs */ -	for (i = 0; i < clk->num_parents; i++) -		if (clk->parents[i] == parent) -			break; +	if (!clk->parents) +		clk->parents = kzalloc((sizeof(struct clk*) * clk->num_parents), +								GFP_KERNEL);  	/* -	 * find index of new parent clock using string name comparison -	 * also try to cache the parent to avoid future calls to __clk_lookup +	 * find index of new parent clock using cached parent ptrs, +	 * or if not yet cached, use string name comparison and cache +	 * them now to avoid future calls to __clk_lookup.  	 */ -	if (i == clk->num_parents) -		for (i = 0; i < clk->num_parents; i++) -			if (!strcmp(clk->parent_names[i], parent->name)) { +	for (i = 0; i < clk->num_parents; i++) { +		if (clk->parents && clk->parents[i] == parent) +			break; +		else if (!strcmp(clk->parent_names[i], parent->name)) { +			if (clk->parents)  				clk->parents[i] = __clk_lookup(parent->name); -				break; -			} +			break; +		} +	}  	if (i == clk->num_parents) {  		pr_debug("%s: clock %s is not a possible parent of clock %s\n",  |