Skip to contentSkip to conversation

mmc: pwrseq_simple: Fix regression with optional GPIOs

PATCH New Tony Lindgren 3 participants 11 messages Dec 7, 2015 – Dec 28, 2015 MMC, SD and SDIO

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 mmc: pwrseq_simple: Fix regression with optional GPIOs

Commit ce037275861e ("mmc: pwrseq_simple: use GPIO descriptors array API") changed the handling MMC power sequence so GPIOs no longer are optional.

This broke SDIO WLAN at least for omap5 that can't yet use the reset GPIOs with pwrseq_simple as a wait is needed after enabling the SDIO device.

Let's fix the problem by allocating the GPIO values array during init depending on the optional GPIOs found.

Note that depending on the board specific configuration, some of the GPIOs can be permanently set up with pulls, so we want to keep pwrseq_simple GPIOs optional.

Cc Javier Martinez Canillas <[email protected]>
---
 drivers/mmc/core/pwrseq_simple.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)
drivers/mmc/core/pwrseq_simple.c +16 -4
@@ -24,6 +24,7 @@ struct mmc_pwrseq_simple {
 	bool clk_enabled;
 	struct clk *ext_clk;
 	struct gpio_descs *reset_gpios;
+	int *values;
 };
 
 static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq,
@@ -31,13 +32,15 @@ static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq,
 {
 	int i;
 	struct gpio_descs *reset_gpios = pwrseq->reset_gpios;
-	int values[reset_gpios->ndescs];
+
+	if (!reset_gpios || !reset_gpios->ndescs)
+		return;
 
 	for (i = 0; i < reset_gpios->ndescs; i++)
-		values[i] = value;
+		pwrseq->values[i] = value;
 
 	gpiod_set_array_value_cansleep(reset_gpios->ndescs, reset_gpios->desc,
-				       values);
+				       pwrseq->values);
 }
 
 static void mmc_pwrseq_simple_pre_power_on(struct mmc_host *host)
@@ -84,6 +87,7 @@ static void mmc_pwrseq_simple_free(struct mmc_host *host)
 	if (!IS_ERR(pwrseq->ext_clk))
 		clk_put(pwrseq->ext_clk);
 
+	kfree(pwrseq->values);
 	kfree(pwrseq);
 }
 
@@ -111,12 +115,20 @@ struct mmc_pwrseq *mmc_pwrseq_simple_alloc(struct mmc_host *host,
 		goto free;
 	}
 
-	pwrseq->reset_gpios = gpiod_get_array(dev, "reset", GPIOD_OUT_HIGH);
+	pwrseq->reset_gpios = gpiod_get_array_optional(dev, "reset",
+						       GPIOD_OUT_HIGH);
 	if (IS_ERR(pwrseq->reset_gpios)) {
 		ret = PTR_ERR(pwrseq->reset_gpios);
 		goto clk_put;
 	}
 
+	if (pwrseq->reset_gpios && pwrseq->reset_gpios->ndescs) {
+		pwrseq->values = kzalloc(pwrseq->reset_gpios->ndescs *
+					 sizeof(int), GFP_KERNEL);
+		if (!pwrseq->values)
+			goto clk_put;
+	}
+
 	pwrseq->pwrseq.ops = &mmc_pwrseq_simple_ops;
 
 	return &pwrseq->pwrseq;
Signature · 1 line
2.6.2
#1 lore raw

PATCH 1/1 mmc: pwrseq_simple: Fix regression with optional GPIOs

+Linus

Quoted 5 lines · Tony Lindgren

Commit ce037275861e ("mmc: pwrseq_simple: use GPIO descriptors array API") changed the handling MMC power sequence so GPIOs no longer are optional.

This broke SDIO WLAN at least for omap5 that can't yet use the reset GPIOs with pwrseq_simple as a wait is needed after enabling the SDIO device.

Can you elaborate on this. Did it break omap5 or not? :-)

Also, I am interested to know more about the waiting period you need. I assume that's because of the HW's characteristic?

Why can't we have that being described in DT and then make pwrseq_simple *wait* if needed?

Quoted 3 lines

Let's fix the problem by allocating the GPIO values array during init depending on the optional GPIOs found.

Certainly it shall be optional! I wonder how I could let that patch slip through, my bad!

Thanks for fixing this!

Quoted 22 lines

Note that depending on the board specific configuration, some of the GPIOs can be permanently set up with pulls, so we want to keep pwrseq_simple GPIOs optional.

