Message ID | 1413454100-23009-1-git-send-email-l.stach@pengutronix.de (mailing list archive) |
---|---|
State | Not Applicable, archived |
Headers | show |
On Thursday, October 16, 2014 12:08:20 PM Lucas Stach wrote: > If the regulator connected to the CPU voltage plane doesn't > support an OPP specified voltage with the acceptable tolerance > it's better to just disable the OPP instead of constantly > failing the voltage scaling later on. > > Signed-off-by: Lucas Stach <l.stach@pengutronix.de> > Acked-by: Viresh Kumar <viresh.kumar@linaro.org> Applied, thanks!
Hi Rafael, Lucas, On Tue, Oct 21, 2014 at 4:19 PM, Rafael J. Wysocki <rjw@rjwysocki.net> wrote: > On Thursday, October 16, 2014 12:08:20 PM Lucas Stach wrote: >> If the regulator connected to the CPU voltage plane doesn't >> support an OPP specified voltage with the acceptable tolerance >> it's better to just disable the OPP instead of constantly >> failing the voltage scaling later on. >> >> Signed-off-by: Lucas Stach <l.stach@pengutronix.de> >> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> > > Applied, thanks! This commit (http://git.kernel.org/cgit/linux/kernel/git/rafael/linux-pm.git/commit/?h=linux-next&id=d7bbd4cd0359d781b67c9e621d4bbfd1bb2f3783) causes a boot regression on r8a7791/koelsch. It hangs after: TCP: cubic registered Initializing XFRM netlink socket NET: Registered protocol family 17 NET: Registered protocol family 15 ata1: link resume succeeded after 1 retries ata1: SATA link down (SStatus 0 SControl 300) random: nonblocking pool is initialized With more debugging, it seems to end up in an infinite loop calling runtime_{suspend,resume}(): cpufreq-dt cpufreq-dt: pm_clk_notify() 4 i2c-sh_mobile e60b0000.i2c: pm_clk_resume() MSTP i2c6 ON i2c-sh_mobile e60b0000.i2c: pm_clk_suspend() MSTP i2c6 OFF i2c-sh_mobile e60b0000.i2c: pm_clk_resume() MSTP i2c6 ON i2c-sh_mobile e60b0000.i2c: pm_clk_suspend() MSTP i2c6 OFF i2c-sh_mobile e60b0000.i2c: pm_clk_resume() MSTP i2c6 ON i2c-sh_mobile e60b0000.i2c: pm_clk_suspend() MSTP i2c6 OFF i2c-sh_mobile e60b0000.i2c: pm_clk_resume() MSTP i2c6 ON i2c-sh_mobile e60b0000.i2c: pm_clk_suspend() MSTP i2c6 OFF i2c-sh_mobile e60b0000.i2c: pm_clk_resume() ... Reverting this commit fixes the issue, and makes the boot continue with: cpufreq: __cpufreq_add_dev: CPU0: Running at unlisted freq: 1300000 KHz cpufreq: __cpufreq_add_dev: CPU0: Unlisted initial frequency changed to: 1312500 KHz cpu cpu1: failed to get cpu-2 clock: 1 cpufreq_dt: cpufreq_init: Failed to allocate resources: -2 Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds -- To unsubscribe from this list: send the line "unsubscribe linux-pm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Geert, Am Donnerstag, den 23.10.2014, 11:19 +0200 schrieb Geert Uytterhoeven: > Hi Rafael, Lucas, > > On Tue, Oct 21, 2014 at 4:19 PM, Rafael J. Wysocki <rjw@rjwysocki.net> wrote: > > On Thursday, October 16, 2014 12:08:20 PM Lucas Stach wrote: > >> If the regulator connected to the CPU voltage plane doesn't > >> support an OPP specified voltage with the acceptable tolerance > >> it's better to just disable the OPP instead of constantly > >> failing the voltage scaling later on. > >> > >> Signed-off-by: Lucas Stach <l.stach@pengutronix.de> > >> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> > > > > Applied, thanks! > > This commit > (http://git.kernel.org/cgit/linux/kernel/git/rafael/linux-pm.git/commit/?h=linux-next&id=d7bbd4cd0359d781b67c9e621d4bbfd1bb2f3783) > causes a boot regression on r8a7791/koelsch. It hangs after: > > TCP: cubic registered > Initializing XFRM netlink socket > NET: Registered protocol family 17 > NET: Registered protocol family 15 > ata1: link resume succeeded after 1 retries > ata1: SATA link down (SStatus 0 SControl 300) > random: nonblocking pool is initialized > > With more debugging, it seems to end up in an infinite loop > calling runtime_{suspend,resume}(): > > cpufreq-dt cpufreq-dt: pm_clk_notify() 4 > i2c-sh_mobile e60b0000.i2c: pm_clk_resume() > MSTP i2c6 ON > i2c-sh_mobile e60b0000.i2c: pm_clk_suspend() > MSTP i2c6 OFF > i2c-sh_mobile e60b0000.i2c: pm_clk_resume() > MSTP i2c6 ON > i2c-sh_mobile e60b0000.i2c: pm_clk_suspend() > MSTP i2c6 OFF > i2c-sh_mobile e60b0000.i2c: pm_clk_resume() > MSTP i2c6 ON > i2c-sh_mobile e60b0000.i2c: pm_clk_suspend() > MSTP i2c6 OFF > i2c-sh_mobile e60b0000.i2c: pm_clk_resume() > MSTP i2c6 ON > i2c-sh_mobile e60b0000.i2c: pm_clk_suspend() > MSTP i2c6 OFF > i2c-sh_mobile e60b0000.i2c: pm_clk_resume() > ... > > Reverting this commit fixes the issue, and makes the boot continue with: > > cpufreq: __cpufreq_add_dev: CPU0: Running at unlisted freq: 1300000 KHz > cpufreq: __cpufreq_add_dev: CPU0: Unlisted initial frequency > changed to: 1312500 KHz > cpu cpu1: failed to get cpu-2 clock: 1 > cpufreq_dt: cpufreq_init: Failed to allocate resources: -2 > Urgh, thanks for the report. Am I right that for koelsch you do reference a regulator supply for the cpu, but don't actually have a driver for it, so a dummy regulator gets plugged in there? Regards, Lucas
Hi Lucas, On Thu, Oct 23, 2014 at 4:10 PM, Lucas Stach <l.stach@pengutronix.de> wrote: > Am Donnerstag, den 23.10.2014, 11:19 +0200 schrieb Geert Uytterhoeven: >> On Tue, Oct 21, 2014 at 4:19 PM, Rafael J. Wysocki <rjw@rjwysocki.net> wrote: >> > On Thursday, October 16, 2014 12:08:20 PM Lucas Stach wrote: >> >> If the regulator connected to the CPU voltage plane doesn't >> >> support an OPP specified voltage with the acceptable tolerance >> >> it's better to just disable the OPP instead of constantly >> >> failing the voltage scaling later on. >> >> >> >> Signed-off-by: Lucas Stach <l.stach@pengutronix.de> >> >> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> >> > >> > Applied, thanks! >> >> This commit >> (http://git.kernel.org/cgit/linux/kernel/git/rafael/linux-pm.git/commit/?h=linux-next&id=d7bbd4cd0359d781b67c9e621d4bbfd1bb2f3783) >> causes a boot regression on r8a7791/koelsch. It hangs after: >> >> TCP: cubic registered >> Initializing XFRM netlink socket >> NET: Registered protocol family 17 >> NET: Registered protocol family 15 >> ata1: link resume succeeded after 1 retries >> ata1: SATA link down (SStatus 0 SControl 300) >> random: nonblocking pool is initialized >> Reverting this commit fixes the issue, and makes the boot continue with: >> >> cpufreq: __cpufreq_add_dev: CPU0: Running at unlisted freq: 1300000 KHz >> cpufreq: __cpufreq_add_dev: CPU0: Unlisted initial frequency >> changed to: 1312500 KHz >> cpu cpu1: failed to get cpu-2 clock: 1 >> cpufreq_dt: cpufreq_init: Failed to allocate resources: -2 >> > > Urgh, thanks for the report. Am I right that for koelsch you do > reference a regulator supply for the cpu, but don't actually have a > driver for it, so a dummy regulator gets plugged in there? arch/arm/boot/dts/r8a7791-koelsch.dts has: &cpu0 { cpu0-supply = <&vdd_dvfs>; }; &i2c6 { status = "okay"; clock-frequency = <100000>; vdd_dvfs: regulator@68 { compatible = "dlg,da9210"; reg = <0x68>; regulator-min-microvolt = <1000000>; regulator-max-microvolt = <1000000>; regulator-boot-on; regulator-always-on; }; }; CONFIG_REGULATOR_DA9210=y and the driver does seem to run: DA9210: 1000 mV at 4600 mA Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds -- To unsubscribe from this list: send the line "unsubscribe linux-pm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Am Donnerstag, den 23.10.2014, 16:43 +0200 schrieb Geert Uytterhoeven: > Hi Lucas, > > On Thu, Oct 23, 2014 at 4:10 PM, Lucas Stach <l.stach@pengutronix.de> wrote: > > Am Donnerstag, den 23.10.2014, 11:19 +0200 schrieb Geert Uytterhoeven: > >> On Tue, Oct 21, 2014 at 4:19 PM, Rafael J. Wysocki <rjw@rjwysocki.net> wrote: > >> > On Thursday, October 16, 2014 12:08:20 PM Lucas Stach wrote: > >> >> If the regulator connected to the CPU voltage plane doesn't > >> >> support an OPP specified voltage with the acceptable tolerance > >> >> it's better to just disable the OPP instead of constantly > >> >> failing the voltage scaling later on. > >> >> > >> >> Signed-off-by: Lucas Stach <l.stach@pengutronix.de> > >> >> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> > >> > > >> > Applied, thanks! > >> > >> This commit > >> (http://git.kernel.org/cgit/linux/kernel/git/rafael/linux-pm.git/commit/?h=linux-next&id=d7bbd4cd0359d781b67c9e621d4bbfd1bb2f3783) > >> causes a boot regression on r8a7791/koelsch. It hangs after: > >> > >> TCP: cubic registered > >> Initializing XFRM netlink socket > >> NET: Registered protocol family 17 > >> NET: Registered protocol family 15 > >> ata1: link resume succeeded after 1 retries > >> ata1: SATA link down (SStatus 0 SControl 300) > >> random: nonblocking pool is initialized > > >> Reverting this commit fixes the issue, and makes the boot continue with: > >> > >> cpufreq: __cpufreq_add_dev: CPU0: Running at unlisted freq: 1300000 KHz > >> cpufreq: __cpufreq_add_dev: CPU0: Unlisted initial frequency > >> changed to: 1312500 KHz > >> cpu cpu1: failed to get cpu-2 clock: 1 > >> cpufreq_dt: cpufreq_init: Failed to allocate resources: -2 > >> > > > > Urgh, thanks for the report. Am I right that for koelsch you do > > reference a regulator supply for the cpu, but don't actually have a > > driver for it, so a dummy regulator gets plugged in there? > > arch/arm/boot/dts/r8a7791-koelsch.dts has: > > &cpu0 { > cpu0-supply = <&vdd_dvfs>; > }; > > &i2c6 { > status = "okay"; > clock-frequency = <100000>; > > vdd_dvfs: regulator@68 { > compatible = "dlg,da9210"; > reg = <0x68>; > > regulator-min-microvolt = <1000000>; > regulator-max-microvolt = <1000000>; > regulator-boot-on; > regulator-always-on; > }; > }; > > CONFIG_REGULATOR_DA9210=y > > and the driver does seem to run: > > DA9210: 1000 mV at 4600 mA > Ah right, I misread your initial report. So the issue doesn't seem to be directly related to the cpufreq-dt driver but seems to be located somewhere deeper down the chain. The fact that this change triggers the bug may be a hint here. The only thing which is new in the change is that it tries to get the supported voltage from the regulator. As the regulator can not change its voltage (min_uV == max_uV) this translates directly to a get_voltage() which in turn only tries to read a register of the i2c chip via regmap. So it seems that somehow the i2c transaction fails and things spin indefinitely there. Maybe this gives a clue on how to debug this further. Regards, Lucas
On Thursday, October 23, 2014 05:13:02 PM Lucas Stach wrote: > Am Donnerstag, den 23.10.2014, 16:43 +0200 schrieb Geert Uytterhoeven: > > Hi Lucas, > > > > On Thu, Oct 23, 2014 at 4:10 PM, Lucas Stach <l.stach@pengutronix.de> wrote: > > > Am Donnerstag, den 23.10.2014, 11:19 +0200 schrieb Geert Uytterhoeven: > > >> On Tue, Oct 21, 2014 at 4:19 PM, Rafael J. Wysocki <rjw@rjwysocki.net> wrote: > > >> > On Thursday, October 16, 2014 12:08:20 PM Lucas Stach wrote: > > >> >> If the regulator connected to the CPU voltage plane doesn't > > >> >> support an OPP specified voltage with the acceptable tolerance > > >> >> it's better to just disable the OPP instead of constantly > > >> >> failing the voltage scaling later on. > > >> >> > > >> >> Signed-off-by: Lucas Stach <l.stach@pengutronix.de> > > >> >> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> > > >> > > > >> > Applied, thanks! > > >> > > >> This commit > > >> (http://git.kernel.org/cgit/linux/kernel/git/rafael/linux-pm.git/commit/?h=linux-next&id=d7bbd4cd0359d781b67c9e621d4bbfd1bb2f3783) > > >> causes a boot regression on r8a7791/koelsch. It hangs after: > > >> > > >> TCP: cubic registered > > >> Initializing XFRM netlink socket > > >> NET: Registered protocol family 17 > > >> NET: Registered protocol family 15 > > >> ata1: link resume succeeded after 1 retries > > >> ata1: SATA link down (SStatus 0 SControl 300) > > >> random: nonblocking pool is initialized > > > > >> Reverting this commit fixes the issue, and makes the boot continue with: > > >> > > >> cpufreq: __cpufreq_add_dev: CPU0: Running at unlisted freq: 1300000 KHz > > >> cpufreq: __cpufreq_add_dev: CPU0: Unlisted initial frequency > > >> changed to: 1312500 KHz > > >> cpu cpu1: failed to get cpu-2 clock: 1 > > >> cpufreq_dt: cpufreq_init: Failed to allocate resources: -2 > > >> > > > > > > Urgh, thanks for the report. Am I right that for koelsch you do > > > reference a regulator supply for the cpu, but don't actually have a > > > driver for it, so a dummy regulator gets plugged in there? > > > > arch/arm/boot/dts/r8a7791-koelsch.dts has: > > > > &cpu0 { > > cpu0-supply = <&vdd_dvfs>; > > }; > > > > &i2c6 { > > status = "okay"; > > clock-frequency = <100000>; > > > > vdd_dvfs: regulator@68 { > > compatible = "dlg,da9210"; > > reg = <0x68>; > > > > regulator-min-microvolt = <1000000>; > > regulator-max-microvolt = <1000000>; > > regulator-boot-on; > > regulator-always-on; > > }; > > }; > > > > CONFIG_REGULATOR_DA9210=y > > > > and the driver does seem to run: > > > > DA9210: 1000 mV at 4600 mA > > > Ah right, I misread your initial report. So the issue doesn't seem to be > directly related to the cpufreq-dt driver but seems to be located > somewhere deeper down the chain. The fact that this change triggers the > bug may be a hint here. The only thing which is new in the change is > that it tries to get the supported voltage from the regulator. As the > regulator can not change its voltage (min_uV == max_uV) this translates > directly to a get_voltage() which in turn only tries to read a register > of the i2c chip via regmap. > > So it seems that somehow the i2c transaction fails and things spin > indefinitely there. Maybe this gives a clue on how to debug this > further. Well, I've dropped the patch for now. The underlying issue needs to be fixed before we can apply it again.
++Inami-san, author of recent CPUFreq patches. On 10/24/2014 6:26 AM, Rafael J. Wysocki wrote: > On Thursday, October 23, 2014 05:13:02 PM Lucas Stach wrote: >> Am Donnerstag, den 23.10.2014, 16:43 +0200 schrieb Geert Uytterhoeven: >>> Hi Lucas, >>> >>> On Thu, Oct 23, 2014 at 4:10 PM, Lucas Stach <l.stach@pengutronix.de> wrote: >>>> Am Donnerstag, den 23.10.2014, 11:19 +0200 schrieb Geert Uytterhoeven: >>>>> On Tue, Oct 21, 2014 at 4:19 PM, Rafael J. Wysocki <rjw@rjwysocki.net> wrote: >>>>>> On Thursday, October 16, 2014 12:08:20 PM Lucas Stach wrote: >>>>>>> If the regulator connected to the CPU voltage plane doesn't >>>>>>> support an OPP specified voltage with the acceptable tolerance >>>>>>> it's better to just disable the OPP instead of constantly >>>>>>> failing the voltage scaling later on. >>>>>>> >>>>>>> Signed-off-by: Lucas Stach <l.stach@pengutronix.de> >>>>>>> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> >>>>>> >>>>>> Applied, thanks! >>>>> >>>>> This commit >>>>> (http://git.kernel.org/cgit/linux/kernel/git/rafael/linux-pm.git/commit/?h=linux-next&id=d7bbd4cd0359d781b67c9e621d4bbfd1bb2f3783) >>>>> causes a boot regression on r8a7791/koelsch. It hangs after: >>>>> >>>>> TCP: cubic registered >>>>> Initializing XFRM netlink socket >>>>> NET: Registered protocol family 17 >>>>> NET: Registered protocol family 15 >>>>> ata1: link resume succeeded after 1 retries >>>>> ata1: SATA link down (SStatus 0 SControl 300) >>>>> random: nonblocking pool is initialized >>> >>>>> Reverting this commit fixes the issue, and makes the boot continue with: >>>>> >>>>> cpufreq: __cpufreq_add_dev: CPU0: Running at unlisted freq: 1300000 KHz >>>>> cpufreq: __cpufreq_add_dev: CPU0: Unlisted initial frequency >>>>> changed to: 1312500 KHz >>>>> cpu cpu1: failed to get cpu-2 clock: 1 >>>>> cpufreq_dt: cpufreq_init: Failed to allocate resources: -2 >>>>> >>>> >>>> Urgh, thanks for the report. Am I right that for koelsch you do >>>> reference a regulator supply for the cpu, but don't actually have a >>>> driver for it, so a dummy regulator gets plugged in there? >>> >>> arch/arm/boot/dts/r8a7791-koelsch.dts has: >>> >>> &cpu0 { >>> cpu0-supply = <&vdd_dvfs>; >>> }; >>> >>> &i2c6 { >>> status = "okay"; >>> clock-frequency = <100000>; >>> >>> vdd_dvfs: regulator@68 { >>> compatible = "dlg,da9210"; >>> reg = <0x68>; >>> >>> regulator-min-microvolt = <1000000>; >>> regulator-max-microvolt = <1000000>; >>> regulator-boot-on; >>> regulator-always-on; >>> }; >>> }; >>> >>> CONFIG_REGULATOR_DA9210=y >>> >>> and the driver does seem to run: >>> >>> DA9210: 1000 mV at 4600 mA >>> >> Ah right, I misread your initial report. So the issue doesn't seem to be >> directly related to the cpufreq-dt driver but seems to be located >> somewhere deeper down the chain. The fact that this change triggers the >> bug may be a hint here. The only thing which is new in the change is >> that it tries to get the supported voltage from the regulator. As the >> regulator can not change its voltage (min_uV == max_uV) this translates >> directly to a get_voltage() which in turn only tries to read a register >> of the i2c chip via regmap. >> >> So it seems that somehow the i2c transaction fails and things spin >> indefinitely there. Maybe this gives a clue on how to debug this >> further. > > Well, I've dropped the patch for now. The underlying issue needs to be fixed > before we can apply it again. > >
Geert, Am Donnerstag, den 23.10.2014, 16:43 +0200 schrieb Geert Uytterhoeven: > Hi Lucas, > > On Thu, Oct 23, 2014 at 4:10 PM, Lucas Stach <l.stach@pengutronix.de> wrote: > > Am Donnerstag, den 23.10.2014, 11:19 +0200 schrieb Geert Uytterhoeven: > >> On Tue, Oct 21, 2014 at 4:19 PM, Rafael J. Wysocki <rjw@rjwysocki.net> wrote: > >> > On Thursday, October 16, 2014 12:08:20 PM Lucas Stach wrote: > >> >> If the regulator connected to the CPU voltage plane doesn't > >> >> support an OPP specified voltage with the acceptable tolerance > >> >> it's better to just disable the OPP instead of constantly > >> >> failing the voltage scaling later on. > >> >> > >> >> Signed-off-by: Lucas Stach <l.stach@pengutronix.de> > >> >> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> > >> > > >> > Applied, thanks! > >> > >> This commit > >> (http://git.kernel.org/cgit/linux/kernel/git/rafael/linux-pm.git/commit/?h=linux-next&id=d7bbd4cd0359d781b67c9e621d4bbfd1bb2f3783) > >> causes a boot regression on r8a7791/koelsch. It hangs after: > >> > >> TCP: cubic registered > >> Initializing XFRM netlink socket > >> NET: Registered protocol family 17 > >> NET: Registered protocol family 15 > >> ata1: link resume succeeded after 1 retries > >> ata1: SATA link down (SStatus 0 SControl 300) > >> random: nonblocking pool is initialized > > >> Reverting this commit fixes the issue, and makes the boot continue with: > >> > >> cpufreq: __cpufreq_add_dev: CPU0: Running at unlisted freq: 1300000 KHz > >> cpufreq: __cpufreq_add_dev: CPU0: Unlisted initial frequency > >> changed to: 1312500 KHz > >> cpu cpu1: failed to get cpu-2 clock: 1 > >> cpufreq_dt: cpufreq_init: Failed to allocate resources: -2 > >> > > I thought a bit more about about this to make sure this isn't a fault on my side, but can't seem to make any sense out of this. Can you please print out the value of opp_freq in each iteration of the while loop and also the return value of regulator_is_supported_voltage()? This would help me a lot to understand what's happening here. Thanks, Lucas
diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index 6bbb8b913446..4485c8eccdc2 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -185,6 +185,7 @@ static int cpufreq_init(struct cpufreq_policy *policy) struct device *cpu_dev; struct regulator *cpu_reg; struct clk *cpu_clk; + unsigned long min_uV = ~0, max_uV = 0; unsigned int transition_latency; int ret; @@ -204,16 +205,10 @@ static int cpufreq_init(struct cpufreq_policy *policy) /* OPPs might be populated at runtime, don't check for error here */ of_init_opp_table(cpu_dev); - ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table); - if (ret) { - dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret); - goto out_put_node; - } - priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { ret = -ENOMEM; - goto out_free_table; + goto out_put_node; } of_property_read_u32(np, "voltage-tolerance", &priv->voltage_tolerance); @@ -222,30 +217,49 @@ static int cpufreq_init(struct cpufreq_policy *policy) transition_latency = CPUFREQ_ETERNAL; if (!IS_ERR(cpu_reg)) { - struct dev_pm_opp *opp; - unsigned long min_uV, max_uV; - int i; - /* - * OPP is maintained in order of increasing frequency, and - * freq_table initialised from OPP is therefore sorted in the - * same order. + * Disable any OPPs where the connected regulator isn't able to + * provide the specified voltage and record minimum and maximum + * voltage levels. */ - for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) - ; - rcu_read_lock(); - opp = dev_pm_opp_find_freq_exact(cpu_dev, - freq_table[0].frequency * 1000, true); - min_uV = dev_pm_opp_get_voltage(opp); - opp = dev_pm_opp_find_freq_exact(cpu_dev, - freq_table[i-1].frequency * 1000, true); - max_uV = dev_pm_opp_get_voltage(opp); - rcu_read_unlock(); + while (1) { + struct dev_pm_opp *opp; + unsigned long opp_freq = 0, opp_uV, tol_uV; + + rcu_read_lock(); + opp = dev_pm_opp_find_freq_ceil(cpu_dev, &opp_freq); + if (IS_ERR(opp)) { + rcu_read_unlock(); + break; + } + opp_uV = dev_pm_opp_get_voltage(opp); + rcu_read_unlock(); + + tol_uV = opp_uV * priv->voltage_tolerance / 100; + if (regulator_is_supported_voltage(cpu_reg, opp_uV, + opp_uV + tol_uV)) { + if (opp_uV < min_uV) + min_uV = opp_uV; + if (opp_uV > max_uV) + max_uV = opp_uV; + } else { + dev_pm_opp_disable(cpu_dev, opp_freq); + } + + opp_freq++; + } + ret = regulator_set_voltage_time(cpu_reg, min_uV, max_uV); if (ret > 0) transition_latency += ret * 1000; } + ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table); + if (ret) { + pr_err("failed to init cpufreq table: %d\n", ret); + goto out_free_priv; + } + /* * For now, just loading the cooling device; * thermal DT code takes care of matching them. @@ -275,9 +289,9 @@ static int cpufreq_init(struct cpufreq_policy *policy) out_cooling_unregister: cpufreq_cooling_unregister(priv->cdev); - kfree(priv); -out_free_table: dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); +out_free_priv: + kfree(priv); out_put_node: of_node_put(np); out_put_reg_clk: