From 211ccb244c8ff09b2cc77dc433a32bce0814ddc1 Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Mon, 7 May 2018 09:58:08 +0800 Subject: [PATCH] PM / devfreq: rockchip_dmc: Fix low voltage when probe If initial rate is greater than opp rate and initial voltage isn't qeual to opp volatge, the opp voltage may too low for initial rate, so it's inappropriate to update voltage when initial voltage isn't qeual to opp volatge. In order to solve this problem and consider that the regulator is shared between several devices on some platforms, make the following two changes. If the driver doesn't support to change frequency, the opp table should contain an opp whose rate is geater than or equal to initial rate, so that the voltage is enough for initial rate and the min_uV and max_uV of regulator aren't equal to zero after update voltage. If the driver supports to change frequency, let devfreq framework update rate and voltage. Change-Id: I4004f55f2cfd3b87f734844a0cdf8e9619d785d2 Signed-off-by: Finley Xiao --- drivers/devfreq/rockchip_dmc.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/devfreq/rockchip_dmc.c b/drivers/devfreq/rockchip_dmc.c index 4288d44852e9..4050ebc458d9 100644 --- a/drivers/devfreq/rockchip_dmc.c +++ b/drivers/devfreq/rockchip_dmc.c @@ -959,6 +959,10 @@ static int rockchip_dmcfreq_target(struct device *dev, unsigned long *freq, target_volt); return err; } + dmcfreq->volt = target_volt; + return 0; + } else if (!dmcfreq->volt) { + dmcfreq->volt = regulator_get_voltage(dmcfreq->vdd_center); } mutex_lock(&dmcfreq->lock); @@ -2962,7 +2966,6 @@ static int rockchip_dmcfreq_probe(struct platform_device *pdev) return -EFAULT; data->rate = clk_get_rate(data->dmc_clk); - data->volt = regulator_get_voltage(data->vdd_center); devp->initial_freq = data->rate; opp_rate = data->rate; @@ -2975,15 +2978,6 @@ static int rockchip_dmcfreq_probe(struct platform_device *pdev) opp_volt = dev_pm_opp_get_voltage(opp); rcu_read_unlock(); - if (opp_volt != data->volt) { - ret = regulator_set_voltage(data->vdd_center, opp_volt, - INT_MAX); - if (ret) { - dev_err(dev, "Cannot set voltage %lu uV\n", opp_volt); - return ret; - } - } - of_property_read_u32(np, "auto-freq-en", &data->auto_freq_en); if (!is_events_available && data->auto_freq_en) { dev_warn(dev, "events isn't available, close auto freq\n"); @@ -2996,6 +2990,13 @@ static int rockchip_dmcfreq_probe(struct platform_device *pdev) dev_info(dev, "don't add devfreq feature\n"); if (data->edev) devfreq_event_disable_edev(data->edev); + ret = regulator_set_voltage(data->vdd_center, opp_volt, + INT_MAX); + if (ret) { + dev_err(dev, "Cannot set voltage %lu uV\n", + opp_volt); + return ret; + } return 0; } }