linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] mmc: mxs-mmc: Introduce regulator support
@ 2019-01-28 10:20 Martin Kepplinger
  2019-01-28 10:27 ` Robin van der Gracht
  2019-01-28 11:33 ` Ulf Hansson
  0 siblings, 2 replies; 3+ messages in thread
From: Martin Kepplinger @ 2019-01-28 10:20 UTC (permalink / raw)
  To: linux-mmc, linux-arm-kernel, robin, ulf.hansson
  Cc: s.hauer, Martin Kepplinger, linux-kernel, linux-imx, kernel, shawnguo

From: Martin Kepplinger <martin.kepplinger@ginzinger.com>

This adds support for explicitly switching the mmc's power on and off
which is needed for example for WL1837 wifi controllers. ip link set wlan0 down
doesn't turn off the VMMC regulator which leads to hangs when loading firmware.

Tested on i.MX28.

Signed-off-by: Martin Kepplinger <martin.kepplinger@ginzinger.com>
---

again, this isn't new. it's (rebased and simplified)
https://patchwork.kernel.org/patch/4365751/

Thanks Robin for your input!

revision history
----------------
v1: was just a question why this hasn't gone in earlier.


 drivers/mmc/host/mxs-mmc.c | 31 +++++++++++++++++++++++--------
 1 file changed, 23 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
index add1e70195ea..fdaca0fcec99 100644
--- a/drivers/mmc/host/mxs-mmc.c
+++ b/drivers/mmc/host/mxs-mmc.c
@@ -66,11 +66,13 @@ struct mxs_mmc_host {
 	struct mmc_request		*mrq;
 	struct mmc_command		*cmd;
 	struct mmc_data			*data;
+	struct regulator		*vmmc;
 
 	unsigned char			bus_width;
 	spinlock_t			lock;
 	int				sdio_irq_en;
 	bool				broken_cd;
+	unsigned char			power_mode;
 };
 
 static int mxs_mmc_get_cd(struct mmc_host *mmc)
@@ -517,6 +519,24 @@ static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	else
 		host->bus_width = 0;
 
+	if (host->vmmc && ios->power_mode != host->power_mode) {
+		switch (ios->power_mode) {
+		case MMC_POWER_OFF:
+			if (regulator_disable(host->vmmc))
+				dev_err(mmc_dev(host->mmc),
+					"Failed to disable vmmc regulator\n");
+			break;
+		case MMC_POWER_UP:
+			if (regulator_enable(host->vmmc))
+				dev_err(mmc_dev(host->mmc),
+					"Failed to enable vmmc regulator\n");
+			break;
+		default:
+			break;
+		}
+		host->power_mode = ios->power_mode;
+	}
+
 	if (ios->clock)
 		mxs_ssp_set_clk_rate(&host->ssp, ios->clock);
 }
@@ -613,16 +633,11 @@ static int mxs_mmc_probe(struct platform_device *pdev)
 
 	host->mmc = mmc;
 	host->sdio_irq_en = 0;
+	host->power_mode = MMC_POWER_OFF;
 
 	reg_vmmc = devm_regulator_get(&pdev->dev, "vmmc");
-	if (!IS_ERR(reg_vmmc)) {
-		ret = regulator_enable(reg_vmmc);
-		if (ret) {
-			dev_err(&pdev->dev,
-				"Failed to enable vmmc regulator: %d\n", ret);
-			goto out_mmc_free;
-		}
-	}
+	if (!IS_ERR(reg_vmmc))
+		host->vmmc = reg_vmmc;
 
 	ssp->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(ssp->clk)) {
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] mmc: mxs-mmc: Introduce regulator support
  2019-01-28 10:20 [PATCH v2] mmc: mxs-mmc: Introduce regulator support Martin Kepplinger
@ 2019-01-28 10:27 ` Robin van der Gracht
  2019-01-28 11:33 ` Ulf Hansson
  1 sibling, 0 replies; 3+ messages in thread
From: Robin van der Gracht @ 2019-01-28 10:27 UTC (permalink / raw)
  To: Martin Kepplinger
  Cc: ulf.hansson, s.hauer, Martin Kepplinger, linux-mmc, linux-kernel,
	linux-imx, kernel, shawnguo, linux-arm-kernel

Hi Martin,

On Mon, 28 Jan 2019 11:20:22 +0100
Martin Kepplinger <martink@posteo.de> wrote:

> From: Martin Kepplinger <martin.kepplinger@ginzinger.com>
> 
> This adds support for explicitly switching the mmc's power on and off
> which is needed for example for WL1837 wifi controllers. ip link set wlan0 down
> doesn't turn off the VMMC regulator which leads to hangs when loading firmware.
> 
> Tested on i.MX28.
> 
> Signed-off-by: Martin Kepplinger <martin.kepplinger@ginzinger.com>
> ---
> 
> again, this isn't new. it's (rebased and simplified)
> https://patchwork.kernel.org/patch/4365751/
> 
> Thanks Robin for your input!
> 
> revision history
> ----------------
> v1: was just a question why this hasn't gone in earlier.

