diff mbox

[2/2] regulator: core: Ensure we are at least in bounds for our constraints

Message ID CAMuHMdXuy2TxACTcsgOpZvrJEeTSQbCgCUmS9PXfBhhZfgbBBA@mail.gmail.com (mailing list archive)
State Superseded
Delegated to: Geert Uytterhoeven
Headers show

Commit Message

Geert Uytterhoeven March 29, 2016, noon UTC
Hi Mark,

On Sun, Mar 27, 2016 at 11:08 AM, Mark Brown <broonie@kernel.org> wrote:
> On Sat, Mar 26, 2016 at 04:50:41PM -0700, Bjorn Andersson wrote:
>
>> Reinstating the following snippet in of_get_regulation_constraints()
>> sort this out:
>
>> if (constraints->min_uV && constraints->max_uV)
>>                                        constraints->apply_uV = true;
>
> The existing check in the patch should be an || not an ==, or possibly
> we should just not bother looking for min_uV at all.  I just pushed out
> a version of that, let's see how that goes.

Has the fix really been pushed out?

With commit fa93fd4ecc9c58475abac6db93a797bff893bc16
Author: Mark Brown <broonie@kernel.org>
Date:   Mon Mar 21 18:12:52 2016 +0000

    regulator: core: Ensure we are at least in bounds for our constraints

I see a few cases of

------------[ cut here ]------------
WARNING: CPU: 1 PID: 31 at drivers/regulator/core.c:2223
_regulator_disable+0x2c/0x128
unbalanced disables for SDHI0 VccQ
Modules linked in:
CPU: 1 PID: 31 Comm: kworker/1:1 Not tainted
4.6.0-rc1-koelsch-00724-g58d619227282dc16 #2422
Hardware name: Generic R8A7791 (Flattened Device Tree)
Workqueue: events_freezable mmc_rescan
sh_mobile_sdhi ee140000.sd: could not set regulator OCR (-22)

[<c020e040>] (unwind_backtrace) from [<c0209d70>] (show_stack+0x10/0x14)
[<c0209d70>] (show_stack) from [<c03c7584>] (dump_stack+0x7c/0x9c)
[<c03c7584>] (dump_stack) from [<c021fa48>] (__warn+0xcc/0xfc)
[<c021fa48>] (__warn) from [<c021faac>] (warn_slowpath_fmt+0x34/0x44)
[<c021faac>] (warn_slowpath_fmt) from [<c041e464>]
(_regulator_disable+0x2c/0x128)
[<c041e464>] (_regulator_disable) from [<c041e590>]
(regulator_disable+0x30/0x60)
[<c041e590>] (regulator_disable) from [<c0572e18>] (tmio_mmc_set_ios+0xb8/0x1d4)
[<c0572e18>] (tmio_mmc_set_ios) from [<c056300c>] (mmc_power_off+0x34/0x54)
[<c056300c>] (mmc_power_off) from [<c0563a5c>] (mmc_rescan+0x214/0x30c)
[<c0563a5c>] (mmc_rescan) from [<c0233368>] (process_one_work+0x1bc/0x2f4)
[<c0233368>] (process_one_work) from [<c0233a2c>] (worker_thread+0x2a8/0x3d0)
[<c0233a2c>] (worker_thread) from [<c0237a9c>] (kthread+0xd8/0xec)
[<c0237a9c>] (kthread) from [<c0206b68>] (ret_from_fork+0x14/0x2c)
---[ end trace 1c61a7f6221c11ea ]---

when booting on r8a7791/koelsch.

I'm a bit confused by the discussion of "&&" vs. "||" vs. "==", but the
warnings do go away when using "!=", cfr. the whitespace-damaged patch below.


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

Comments

Mark Brown March 29, 2016, 2:58 p.m. UTC | #1
On Tue, Mar 29, 2016 at 02:00:52PM +0200, Geert Uytterhoeven wrote:
> On Sun, Mar 27, 2016 at 11:08 AM, Mark Brown <broonie@kernel.org> wrote:

