Message ID | 1314253575-2602-2-git-send-email-zhangfei.gao@marvell.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Zhangfei, My understanding is that the card in the slot would be either MMC _or_ SDIO and why do we need another regulator for the power on/off? On Thu, Aug 25, 2011 at 2:26 PM, Zhangfei Gao <zhangfei.gao@marvell.com> wrote: > sdio client may be required power on/off dynamically. > With regulator vsdio, sdio client power on/off could be executed by mmc_power_up/down > > CC: Ohad Ben-Cohen <ohad@wizery.com> > Signed-off-by: Zhangfei Gao <zhangfei.gao@marvell.com> > --- > drivers/mmc/host/sdhci.c | 22 , > include/linux/mmc/sdhci.h | 2 ++ > 2 files changed, 24 insertions(+), 0 deletions(-) > > diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c > index 0e02cc1..e0ef7d3 100644 > --- a/drivers/mmc/host/sdhci.c > +++ b/drivers/mmc/host/sdhci.c > @@ -1424,6 +1424,18 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) > out: > mmiowb(); > spin_unlock_irqrestore(&host->lock, flags); > + > + if (host->vsdio) { > + if (ios->power_mode != host->power_mode_old) { > + if (ios->power_mode == MMC_POWER_OFF) > + regulator_disable(host->vsdio); > + > + if (ios->power_mode == MMC_POWER_UP) > + regulator_enable(host->vsdio); > + } > + > + host->power_mode_old = ios->power_mode; > + } > } > > static int check_ro(struct sdhci_host *host) > @@ -2748,6 +2760,13 @@ int sdhci_add_host(struct sdhci_host *host) > regulator_enable(host->vmmc); > } > > + host->vsdio = regulator_get(mmc_dev(mmc), "vsdio"); > + if (IS_ERR(host->vsdio)) > + host->vsdio = NULL; > + else > + printk(KERN_INFO "%s: vsdio regulator found\n", > + mmc_hostname(mmc)); > + > sdhci_init(host, 0); > > #ifdef CONFIG_MMC_DEBUG > @@ -2839,6 +2858,9 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) > regulator_put(host->vmmc); > } > > + if (host->vsdio) > + regulator_put(host->vsdio); > + > kfree(host->adma_desc); > kfree(host->align_buffer); > > diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h > index 5666f3a..201207a 100644 > --- a/include/linux/mmc/sdhci.h > +++ b/include/linux/mmc/sdhci.h > @@ -94,6 +94,8 @@ struct sdhci_host { > const struct sdhci_ops *ops; /* Low level hw interface */ > > struct regulator *vmmc; /* Power regulator */ > + struct regulator *vsdio; /* sdio Power regulator */ > + unsigned char power_mode_old; /* power supply mode */ > > /* Internal data */ > struct mmc_host *mmc; /* MMC structure */ > -- > 1.7.0.4 > >
On Wed, Aug 31, 2011 at 10:06 PM, Eric Miao <eric.y.miao@gmail.com> wrote: > Zhangfei, > > My understanding is that the card in the slot would be either MMC _or_ > SDIO and why do we need another regulator for the power on/off? > Hi, Eric vsdio is used for dynamically power control to sdio, for example application dynamically disable/enable wifi. Then mmc_start/stop_host and mmc_power_up/down could directly power on/off sdio via mmc_set_ios. This also workable with runtime PM, which already introduced into mmc by Ohad. vmmc is used to statically provided power to sd or vmmc. Daniel once suggested reusing vmmc, however we found CD pin requires vmmc to be alwayes on. If vmmc is dynamically power off, CD pin will be low, which indicating card is inserted by mistake. For example when no card inserted, CD pin will high -> host fail to detect sd card -> vmmc disabled in set_ios -> host thought card inserted -> irq happen -> host redetect card -> If there is concern of vsdio in sdhci.c, how about moving vsdio to specific driver via call back. Thanks
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 0e02cc1..e0ef7d3 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1424,6 +1424,18 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) out: mmiowb(); spin_unlock_irqrestore(&host->lock, flags); + + if (host->vsdio) { + if (ios->power_mode != host->power_mode_old) { + if (ios->power_mode == MMC_POWER_OFF) + regulator_disable(host->vsdio); + + if (ios->power_mode == MMC_POWER_UP) + regulator_enable(host->vsdio); + } + + host->power_mode_old = ios->power_mode; + } } static int check_ro(struct sdhci_host *host) @@ -2748,6 +2760,13 @@ int sdhci_add_host(struct sdhci_host *host) regulator_enable(host->vmmc); } + host->vsdio = regulator_get(mmc_dev(mmc), "vsdio"); + if (IS_ERR(host->vsdio)) + host->vsdio = NULL; + else + printk(KERN_INFO "%s: vsdio regulator found\n", + mmc_hostname(mmc)); + sdhci_init(host, 0); #ifdef CONFIG_MMC_DEBUG @@ -2839,6 +2858,9 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) regulator_put(host->vmmc); } + if (host->vsdio) + regulator_put(host->vsdio); + kfree(host->adma_desc); kfree(host->align_buffer); diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index 5666f3a..201207a 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h @@ -94,6 +94,8 @@ struct sdhci_host { const struct sdhci_ops *ops; /* Low level hw interface */ struct regulator *vmmc; /* Power regulator */ + struct regulator *vsdio; /* sdio Power regulator */ + unsigned char power_mode_old; /* power supply mode */ /* Internal data */ struct mmc_host *mmc; /* MMC structure */
sdio client may be required power on/off dynamically. With regulator vsdio, sdio client power on/off could be executed by mmc_power_up/down CC: Ohad Ben-Cohen <ohad@wizery.com> Signed-off-by: Zhangfei Gao <zhangfei.gao@marvell.com> --- drivers/mmc/host/sdhci.c | 22 ++++++++++++++++++++++ include/linux/mmc/sdhci.h | 2 ++ 2 files changed, 24 insertions(+), 0 deletions(-)