Not sure why it never made it. I created it for use with a wl1271 which
wan't properly reset in case of a fault. Also combined with imx28.

Regards,
Robin van der Gracht

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] mmc: mxs-mmc: Introduce regulator support
  2019-01-28 10:20 [PATCH v2] mmc: mxs-mmc: Introduce regulator support Martin Kepplinger
  2019-01-28 10:27 ` Robin van der Gracht
@ 2019-01-28 11:33 ` Ulf Hansson
  1 sibling, 0 replies; 3+ messages in thread
From: Ulf Hansson @ 2019-01-28 11:33 UTC (permalink / raw)
  To: Martin Kepplinger
  Cc: Robin van der Gracht, Sascha Hauer, Martin Kepplinger, linux-mmc,
	Linux Kernel Mailing List, dl-linux-imx, Sascha Hauer, Shawn Guo,
	Linux ARM

On Mon, 28 Jan 2019 at 11:20, Martin Kepplinger <martink@posteo.de> wrote:
>
> From: Martin Kepplinger <martin.kepplinger@ginzinger.com>
>
> This adds support for explicitly switching the mmc's power on and off
> which is needed for example for WL1837 wifi controllers. ip link set wlan0 down
> doesn't turn off the VMMC regulator which leads to hangs when loading firmware.

Isn't there a GPIO that needs to be toggled and separate clk for the
WiFi chip that needs to be enabled as well?

>
> Tested on i.MX28.
>
> Signed-off-by: Martin Kepplinger <martin.kepplinger@ginzinger.com>
> ---
>
> again, this isn't new. it's (rebased and simplified)
> https://patchwork.kernel.org/patch/4365751/
>
> Thanks Robin for your input!
>
> revision history
> ----------------
> v1: was just a question why this hasn't gone in earlier.
>
>
>  drivers/mmc/host/mxs-mmc.c | 31 +++++++++++++++++++++++--------
>  1 file changed, 23 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
> index add1e70195ea..fdaca0fcec99 100644
> --- a/drivers/mmc/host/mxs-mmc.c
> +++ b/drivers/mmc/host/mxs-mmc.c
> @@ -66,11 +66,13 @@ struct mxs_mmc_host {
>         struct mmc_request              *mrq;
>         struct mmc_command              *cmd;
>         struct mmc_data                 *data;
> +       struct regulator                *vmmc;

You don't need this here as this is already part of the generic struct
mmc_host (via the struct mmc_supply).

>
>         unsigned char                   bus_width;
>         spinlock_t                      lock;
>         int                             sdio_irq_en;
>         bool                            broken_cd;
> +       unsigned char                   power_mode;

Ditto.

>  };
>
>  static int mxs_mmc_get_cd(struct mmc_host *mmc)
> @@ -517,6 +519,24 @@ static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>         else
>                 host->bus_width = 0;
>
> +       if (host->vmmc && ios->power_mode != host->power_mode) {
> +               switch (ios->power_mode) {
> +               case MMC_POWER_OFF:
> +                       if (regulator_disable(host->vmmc))
> +                               dev_err(mmc_dev(host->mmc),
> +                                       "Failed to disable vmmc regulator\n");

You should use mmc_regulator_set_ocr() instead.

> +                       break;
> +               case MMC_POWER_UP:
> +                       if (regulator_enable(host->vmmc))

Ditto.

> +                               dev_err(mmc_dev(host->mmc),
> +                                       "Failed to enable vmmc regulator\n");
> +                       break;
> +               default:
> +                       break;
> +               }
> +               host->power_mode = ios->power_mode;
> +       }
> +
>         if (ios->clock)
>                 mxs_ssp_set_clk_rate(&host->ssp, ios->clock);
>  }
> @@ -613,16 +633,11 @@ static int mxs_mmc_probe(struct platform_device *pdev)
>
>         host->mmc = mmc;
>         host->sdio_irq_en = 0;
> +       host->power_mode = MMC_POWER_OFF;

This isn't needed. The state is already controlled by the mmc core.

>
>         reg_vmmc = devm_regulator_get(&pdev->dev, "vmmc");

You should use mmc_regulator_get_supply() instead.

> -       if (!IS_ERR(reg_vmmc)) {
> -               ret = regulator_enable(reg_vmmc);
> -               if (ret) {
> -                       dev_err(&pdev->dev,
> -                               "Failed to enable vmmc regulator: %d\n", ret);
> -                       goto out_mmc_free;
> -               }
> -       }
> +       if (!IS_ERR(reg_vmmc))
> +               host->vmmc = reg_vmmc;
>
>         ssp->clk = devm_clk_get(&pdev->dev, NULL);
>         if (IS_ERR(ssp->clk)) {
> --
> 2.20.1
>

Kind regards
Uffe

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-01-28 11:34 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-28 10:20 [PATCH v2] mmc: mxs-mmc: Introduce regulator support Martin Kepplinger
2019-01-28 10:27 ` Robin van der Gracht
2019-01-28 11:33 ` Ulf Hansson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).