diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-14 13:46:57 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-14 13:46:57 -0700 |
commit | 2625b10d8c37656cf410a464ed95942b3abbd1f6 (patch) | |
tree | f02fc44aaed07dceed2566b3fdf4dc64b786cb89 /drivers/mmc/host/pxamci.c | |
parent | 489f7ab6c18cdd64a2d444e056d60a0e722f4ad7 (diff) | |
parent | 7f72134c32eb64c77d1fb35123ba8bf815bf797c (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc: (25 commits)
atmel-mci: add MCI2 register definitions
atmel-mci: Integrate AT91 specific definition in header file
tmio_mmc: allow compilation for ASIC3
mmc_block: do not DMA to stack
sdhci: Print ADMA status and pointer on debug
tmio_mmc: fix clock setup
tmio_mmc: map SD control registers after enabling the MFD cell
tmio_mmc: correct probe return value for num_resources != 3
tmio_mmc: don't use set_irq_type
tmio_mmc: add bus_shift support
MFD,mmc: tmio_mmc: make HCLK configurable
mmc_spi: don't use EINVAL for possible transmission errors
cb710: more cleanup for the DEBUG case.
sdhci: platform driver for SDHCI
mxcmmc: remove frequency workaround
cb710: handle DEBUG define in Makefile
cb710: add missing parenthesis
cb710: fix printk format string
mmc: Driver for CB710/720 memory card reader (MMC part)
pxamci: add regulator support.
...
Diffstat (limited to 'drivers/mmc/host/pxamci.c')
-rw-r--r-- | drivers/mmc/host/pxamci.c | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index 430095725f9..d7d7109ef47 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c @@ -27,6 +27,7 @@ #include <linux/err.h> #include <linux/mmc/host.h> #include <linux/io.h> +#include <linux/regulator/consumer.h> #include <asm/sizes.h> @@ -67,8 +68,42 @@ struct pxamci_host { unsigned int dma_dir; unsigned int dma_drcmrrx; unsigned int dma_drcmrtx; + + struct regulator *vcc; }; +static inline void pxamci_init_ocr(struct pxamci_host *host) +{ +#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 */ + host->mmc->ocr_avail = host->pdata ? + host->pdata->ocr_mask : + MMC_VDD_32_33 | MMC_VDD_33_34; + } +} + +static inline void pxamci_set_power(struct pxamci_host *host, unsigned int vdd) +{ +#ifdef CONFIG_REGULATOR + if (host->vcc) + mmc_regulator_set_ocr(host->vcc, vdd); +#endif + if (!host->vcc && host->pdata && host->pdata->setpower) + host->pdata->setpower(mmc_dev(host->mmc), vdd); +} + static void pxamci_stop_clock(struct pxamci_host *host) { if (readl(host->base + MMC_STAT) & STAT_CLK_EN) { @@ -438,8 +473,7 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (host->power_mode != ios->power_mode) { host->power_mode = ios->power_mode; - if (host->pdata && host->pdata->setpower) - host->pdata->setpower(mmc_dev(mmc), ios->vdd); + pxamci_set_power(host, ios->vdd); if (ios->power_mode == MMC_POWER_ON) host->cmdat |= CMDAT_INIT; @@ -562,9 +596,8 @@ static int pxamci_probe(struct platform_device *pdev) mmc->f_max = (cpu_is_pxa300() || cpu_is_pxa310()) ? 26000000 : host->clkrate; - mmc->ocr_avail = host->pdata ? - host->pdata->ocr_mask : - MMC_VDD_32_33|MMC_VDD_33_34; + pxamci_init_ocr(host); + mmc->caps = 0; host->cmdat = 0; if (!cpu_is_pxa25x()) { @@ -661,6 +694,9 @@ static int pxamci_remove(struct platform_device *pdev) if (mmc) { struct pxamci_host *host = mmc_priv(mmc); + if (host->vcc) + regulator_put(host->vcc); + if (host->pdata && host->pdata->exit) host->pdata->exit(&pdev->dev, mmc); |