diff options
Diffstat (limited to 'drivers/mmc/host/pxamci.c')
-rw-r--r-- | drivers/mmc/host/pxamci.c | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index b7dfcac31e8a..7257738fd7da 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c | |||
@@ -99,14 +99,25 @@ static inline void pxamci_init_ocr(struct pxamci_host *host) | |||
99 | } | 99 | } |
100 | } | 100 | } |
101 | 101 | ||
102 | static inline void pxamci_set_power(struct pxamci_host *host, unsigned int vdd) | 102 | static inline int pxamci_set_power(struct pxamci_host *host, |
103 | unsigned char power_mode, | ||
104 | unsigned int vdd) | ||
103 | { | 105 | { |
104 | int on; | 106 | int on; |
105 | 107 | ||
106 | #ifdef CONFIG_REGULATOR | 108 | if (host->vcc) { |
107 | if (host->vcc) | 109 | int ret; |
108 | mmc_regulator_set_ocr(host->vcc, vdd); | 110 | |
109 | #endif | 111 | if (power_mode == MMC_POWER_UP) { |
112 | ret = mmc_regulator_set_ocr(host->mmc, host->vcc, vdd); | ||
113 | if (ret) | ||
114 | return ret; | ||
115 | } else if (power_mode == MMC_POWER_OFF) { | ||
116 | ret = mmc_regulator_set_ocr(host->mmc, host->vcc, 0); | ||
117 | if (ret) | ||
118 | return ret; | ||
119 | } | ||
120 | } | ||
110 | if (!host->vcc && host->pdata && | 121 | if (!host->vcc && host->pdata && |
111 | gpio_is_valid(host->pdata->gpio_power)) { | 122 | gpio_is_valid(host->pdata->gpio_power)) { |
112 | on = ((1 << vdd) & host->pdata->ocr_mask); | 123 | on = ((1 << vdd) & host->pdata->ocr_mask); |
@@ -115,6 +126,8 @@ static inline void pxamci_set_power(struct pxamci_host *host, unsigned int vdd) | |||
115 | } | 126 | } |
116 | if (!host->vcc && host->pdata && host->pdata->setpower) | 127 | if (!host->vcc && host->pdata && host->pdata->setpower) |
117 | host->pdata->setpower(mmc_dev(host->mmc), vdd); | 128 | host->pdata->setpower(mmc_dev(host->mmc), vdd); |
129 | |||
130 | return 0; | ||
118 | } | 131 | } |
119 | 132 | ||
120 | static void pxamci_stop_clock(struct pxamci_host *host) | 133 | static void pxamci_stop_clock(struct pxamci_host *host) |
@@ -490,9 +503,21 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
490 | } | 503 | } |
491 | 504 | ||
492 | if (host->power_mode != ios->power_mode) { | 505 | if (host->power_mode != ios->power_mode) { |
506 | int ret; | ||
507 | |||
493 | host->power_mode = ios->power_mode; | 508 | host->power_mode = ios->power_mode; |
494 | 509 | ||
495 | pxamci_set_power(host, ios->vdd); | 510 | ret = pxamci_set_power(host, ios->power_mode, ios->vdd); |
511 | if (ret) { | ||
512 | dev_err(mmc_dev(mmc), "unable to set power\n"); | ||
513 | /* | ||
514 | * The .set_ios() function in the mmc_host_ops | ||
515 | * struct return void, and failing to set the | ||
516 | * power should be rare so we print an error and | ||
517 | * return here. | ||
518 | */ | ||
519 | return; | ||
520 | } | ||
496 | 521 | ||
497 | if (ios->power_mode == MMC_POWER_ON) | 522 | if (ios->power_mode == MMC_POWER_ON) |
498 | host->cmdat |= CMDAT_INIT; | 523 | host->cmdat |= CMDAT_INIT; |
@@ -503,8 +528,8 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
503 | else | 528 | else |
504 | host->cmdat &= ~CMDAT_SD_4DAT; | 529 | host->cmdat &= ~CMDAT_SD_4DAT; |
505 | 530 | ||
506 | pr_debug("PXAMCI: clkrt = %x cmdat = %x\n", | 531 | dev_dbg(mmc_dev(mmc), "PXAMCI: clkrt = %x cmdat = %x\n", |
507 | host->clkrt, host->cmdat); | 532 | host->clkrt, host->cmdat); |
508 | } | 533 | } |
509 | 534 | ||
510 | static void pxamci_enable_sdio_irq(struct mmc_host *host, int enable) | 535 | static void pxamci_enable_sdio_irq(struct mmc_host *host, int enable) |