Cc Javier Martinez Canillas <[email protected]>
---
 drivers/mmc/core/pwrseq_simple.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)
drivers/mmc/core/pwrseq_simple.c +1 -0
@@ -24,6 +24,7 @@ struct mmc_pwrseq_simple {
        bool clk_enabled;
        struct clk *ext_clk;
        struct gpio_descs *reset_gpios;
+       int *values;
 };
 
 static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq,

drivers/mmc/core/pwrseq_simple.c static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq, · line 34

Quoted 4 lines
drivers/mmc/core/pwrseq_simple.c +0 -1
@@ -31,13 +32,15 @@ static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq,
 {
        int i;
        struct gpio_descs *reset_gpios = pwrseq->reset_gpios;
-       int values[reset_gpios->ndescs];

I would prefer if we don't need to keep this memory on the heap.

Can't we instead keep a local copy of the reset_gpios->ndesc and when pwrseq->reset_gpios doesn't exist use a default value?

Quoted 23 lines
drivers/mmc/core/pwrseq_simple.c +6 -2
+
+       if (!reset_gpios || !reset_gpios->ndescs)
+               return;
 
        for (i = 0; i < reset_gpios->ndescs; i++)
-               values[i] = value;
+               pwrseq->values[i] = value;
 
        gpiod_set_array_value_cansleep(reset_gpios->ndescs, reset_gpios->desc,
-                                      values);
+                                      pwrseq->values);
 }
 
 static void mmc_pwrseq_simple_pre_power_on(struct mmc_host *host)
@@ -84,6 +87,7 @@ static void mmc_pwrseq_simple_free(struct mmc_host *host)
        if (!IS_ERR(pwrseq->ext_clk))
                clk_put(pwrseq->ext_clk);
 
+       kfree(pwrseq->values);
        kfree(pwrseq);
 }
 

drivers/mmc/core/pwrseq_simple.c struct mmc_pwrseq *mmc_pwrseq_simple_alloc(struct mmc_host *host, · line 120

Quoted 7 lines
drivers/mmc/core/pwrseq_simple.c +2 -1
@@ -111,12 +115,20 @@ struct mmc_pwrseq *mmc_pwrseq_simple_alloc(struct mmc_host *host,
                goto free;
        }
 
-       pwrseq->reset_gpios = gpiod_get_array(dev, "reset", GPIOD_OUT_HIGH);
+       pwrseq->reset_gpios = gpiod_get_array_optional(dev, "reset",
+                                                      GPIOD_OUT_HIGH);
        if (IS_ERR(pwrseq->reset_gpios)) {

The original code also considered -ENOSYS, as that's the return code you get when CONFIG_GPIOLIB is unset, I think we need that as well.

Although, perhaps it's more correct that the gpiolib API returns NULL instead of ERR_PTR(-ENOSYS)?

I have added Linus, to see if he has any comments on this.

drivers/mmc/core/pwrseq_simple.c struct mmc_pwrseq *mmc_pwrseq_simple_alloc(struct mmc_host *host, · line 129

Quoted 9 lines
drivers/mmc/core/pwrseq_simple.c +5 -0
                ret = PTR_ERR(pwrseq->reset_gpios);
                goto clk_put;
        }
 
+       if (pwrseq->reset_gpios && pwrseq->reset_gpios->ndescs) {
+               pwrseq->values = kzalloc(pwrseq->reset_gpios->ndescs *
+                                        sizeof(int), GFP_KERNEL);
+               if (!pwrseq->values)
+                       goto clk_put;

This will leak a gpio cookie as it needs a gpiod_put_array().

Quoted 8 lines
drivers/mmc/core/pwrseq_simple.c +2 -1
+       }
+
        pwrseq->pwrseq.ops = &mmc_pwrseq_simple_ops;
 
        return &pwrseq->pwrseq;
--

2.6.2

One final comment, gpiod_put_array() doesn't deal with NULL pointers. You need to check that in mmc_pwrseq_simple_free().

Kind regards
Uffe

#2 lore raw

PATCH 1/1 mmc: pwrseq_simple: Fix regression with optional GPIOs

Quoted 10 lines · Ulf Hansson

+Linus

Quoted 5 lines · Tony Lindgren

Commit ce037275861e ("mmc: pwrseq_simple: use GPIO descriptors array API") changed the handling MMC power sequence so GPIOs no longer are optional.

This broke SDIO WLAN at least for omap5 that can't yet use the reset GPIOs with pwrseq_simple as a wait is needed after enabling the SDIO device.

Can you elaborate on this. Did it break omap5 or not? :-)

Yes it broke WLAN for omap5 that I just got fixed.. It only uses the clocks art of the pwrseq currently because of the delay needed.

Quoted 2 lines

Also, I am interested to know more about the waiting period you need. I assume that's because of the HW's characteristic?

At least TI wl12xx and Marvell 8787 need a delay after enabling the the WLAN.

Quoted 2 lines

Why can't we have that being described in DT and then make pwrseq_simple *wait* if needed?

We can, but I'm thinking that we might be better off adding support for regulators to pwrseq. Both TI wl12xx and Marvell 8787 get power from the battery, and probably have an integrated regulator.

Also, the delay and the power up sequencey can be more complicated than what we currently support. In the 8787 case, pdn pin needs to be asserted for 300ms after power pins are stable and while reset is held high.

Quoted 5 lines
Quoted 2 lines

Let's fix the problem by allocating the GPIO values array during init depending on the optional GPIOs found.

Certainly it shall be optional! I wonder how I could let that patch slip through, my bad!

OK good to hear :)

