Commit 8385f9cb authored by Daniel Ribeiro's avatar Daniel Ribeiro Committed by Pierre Ossman

pxamci: add regulator support.

Changes pxamci.c to use the regulator subsystem. Uses the regulator case
CONFIG_REGULATOR is defined and a matching is regulator is provided, or
falls back to pdata->setpower otherwise. A warning is displayed case
both a valid regulator and pdata is set, and the regulator is used.
Signed-off-by: default avatarDaniel Ribeiro <drwyrm@gmail.com>
Acked-by: default avatarEric Miao <eric.miao@marvell.com>
Signed-off-by: default avatarPierre Ossman <pierre@ossman.eu>
parent 8dfd0374
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/mmc/host.h> #include <linux/mmc/host.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/regulator/consumer.h>
#include <asm/sizes.h> #include <asm/sizes.h>
...@@ -67,8 +68,42 @@ struct pxamci_host { ...@@ -67,8 +68,42 @@ struct pxamci_host {
unsigned int dma_dir; unsigned int dma_dir;
unsigned int dma_drcmrrx; unsigned int dma_drcmrrx;
unsigned int dma_drcmrtx; 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) static void pxamci_stop_clock(struct pxamci_host *host)
{ {
if (readl(host->base + MMC_STAT) & STAT_CLK_EN) { 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) ...@@ -438,8 +473,7 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
if (host->power_mode != ios->power_mode) { if (host->power_mode != ios->power_mode) {
host->power_mode = ios->power_mode; host->power_mode = ios->power_mode;
if (host->pdata && host->pdata->setpower) pxamci_set_power(host, ios->vdd);
host->pdata->setpower(mmc_dev(mmc), ios->vdd);
if (ios->power_mode == MMC_POWER_ON) if (ios->power_mode == MMC_POWER_ON)
host->cmdat |= CMDAT_INIT; host->cmdat |= CMDAT_INIT;
...@@ -562,9 +596,8 @@ static int pxamci_probe(struct platform_device *pdev) ...@@ -562,9 +596,8 @@ static int pxamci_probe(struct platform_device *pdev)
mmc->f_max = (cpu_is_pxa300() || cpu_is_pxa310()) ? 26000000 mmc->f_max = (cpu_is_pxa300() || cpu_is_pxa310()) ? 26000000
: host->clkrate; : host->clkrate;
mmc->ocr_avail = host->pdata ? pxamci_init_ocr(host);
host->pdata->ocr_mask :
MMC_VDD_32_33|MMC_VDD_33_34;
mmc->caps = 0; mmc->caps = 0;
host->cmdat = 0; host->cmdat = 0;
if (!cpu_is_pxa25x()) { if (!cpu_is_pxa25x()) {
...@@ -661,6 +694,9 @@ static int pxamci_remove(struct platform_device *pdev) ...@@ -661,6 +694,9 @@ static int pxamci_remove(struct platform_device *pdev)
if (mmc) { if (mmc) {
struct pxamci_host *host = mmc_priv(mmc); struct pxamci_host *host = mmc_priv(mmc);
if (host->vcc)
regulator_put(host->vcc);
if (host->pdata && host->pdata->exit) if (host->pdata && host->pdata->exit)
host->pdata->exit(&pdev->dev, mmc); host->pdata->exit(&pdev->dev, mmc);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment