Message ID | 1303388873-15467-5-git-send-email-ospite@studenti.unina.it (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Thu, Apr 21, 2011 at 02:27:53PM +0200, Antonio Ospite wrote: > +#ifdef CONFIG_REGULATOR > + host->vcc = regulator_get(mmc_dev(host->mmc), "vmmc"); > + > + if (IS_ERR(host->vcc)) { > + host->vcc = NULL; > + } else { > + host->mmc->ocr_avail = mmc_regulator_get_ocrmask(host->vcc); > + if (host->pdata && host->pdata->ocr_mask) > + dev_warn(mmc_dev(host->mmc), > + "ocr_mask/setpower will not be used\n"); > } > +#endif Why is this code conditional? The regulator API will stub itself out (by returning a null pointer, which plays well with your use of null) if it's disabled. I'm also not seeing any corresponding code to release the regulator. -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, 21 Apr 2011 13:40:41 +0100 Mark Brown <broonie@opensource.wolfsonmicro.com> wrote: > On Thu, Apr 21, 2011 at 02:27:53PM +0200, Antonio Ospite wrote: > > > +#ifdef CONFIG_REGULATOR > > + host->vcc = regulator_get(mmc_dev(host->mmc), "vmmc"); > > + > > + if (IS_ERR(host->vcc)) { > > + host->vcc = NULL; > > + } else { > > + host->mmc->ocr_avail = mmc_regulator_get_ocrmask(host->vcc); > > + if (host->pdata && host->pdata->ocr_mask) > > + dev_warn(mmc_dev(host->mmc), > > + "ocr_mask/setpower will not be used\n"); > > } > > +#endif > > Why is this code conditional? The regulator API will stub itself out > (by returning a null pointer, which plays well with your use of null) if > it's disabled. I'm also not seeing any corresponding code to release > the regulator. > Actually I saw this done conditionally in pxamci.c and thought it was really needed. About the call to regulator_put() if was there but got lost when squashing the commits into the final patch and I was still reading that part in my mind even if it was not there anymore. The importance of reviewers with fresh eyes. I'll resubmit this forth patch with the needed changes. Thanks, Antonio
Em Qui, 2011-04-21 às 14:49 +0200, Antonio Ospite escreveu: > On Thu, 21 Apr 2011 13:40:41 +0100 > Mark Brown <broonie@opensource.wolfsonmicro.com> wrote: > > > On Thu, Apr 21, 2011 at 02:27:53PM +0200, Antonio Ospite wrote: > > > > > +#ifdef CONFIG_REGULATOR > > > + host->vcc = regulator_get(mmc_dev(host->mmc), "vmmc"); > > > + > > > + if (IS_ERR(host->vcc)) { > > > + host->vcc = NULL; > > > + } else { > > > + host->mmc->ocr_avail = mmc_regulator_get_ocrmask(host->vcc); > > > + if (host->pdata && host->pdata->ocr_mask) > > > + dev_warn(mmc_dev(host->mmc), > > > + "ocr_mask/setpower will not be used\n"); > > > } > > > +#endif > > > > Why is this code conditional? The regulator API will stub itself out > > (by returning a null pointer, which plays well with your use of null) if > > it's disabled. I'm also not seeing any corresponding code to release > > the regulator. > > > > Actually I saw this done conditionally in pxamci.c and thought it was > really needed. About the call to regulator_put() if was there but got > lost when squashing the commits into the final patch and I was still > reading that part in my mind even if it was not there anymore. > The importance of reviewers with fresh eyes. > > I'll resubmit this forth patch with the needed changes. Hi, The #ifdefs on pxamci were needed because at the time it was written IS_ERR(regulator_get()) would return _false_ if CONFIG_REGULATOR is not defined, breaking compatibility with the older ocr_mask/setpower. I don't know if the regulator api changed it's old behaviour, see http://www.mail-archive.com/openezx-devel@lists.openezx.org/msg01954.html
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 0f3672d..acc2ec8 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c @@ -31,6 +31,7 @@ #include <linux/dma-mapping.h> #include <linux/crc7.h> #include <linux/crc-itu-t.h> +#include <linux/regulator/consumer.h> #include <linux/scatterlist.h> #include <linux/mmc/host.h> @@ -150,11 +151,13 @@ struct mmc_spi_host { */ void *ones; dma_addr_t ones_dma; + + struct regulator *vcc; }; static inline int mmc_spi_canpower(struct mmc_spi_host *host) { - return host->pdata && host->pdata->setpower; + return (host->pdata && host->pdata->setpower) || host->vcc; } /****************************************************************************/ @@ -1225,17 +1228,35 @@ static inline int mmc_spi_setpower(struct mmc_spi_host *host, unsigned char power_mode, unsigned int vdd) { + if (!mmc_spi_canpower(host)) + return -ENOSYS; + /* switch power on/off if possible, accounting for * max 250msec powerup time if needed. */ - if (mmc_spi_canpower(host)) { - switch (power_mode) { - case MMC_POWER_OFF: - case MMC_POWER_UP: + switch (power_mode) { + case MMC_POWER_OFF: + if (host->vcc) { + int ret = mmc_regulator_set_ocr(host->mmc, + host->vcc, 0); + if (ret) + return ret; + } else { + host->pdata->setpower(&host->spi->dev, vdd); + } + break; + + case MMC_POWER_UP: + if (host->vcc) { + int ret = mmc_regulator_set_ocr(host->mmc, + host->vcc, vdd); + if (ret) + return ret; + } else { host->pdata->setpower(&host->spi->dev, vdd); - if (power_mode == MMC_POWER_UP) - msleep(host->powerup_msecs); } + msleep(host->powerup_msecs); + break; } return 0; @@ -1420,12 +1441,28 @@ static int mmc_spi_probe(struct spi_device *spi) * and power switching gpios. */ host->pdata = mmc_spi_get_pdata(spi); - if (host->pdata) - mmc->ocr_avail = host->pdata->ocr_mask; - if (!mmc->ocr_avail) { - dev_warn(&spi->dev, "ASSUMING 3.2-3.4 V slot power\n"); - mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; +#ifdef CONFIG_REGULATOR + host->vcc = regulator_get(mmc_dev(host->mmc), "vmmc"); + + if (IS_ERR(host->vcc)) { + host->vcc = NULL; + } else { + host->mmc->ocr_avail = mmc_regulator_get_ocrmask(host->vcc); + if (host->pdata && host->pdata->ocr_mask) + dev_warn(mmc_dev(host->mmc), + "ocr_mask/setpower will not be used\n"); } +#endif + if (host->vcc == NULL) { + /* fall-back to platform data */ + if (host->pdata) + mmc->ocr_avail = host->pdata->ocr_mask; + if (!mmc->ocr_avail) { + dev_warn(&spi->dev, "ASSUMING 3.2-3.4 V slot power\n"); + mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; + } + } + if (mmc_spi_canpower(host)) { host->powerup_msecs = host->pdata->powerup_msecs; if (!host->powerup_msecs || host->powerup_msecs > 250)
Add support for powering up SD cards driven by regulators. This makes the mmc_spi driver work also with the Motorola A910 phone. Signed-off-by: Antonio Ospite <ospite@studenti.unina.it> --- drivers/mmc/host/mmc_spi.c | 61 +++++++++++++++++++++++++++++++++++-------- 1 files changed, 49 insertions(+), 12 deletions(-)