clk_set_rate() can fail in a case where a driver denies frequency change, this can happen after Paul's clk notifier code has been applied. This patch makes DVFS VDD2 control handle this situation correctly. Signed-off-by: Tero Kristo <tero.kristo@xxxxxxxxx> --- arch/arm/mach-omap2/clock34xx.c | 5 ++++- arch/arm/mach-omap2/resource34xx.c | 18 ++++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c index 6c5254c..17102ba 100644 --- a/arch/arm/mach-omap2/clock34xx.c +++ b/arch/arm/mach-omap2/clock34xx.c @@ -960,6 +960,7 @@ static int omap3_select_table_rate(struct clk *clk, unsigned long rate) unsigned long found_speed = 0, curr_mpu_speed; int index = 0; int l3_div; + int ret; if ((clk != &virt_vdd1_prcm_set) && (clk != &virt_vdd2_prcm_set)) return -EINVAL; @@ -1003,7 +1004,9 @@ static int omap3_select_table_rate(struct clk *clk, unsigned long rate) } else { l3_div = cm_read_mod_reg(CORE_MOD, CM_CLKSEL) & OMAP3430_CLKSEL_L3_MASK; - clk_set_rate(dpll3_clk, prcm_vdd->rate * l3_div); + ret = clk_set_rate(dpll3_clk, prcm_vdd->rate * l3_div); + if (ret) + return ret; curr_vdd2_prcm_set = prcm_vdd; } diff --git a/arch/arm/mach-omap2/resource34xx.c b/arch/arm/mach-omap2/resource34xx.c index aec2bcb..2328323 100644 --- a/arch/arm/mach-omap2/resource34xx.c +++ b/arch/arm/mach-omap2/resource34xx.c @@ -188,6 +188,7 @@ int resource_set_opp_level(int res, u32 target_level, int flags) struct cpufreq_freqs freqs_notify; #endif struct shared_resource *resp; + int ret; if (res == VDD1_OPP) resp = vdd1_resp; @@ -260,7 +261,9 @@ int resource_set_opp_level(int res, u32 target_level, int flags) ID_OPP_NO(l3_opps[target_level].opp_id); if (resp->curr_level > target_level) { /* Scale Frequency and then voltage */ - clk_set_rate(vdd2_clk, l3_freq); + ret = clk_set_rate(vdd2_clk, l3_freq); + if (ret) + return ret; #ifdef CONFIG_OMAP_SMARTREFLEX sr_voltagescale_vcbypass(t_opp, l3_opps[target_level].vsel); @@ -271,7 +274,18 @@ int resource_set_opp_level(int res, u32 target_level, int flags) sr_voltagescale_vcbypass(t_opp, l3_opps[target_level].vsel); #endif - clk_set_rate(vdd2_clk, l3_freq); + ret = clk_set_rate(vdd2_clk, l3_freq); + if (ret) { +#ifdef CONFIG_OMAP_SMARTREFLEX + /* Setting clock failed, revert voltage */ + t_opp = ID_VDD(PRCM_VDD2) | + ID_OPP_NO(l3_opps[resp->curr_level]. + opp_id); + sr_voltagescale_vcbypass(t_opp, + l3_opps[resp->curr_level].vsel); +#endif + return ret; + } } resp->curr_level = curr_vdd2_prcm_set->opp_id; } -- 1.5.4.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html