Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+41 −5
Original line number Diff line number Diff line
@@ -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);