> > The existing check in the patch should be an || not an ==, or possibly
> > we should just not bother looking for min_uV at all.  I just pushed out
> > a version of that, let's see how that goes.

> Has the fix really been pushed out?

Yes.

> WARNING: CPU: 1 PID: 31 at drivers/regulator/core.c:2223
> _regulator_disable+0x2c/0x128
> unbalanced disables for SDHI0 VccQ

> when booting on r8a7791/koelsch.

This seems like a bug somewhere else in your code, we're looking at
changes in the voltage setting code but this is an unbalanced disable.

> I'm a bit confused by the discussion of "&&" vs. "||" vs. "==", but the
> warnings do go away when using "!=", cfr. the whitespace-damaged patch below.

>         /* Voltage change possible? */
> -       if (constraints->min_uV && constraints->max_uV) {
> +       if (constraints->min_uV != constraints->max_uV) {

Do you have constraints that specify a maximum voltage but no minimum
(which I'd say are broken), or constraints that are just plain wrong but
are now being applied like specifying the entire range of the regulator?
The above might be some follow on error handling from something that
happened the change in handling of the constraints.  You need to look at
what the relevant regulator constraints are...

Previously both voltages needed to be non-zero and equal for anything to
happen, now they only need to both be non-zero.
Geert Uytterhoeven March 29, 2016, 6:05 p.m. UTC | #2
On Tue, Mar 29, 2016 at 4:58 PM, Mark Brown <broonie@kernel.org> wrote:
> On Tue, Mar 29, 2016 at 02:00:52PM +0200, Geert Uytterhoeven wrote:
>> On Sun, Mar 27, 2016 at 11:08 AM, Mark Brown <broonie@kernel.org> wrote:
>
>> > The existing check in the patch should be an || not an ==, or possibly
>> > we should just not bother looking for min_uV at all.  I just pushed out
>> > a version of that, let's see how that goes.
>
>> Has the fix really been pushed out?
>
> Yes.
>
>> WARNING: CPU: 1 PID: 31 at drivers/regulator/core.c:2223
>> _regulator_disable+0x2c/0x128
>> unbalanced disables for SDHI0 VccQ
>
>> when booting on r8a7791/koelsch.
>
> This seems like a bug somewhere else in your code, we're looking at
> changes in the voltage setting code but this is an unbalanced disable.
>
>> I'm a bit confused by the discussion of "&&" vs. "||" vs. "==", but the
>> warnings do go away when using "!=", cfr. the whitespace-damaged patch below.
>
>>         /* Voltage change possible? */
>> -       if (constraints->min_uV && constraints->max_uV) {
>> +       if (constraints->min_uV != constraints->max_uV) {
>
> Do you have constraints that specify a maximum voltage but no minimum
> (which I'd say are broken), or constraints that are just plain wrong but
> are now being applied like specifying the entire range of the regulator?
> The above might be some follow on error handling from something that
> happened the change in handling of the constraints.  You need to look at
> what the relevant regulator constraints are...
>
> Previously both voltages needed to be non-zero and equal for anything to
> happen, now they only need to both be non-zero.

There are 3 regulators with equal constraints:

/regulator@0: constraints->min_uV = 3300000, constraints->max_uV = 3300000
/regulator@2: constraints->min_uV = 3300000, constraints->max_uV = 3300000
/regulator@4: constraints->min_uV = 3300000, constraints->max_uV = 3300000

and 3 with different constraints:

/regulator@1: constraints->min_uV = 1800000, constraints->max_uV = 3300000
/regulator@3: constraints->min_uV = 1800000, constraints->max_uV = 3300000
/regulator@5: constraints->min_uV = 1800000, constraints->max_uV = 3300000

For the first SDHI channel, these come from:

        vcc_sdhi0: regulator@0 {
                compatible = "regulator-fixed";

                regulator-name = "SDHI0 Vcc";
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;

                gpio = <&gpio7 17 GPIO_ACTIVE_HIGH>;
                enable-active-high;
        };

        vccq_sdhi0: regulator@1 {
                compatible = "regulator-gpio";

                regulator-name = "SDHI0 VccQ";
                regulator-min-microvolt = <1800000>;
                regulator-max-microvolt = <3300000>;

                gpios = <&gpio2 12 GPIO_ACTIVE_HIGH>;
                gpios-states = <1>;
                states = <3300000 1
                          1800000 0>;
        };

        &sdhi0 {
                pinctrl-0 = <&sdhi0_pins>;
                pinctrl-names = "default";

                vmmc-supply = <&vcc_sdhi0>;
                vqmmc-supply = <&vccq_sdhi0>;
                cd-gpios = <&gpio6 6 GPIO_ACTIVE_LOW>;
                wp-gpios = <&gpio6 7 GPIO_ACTIVE_HIGH>;
                status = "okay";
        };

giving:

        sh_mobile_sdhi ee100000.sd: GPIO lookup for consumer cd
        sh_mobile_sdhi ee100000.sd: using device tree for GPIO lookup
        of_get_named_gpiod_flags: parsed 'cd-gpios' property of node
'/sd@ee100000[0]' - status (0)
        sh_mobile_sdhi ee100000.sd: Got CD GPIO
        sh_mobile_sdhi ee100000.sd: GPIO lookup for consumer wp
        sh_mobile_sdhi ee100000.sd: using device tree for GPIO lookup
        of_get_named_gpiod_flags: parsed 'wp-gpios' property of node
'/sd@ee100000[0]' - status (0)
        sh_mobile_sdhi ee100000.sd: Got WP GPIO
======> sh_mobile_sdhi ee100000.sd: could not set regulator OCR (-22)
        gpio_rcar e6055400.gpio: sense irq = 6, type = 3
        sh_mobile_sdhi ee100000.sd: mmc0 base at 0xee100000 clock rate 97 MHz

The line marked with the arrow is introduced by the changed check, and looks
to be the origin of the failure.

Later, the "unbalanced disables for SDHI0 VccQ" warning is triggered.
Probably the error path always disables the second regulator, even if it was
never enabled due an the earlier failure.

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
Mark Brown March 29, 2016, 6:27 p.m. UTC | #3
On Tue, Mar 29, 2016 at 08:05:34PM +0200, Geert Uytterhoeven wrote:

>         sh_mobile_sdhi ee100000.sd: Got WP GPIO
> ======> sh_mobile_sdhi ee100000.sd: could not set regulator OCR (-22)
>         gpio_rcar e6055400.gpio: sense irq = 6, type = 3
>         sh_mobile_sdhi ee100000.sd: mmc0 base at 0xee100000 clock rate 97 MHz

> The line marked with the arrow is introduced by the changed check, and looks
> to be the origin of the failure.

This isn't making any sense.  Why would a change in how we apply voltage
constraints on initial probe of the regulator have an impact here?  The
changed code shouldn't even be executing at the point where the SDHCI
driver is trying to use the regulator.  There's something else going on
here.
Bough Chen March 30, 2016, 9:07 a.m. UTC | #4
Hi Brown,

I also meet the similar issue on i.MX6 platforms.

With your patch   ---> regulator: core: Ensure we are at least in bounds for our constraints
When I insert an SD3.0 card, shows the following log:

root@imx6qdlsolo:~# [   59.733941] sdhci-esdhc-imx 2190000.usdhc: could not set regulator OCR (-22)
[   60.829911] sdhci-esdhc-imx 2190000.usdhc: could not set regulator OCR (-22)
[   61.917951] sdhci-esdhc-imx 2190000.usdhc: could not set regulator OCR (-22)
[   63.009498] sdhci-esdhc-imx 2190000.usdhc: could not set regulator OCR (-22)

I did a quick debug, and find when I change the operator   &&  to  !=  , this issue gone.
-       if (constraints->min_uV != constraints->max_uV) {
+       if (constraints->min_uV && constraints->max_uV) {


In our sdhci.c, we call the function 
regulator_set_voltage ---> regulator_set_voltage_unlocked(struct regulator *regulator, int min_uV, int max_uV)
here, the parameter min_uV is 3300000, and the max_uV is 3400000

currently with your patch (the upper operator is &&), when insert a SD3.0 card, 
it will do the sanity check, and return -EINVAL

but when I change the upper operator from && to !=, 
before the sanity check, it will first get the current_uV, and then go to out.

I'm not familiar with regulator common code. Hope the upper describe can help you debug this issue.

The following attach our dts piece code.

126 &usdhc1 {
127         pinctrl-names = "default", "state_100mhz", "state_200mhz";
128         pinctrl-0 = <&pinctrl_usdhc1>;
129         pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
130         pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
131         cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
132         keep-power-in-suspend;
133         wakeup-source;
134         vmmc-supply = <&reg_sd1_vmmc>;
135         status = "okay";
136 };

regulators {
 26                 compatible = "simple-bus";
 27                 #address-cells = <1>;
 28                 #size-cells = <0>;
 29
 30                 reg_sd1_vmmc: sd1_regulator {
 31                         compatible = "regulator-fixed";
 32                         regulator-name = "VSD_3V3";
 33                         regulator-min-microvolt = <3300000>;
 34                         regulator-max-microvolt = <3300000>;
 35                         gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>;
 36                         enable-active-high;
 37                 };
 38         };

Best Regards
Haibo Chen



> -----Original Message-----
> From: linux-mmc-owner@vger.kernel.org [mailto:linux-mmc-
> owner@vger.kernel.org] On Behalf Of Mark Brown
> Sent: Wednesday, March 30, 2016 2:27 AM
> To: Geert Uytterhoeven <geert@linux-m68k.org>
> Cc: Bjorn Andersson <bjorn@kryo.se>; Krzysztof Kozlowski
> <k.kozlowski@samsung.com>; Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>;
> Liam Girdwood <lgirdwood@gmail.com>; linux-kernel@vger.kernel.org; Ulf
> Hansson <ulf.hansson@linaro.org>; linux-mmc <linux-mmc@vger.kernel.org>;
> linux-samsung-soc <linux-samsung-soc@vger.kernel.org>; Javier Martinez
> Canillas <javier@osg.samsung.com>; Marek Szyprowski
> <m.szyprowski@samsung.com>; linux-renesas-soc@vger.kernel.org
> Subject: Re: [PATCH 2/2] regulator: core: Ensure we are at least in bounds for
> our constraints
> 
> On Tue, Mar 29, 2016 at 08:05:34PM +0200, Geert Uytterhoeven wrote:
> 
> >         sh_mobile_sdhi ee100000.sd: Got WP GPIO ======> sh_mobile_sdhi
> > ee100000.sd: could not set regulator OCR (-22)
> >         gpio_rcar e6055400.gpio: sense irq = 6, type = 3
> >         sh_mobile_sdhi ee100000.sd: mmc0 base at 0xee100000 clock rate
> > 97 MHz
> 
> > The line marked with the arrow is introduced by the changed check, and
> > looks to be the origin of the failure.
> 
> This isn't making any sense.  Why would a change in how we apply voltage
> constraints on initial probe of the regulator have an impact here?  The changed
> code shouldn't even be executing at the point where the SDHCI driver is trying
> to use the regulator.  There's something else going on here.
diff mbox

Patch

--- a/drivers/regulator/of_regulator.c
+++ b/drivers/regulator/of_regulator.c
@@ -43,7 +43,7 @@  static void of_get_regulation_constraints(struct device_node *
                constraints->max_uV = pval;

        /* Voltage change possible? */
-       if (constraints->min_uV && constraints->max_uV) {
+       if (constraints->min_uV != constraints->max_uV) {
                constraints->valid_ops_mask |= REGULATOR_CHANGE_VOLTAGE;
                constraints->apply_uV = true;
        }