diff options
Diffstat (limited to 'drivers/cpufreq/cpufreq-cpu0.c')
-rw-r--r-- | drivers/cpufreq/cpufreq-cpu0.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c index 3ab8294eab0..ad1fde27766 100644 --- a/drivers/cpufreq/cpufreq-cpu0.c +++ b/drivers/cpufreq/cpufreq-cpu0.c @@ -45,7 +45,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy, struct cpufreq_freqs freqs; struct opp *opp; unsigned long volt = 0, volt_old = 0, tol = 0; - long freq_Hz; + long freq_Hz, freq_exact; unsigned int index; int ret; @@ -60,6 +60,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy, freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000); if (freq_Hz < 0) freq_Hz = freq_table[index].frequency * 1000; + freq_exact = freq_Hz; freqs.new = freq_Hz / 1000; freqs.old = clk_get_rate(cpu_clk) / 1000; @@ -98,7 +99,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy, } } - ret = clk_set_rate(cpu_clk, freqs.new * 1000); + ret = clk_set_rate(cpu_clk, freq_exact); if (ret) { pr_err("failed to set clock rate: %d\n", ret); if (cpu_reg) @@ -189,12 +190,29 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev) if (!np) { pr_err("failed to find cpu0 node\n"); - return -ENOENT; + ret = -ENOENT; + goto out_put_parent; } cpu_dev = &pdev->dev; cpu_dev->of_node = np; + cpu_reg = devm_regulator_get(cpu_dev, "cpu0"); + if (IS_ERR(cpu_reg)) { + /* + * If cpu0 regulator supply node is present, but regulator is + * not yet registered, we should try defering probe. + */ + if (PTR_ERR(cpu_reg) == -EPROBE_DEFER) { + dev_err(cpu_dev, "cpu0 regulator not ready, retry\n"); + ret = -EPROBE_DEFER; + goto out_put_node; + } + pr_warn("failed to get cpu0 regulator: %ld\n", + PTR_ERR(cpu_reg)); + cpu_reg = NULL; + } + cpu_clk = devm_clk_get(cpu_dev, NULL); if (IS_ERR(cpu_clk)) { ret = PTR_ERR(cpu_clk); @@ -202,12 +220,6 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev) goto out_put_node; } - cpu_reg = devm_regulator_get(cpu_dev, "cpu0"); - if (IS_ERR(cpu_reg)) { - pr_warn("failed to get cpu0 regulator\n"); - cpu_reg = NULL; - } - ret = of_init_opp_table(cpu_dev); if (ret) { pr_err("failed to init OPP table: %d\n", ret); @@ -264,6 +276,8 @@ out_free_table: opp_free_cpufreq_table(cpu_dev, &freq_table); out_put_node: of_node_put(np); +out_put_parent: + of_node_put(parent); return ret; } |