diff mbox

[RESEND,2] cpufreq: dt: disable unsupported OPPs

Message ID 1413454100-23009-1-git-send-email-l.stach@pengutronix.de (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Lucas Stach Oct. 16, 2014, 10:08 a.m. UTC
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>
---
resend 2:
- no functional change, rebase against latest Linus tree
- added Viresh's ack
resend:
- no functional change, split out from the imx5 cpufreq series
v2:
- rebase on top of pm/linux-next
---
 drivers/cpufreq/cpufreq-dt.c | 66 +++++++++++++++++++++++++++-----------------
 1 file changed, 40 insertions(+), 26 deletions(-)

Comments

Rafael J. Wysocki Oct. 21, 2014, 2:19 p.m. UTC | #1
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!
Geert Uytterhoeven Oct. 23, 2014, 9:19 a.m. UTC | #2
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
Lucas Stach Oct. 23, 2014, 2:10 p.m. UTC | #3
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
Geert Uytterhoeven Oct. 23, 2014, 2:43 p.m. UTC | #4
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
Lucas Stach Oct. 23, 2014, 3:13 p.m. UTC | #5
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
Rafael J. Wysocki Oct. 23, 2014, 9:26 p.m. UTC | #6
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.
Khiem Nguyen Oct. 24, 2014, 12:26 a.m. UTC | #7
++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.
> 
>
Lucas Stach Oct. 24, 2014, 10:19 a.m. UTC | #8
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 mbox

Patch

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: