Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 166126
b: refs/heads/master
c: 34e84f3
h: refs/heads/master
v: v3
  • Loading branch information
Linus Walleij authored and Russell King committed Sep 22, 2009
1 parent 093c280 commit 0f7108b
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6ef297f86b62f187c59475784208f75c2ed8ccd8
refs/heads/master: 34e84f39a27d059a3e6ec6e8b94aafa702e6f220
50 changes: 46 additions & 4 deletions trunk/drivers/mmc/host/mmci.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <linux/scatterlist.h>
#include <linux/gpio.h>
#include <linux/amba/mmci.h>
#include <linux/regulator/consumer.h>

#include <asm/cacheflush.h>
#include <asm/div64.h>
Expand Down Expand Up @@ -452,13 +453,28 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
u32 pwr = 0;
unsigned long flags;

if (host->plat->translate_vdd)
pwr |= host->plat->translate_vdd(mmc_dev(mmc), ios->vdd);

switch (ios->power_mode) {
case MMC_POWER_OFF:
if(host->vcc &&
regulator_is_enabled(host->vcc))
regulator_disable(host->vcc);
break;
case MMC_POWER_UP:
#ifdef CONFIG_REGULATOR
if (host->vcc)
/* This implicitly enables the regulator */
mmc_regulator_set_ocr(host->vcc, ios->vdd);
#endif
/*
* The translate_vdd function is not used if you have
* an external regulator, or your design is really weird.
* Using it would mean sending in power control BOTH using
* a regulator AND the 4 MMCIPWR bits. If we don't have
* a regulator, we might have some other platform specific
* power control behind this translate function.
*/
if (!host->vcc && host->plat->translate_vdd)
pwr |= host->plat->translate_vdd(mmc_dev(mmc), ios->vdd);
/* The ST version does not have this, fall through to POWER_ON */
if (host->hw_designer != AMBA_VENDOR_ST) {
pwr |= MCI_PWR_UP;
Expand Down Expand Up @@ -603,7 +619,29 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
mmc->ops = &mmci_ops;
mmc->f_min = (host->mclk + 511) / 512;
mmc->f_max = min(host->mclk, fmax);
mmc->ocr_avail = plat->ocr_mask;
#ifdef CONFIG_REGULATOR
/* If we're using the regulator framework, try to fetch a regulator */
host->vcc = regulator_get(&dev->dev, "vmmc");
if (IS_ERR(host->vcc))
host->vcc = NULL;
else {
int mask = mmc_regulator_get_ocrmask(host->vcc);

if (mask < 0)
dev_err(&dev->dev, "error getting OCR mask (%d)\n",
mask);
else {
host->mmc->ocr_avail = (u32) mask;
if (plat->ocr_mask)
dev_warn(&dev->dev,
"Provided ocr_mask/setpower will not be used "
"(using regulator instead)\n");
}
}
#endif
/* Fall back to platform data if no regulator is found */
if (host->vcc == NULL)
mmc->ocr_avail = plat->ocr_mask;
mmc->caps = plat->capabilities;

/*
Expand Down Expand Up @@ -741,6 +779,10 @@ static int __devexit mmci_remove(struct amba_device *dev)
clk_disable(host->clk);
clk_put(host->clk);

if (regulator_is_enabled(host->vcc))
regulator_disable(host->vcc);
regulator_put(host->vcc);

mmc_free_host(mmc);

amba_release_regions(dev);
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/mmc/host/mmci.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ struct mmci_host {
struct scatterlist *sg_ptr;
unsigned int sg_off;
unsigned int size;
struct regulator *vcc;
};

static inline void mmci_init_sg(struct mmci_host *host, struct mmc_data *data)
Expand Down

0 comments on commit 0f7108b

Please sign in to comment.