Quoted 1 line

Thanks for fixing this!

No problem, thanks,

Tony

#3 lore raw

PATCH 1/1 mmc: pwrseq_simple: Fix regression with optional GPIOs

Hello Tony,

Quoted 23 lines · Tony Lindgren
Quoted 10 lines · Ulf Hansson

+Linus

Quoted 5 lines · Tony Lindgren

Commit ce037275861e ("mmc: pwrseq_simple: use GPIO descriptors array API") changed the handling MMC power sequence so GPIOs no longer are optional.

This broke SDIO WLAN at least for omap5 that can't yet use the reset GPIOs with pwrseq_simple as a wait is needed after enabling the SDIO device.

Can you elaborate on this. Did it break omap5 or not? :-)

Yes it broke WLAN for omap5 that I just got fixed.. It only uses the clocks art of the pwrseq currently because of the delay needed.

Quoted 2 lines

Also, I am interested to know more about the waiting period you need. I assume that's because of the HW's characteristic?

At least TI wl12xx and Marvell 8787 need a delay after enabling the the WLAN.

Quoted 2 lines

Why can't we have that being described in DT and then make pwrseq_simple *wait* if needed?

Quoted 14 lines

We can, but I'm thinking that we might be better off adding support for regulators to pwrseq. Both TI wl12xx and Marvell 8787 get power from the battery, and probably have an integrated regulator.

Also, the delay and the power up sequencey can be more complicated than what we currently support. In the 8787 case, pdn pin needs to be asserted for 300ms after power pins are stable and while reset is held high.

Quoted 5 lines
Quoted 2 lines

Let's fix the problem by allocating the GPIO values array during init depending on the optional GPIOs found.

Certainly it shall be optional! I wonder how I could let that patch slip through, my bad!

I also wonder how I missed that in my patch, sorry for the mess :(

Quoted 4 lines

OK good to hear :)

Quoted 1 line

Thanks for fixing this!

+1

Quoted 4 lines

No problem, thanks,

Tony

Best regards,

Signature · 3 lines
Javier Martinez Canillas
Open Source Group
Samsung Research America
#4 lore raw

PATCH 1/1 mmc: pwrseq_simple: Fix regression with optional GPIOs

In reply to Tony Lindgren
Quoted 18 lines · Tony Lindgren
Quoted 10 lines · Ulf Hansson

+Linus

Quoted 5 lines · Tony Lindgren

Commit ce037275861e ("mmc: pwrseq_simple: use GPIO descriptors array API") changed the handling MMC power sequence so GPIOs no longer are optional.

This broke SDIO WLAN at least for omap5 that can't yet use the reset GPIOs with pwrseq_simple as a wait is needed after enabling the SDIO device.

Can you elaborate on this. Did it break omap5 or not? :-)

Yes it broke WLAN for omap5 that I just got fixed.. It only uses the clocks art of the pwrseq currently because of the delay needed.

Quoted 2 lines

Also, I am interested to know more about the waiting period you need. I assume that's because of the HW's characteristic?

Quoted 8 lines

At least TI wl12xx and Marvell 8787 need a delay after enabling the the WLAN.

Quoted 2 lines

Why can't we have that being described in DT and then make pwrseq_simple *wait* if needed?

We can, but I'm thinking that we might be better off adding support for regulators to pwrseq. Both TI wl12xx and Marvell 8787 get power from the battery, and probably have an integrated regulator.

Sounds very reasonable! Perhaps some of the delays can be handled within the context of the regulator then!?

Quoted 4 lines

Also, the delay and the power up sequencey can be more complicated than what we currently support. In the 8787 case, pdn pin needs to be asserted for 300ms after power pins are stable and while reset is held high.

I am for sure open to extend pwrseq_simple, please go ahead!

The initial version provided a proof of concept and the infrastructure. I expect and want people to extend it to suit their HWs.

If we at some point find that pwrseq_simple starts to become too complex, we may add another pwrseq type with a corresponding new compatible string.

[...]

Kind regards
Uffe

#5 lore raw

PATCH 1/1 mmc: pwrseq_simple: Fix regression with optional GPIOs

Quoted 24 lines · Ulf Hansson
Quoted 23 lines · Tony Lindgren
Quoted 10 lines · Ulf Hansson

+Linus

Quoted 5 lines · Tony Lindgren

Commit ce037275861e ("mmc: pwrseq_simple: use GPIO descriptors array API") changed the handling MMC power sequence so GPIOs no longer are optional.

This broke SDIO WLAN at least for omap5 that can't yet use the reset GPIOs with pwrseq_simple as a wait is needed after enabling the SDIO device.

Can you elaborate on this. Did it break omap5 or not? :-)

Yes it broke WLAN for omap5 that I just got fixed.. It only uses the clocks art of the pwrseq currently because of the delay needed.

Quoted 2 lines

Also, I am interested to know more about the waiting period you need. I assume that's because of the HW's characteristic?

At least TI wl12xx and Marvell 8787 need a delay after enabling the the WLAN.

Quoted 2 lines

Why can't we have that being described in DT and then make pwrseq_simple *wait* if needed?

Quoted 6 lines
Quoted 3 lines

We can, but I'm thinking that we might be better off adding support for regulators to pwrseq. Both TI wl12xx and Marvell 8787 get power from the battery, and probably have an integrated regulator.

Sounds very reasonable! Perhaps some of the delays can be handled within the context of the regulator then!?

Yes that's in the regulator binding. As long as the pwrseq code can sleep there's no problem with that.

Quoted 6 lines
Quoted 3 lines

Also, the delay and the power up sequencey can be more complicated than what we currently support. In the 8787 case, pdn pin needs to be asserted for 300ms after power pins are stable and while reset is held high.

I am for sure open to extend pwrseq_simple, please go ahead!

Quoted 7 lines

The initial version provided a proof of concept and the infrastructure. I expect and want people to extend it to suit their HWs.

If we at some point find that pwrseq_simple starts to become too complex, we may add another pwrseq type with a corresponding new compatible string.

Yeah OK I'll take a look when I get a chance.

Regards,

Tony

#6 lore raw

PATCH 1/1 mmc: pwrseq_simple: Fix regression with optional GPIOs

In reply to Ulf Hansson
Quoted 10 lines · Ulf Hansson

+Linus

Quoted 5 lines · Tony Lindgren

Commit ce037275861e ("mmc: pwrseq_simple: use GPIO descriptors array API") changed the handling MMC power sequence so GPIOs no longer are optional.

This broke SDIO WLAN at least for omap5 that can't yet use the reset GPIOs with pwrseq_simple as a wait is needed after enabling the SDIO device.

Can you elaborate on this. Did it break omap5 or not? :-)

Ulf, is this patch queued for v4.4 as a regression fix? I don't see it in Linux next or mainline trees?

Regards,

Tony

#7 lore raw

PATCH 1/1 mmc: pwrseq_simple: Fix regression with optional GPIOs

Quoted 7 lines · Tony Lindgren
Quoted 6 lines · Ulf Hansson

+Linus

Quoted 3 lines · Tony Lindgren

Commit ce037275861e ("mmc: pwrseq_simple: use GPIO descriptors array API") changed the handling MMC power sequence so GPIOs no longer are optional.

Quoted 7 lines
Quoted 4 lines
Quoted 2 lines

This broke SDIO WLAN at least for omap5 that can't yet use the reset GPIOs with pwrseq_simple as a wait is needed after enabling the SDIO device.

Can you elaborate on this. Did it break omap5 or not? :-)

Ulf, is this patch queued for v4.4 as a regression fix? I don't see it in Linux next or mainline trees?

Ohh, I guess there where some misunderstanding. I made a bunch of comments on your patch as well, so I have been expecting a new version.

Sorry if that was unclear!

Kind regards
Uffe

#8 lore raw

PATCH 1/1 mmc: pwrseq_simple: Fix regression with optional GPIOs

Quoted 11 lines · Ulf Hansson
Quoted 10 lines · Tony Lindgren
Quoted 9 lines · Ulf Hansson

+Linus

Quoted 5 lines · Tony Lindgren

Commit ce037275861e ("mmc: pwrseq_simple: use GPIO descriptors array API") changed the handling MMC power sequence so GPIOs no longer are optional.

This broke SDIO WLAN at least for omap5 that can't yet use the reset GPIOs with pwrseq_simple as a wait is needed after enabling the SDIO device.

Quoted 8 lines
Quoted 4 lines
Quoted 1 line

Can you elaborate on this. Did it break omap5 or not? :-)

Ulf, is this patch queued for v4.4 as a regression fix? I don't see it in Linux next or mainline trees?

Ohh, I guess there where some misunderstanding. I made a bunch of comments on your patch as well, so I have been expecting a new version.

Well this $subject patch was intended as a regression fix for v4.4-rc cycle. All the other things discussed are not fixes but new features instead.

Quoted 1 line

Sorry if that was unclear!

I think this patch should be still fine as is, care to take a look again?

Regards,

Tony

#9 lore raw

PATCH 1/1 mmc: pwrseq_simple: Fix regression with optional GPIOs

Quoted 21 lines · Tony Lindgren
Quoted 11 lines · Ulf Hansson
Quoted 10 lines · Tony Lindgren
Quoted 9 lines · Ulf Hansson

+Linus

Quoted 5 lines · Tony Lindgren

Commit ce037275861e ("mmc: pwrseq_simple: use GPIO descriptors array API") changed the handling MMC power sequence so GPIOs no longer are optional.

This broke SDIO WLAN at least for omap5 that can't yet use the reset GPIOs with pwrseq_simple as a wait is needed after enabling the SDIO device.

Quoted 8 lines
Quoted 4 lines
Quoted 1 line

Can you elaborate on this. Did it break omap5 or not? :-)

Ulf, is this patch queued for v4.4 as a regression fix? I don't see it in Linux next or mainline trees?

Ohh, I guess there where some misunderstanding. I made a bunch of comments on your patch as well, so I have been expecting a new version.

Quoted 6 lines

Well this $subject patch was intended as a regression fix for v4.4-rc cycle. All the other things discussed are not fixes but new features instead.

Quoted 1 line

Sorry if that was unclear!

I think this patch should be still fine as is, care to take a look again?

No, the patch have issues that needs to be fixed.
http://www.spinics.net/lists/linux-mmc/msg34399.html

Kind regards
Uffe

#10 lore raw

PATCH 1/1 mmc: pwrseq_simple: Fix regression with optional GPIOs

Quoted 25 lines · Ulf Hansson
Quoted 24 lines · Tony Lindgren
Quoted 11 lines · Ulf Hansson
Quoted 10 lines · Tony Lindgren
Quoted 9 lines · Ulf Hansson

+Linus

Quoted 5 lines · Tony Lindgren

Commit ce037275861e ("mmc: pwrseq_simple: use GPIO descriptors array API") changed the handling MMC power sequence so GPIOs no longer are optional.

This broke SDIO WLAN at least for omap5 that can't yet use the reset GPIOs with pwrseq_simple as a wait is needed after enabling the SDIO device.

Quoted 8 lines
Quoted 4 lines
Quoted 1 line

Can you elaborate on this. Did it break omap5 or not? :-)

Ulf, is this patch queued for v4.4 as a regression fix? I don't see it in Linux next or mainline trees?

Ohh, I guess there where some misunderstanding. I made a bunch of comments on your patch as well, so I have been expecting a new version.

Well this $subject patch was intended as a regression fix for v4.4-rc cycle. All the other things discussed are not fixes but new features instead.

Quoted 6 lines
Quoted 3 lines
Quoted 1 line

Sorry if that was unclear!

I think this patch should be still fine as is, care to take a look again?

No, the patch have issues that needs to be fixed.
http://www.spinics.net/lists/linux-mmc/msg34399.html

Oh sorry, somehow I did not notice those comments earlier, will take a look.

Tony