Skip to content

Commit ceb6143

Browse files
ahunter6cjb
authored andcommitted
mmc: sdhci: fix vmmc handling
Presently the vmmc regulator is enabled when the host controller is added and disabled when it is removed. However, the vmmc regulator should be under the control of the upper layers via ->set_ios(). Make it so. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Signed-off-by: Chris Ball <cjb@laptop.org>
1 parent 17e9ff5 commit ceb6143

File tree

1 file changed

+21
-22
lines changed

1 file changed

+21
-22
lines changed

drivers/mmc/host/sdhci.c

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,7 +1170,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
11701170
host->clock = clock;
11711171
}
11721172

1173-
static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
1173+
static int sdhci_set_power(struct sdhci_host *host, unsigned short power)
11741174
{
11751175
u8 pwr = 0;
11761176

@@ -1193,13 +1193,13 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
11931193
}
11941194

11951195
if (host->pwr == pwr)
1196-
return;
1196+
return -1;
11971197

11981198
host->pwr = pwr;
11991199

12001200
if (pwr == 0) {
12011201
sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
1202-
return;
1202+
return 0;
12031203
}
12041204

12051205
/*
@@ -1226,6 +1226,8 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
12261226
*/
12271227
if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER)
12281228
mdelay(10);
1229+
1230+
return power;
12291231
}
12301232

12311233
/*****************************************************************************\
@@ -1307,12 +1309,17 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
13071309
static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
13081310
{
13091311
unsigned long flags;
1312+
int vdd_bit = -1;
13101313
u8 ctrl;
13111314

13121315
spin_lock_irqsave(&host->lock, flags);
13131316

1314-
if (host->flags & SDHCI_DEVICE_DEAD)
1315-
goto out;
1317+
if (host->flags & SDHCI_DEVICE_DEAD) {
1318+
spin_unlock_irqrestore(&host->lock, flags);
1319+
if (host->vmmc && ios->power_mode == MMC_POWER_OFF)
1320+
mmc_regulator_set_ocr(host->mmc, host->vmmc, 0);
1321+
return;
1322+
}
13161323

13171324
/*
13181325
* Reset the chip on each power off.
@@ -1326,9 +1333,15 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
13261333
sdhci_set_clock(host, ios->clock);
13271334

13281335
if (ios->power_mode == MMC_POWER_OFF)
1329-
sdhci_set_power(host, -1);
1336+
vdd_bit = sdhci_set_power(host, -1);
13301337
else
1331-
sdhci_set_power(host, ios->vdd);
1338+
vdd_bit = sdhci_set_power(host, ios->vdd);
1339+
1340+
if (host->vmmc && vdd_bit != -1) {
1341+
spin_unlock_irqrestore(&host->lock, flags);
1342+
mmc_regulator_set_ocr(host->mmc, host->vmmc, vdd_bit);
1343+
spin_lock_irqsave(&host->lock, flags);
1344+
}
13321345

13331346
if (host->ops->platform_send_init_74_clocks)
13341347
host->ops->platform_send_init_74_clocks(host, ios->power_mode);
@@ -1453,7 +1466,6 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
14531466
if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS)
14541467
sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
14551468

1456-
out:
14571469
mmiowb();
14581470
spin_unlock_irqrestore(&host->lock, flags);
14591471
}
@@ -2357,9 +2369,6 @@ int sdhci_suspend_host(struct sdhci_host *host)
23572369

23582370
free_irq(host->irq, host);
23592371

2360-
if (host->vmmc)
2361-
ret = regulator_disable(host->vmmc);
2362-
23632372
return ret;
23642373
}
23652374

@@ -2369,12 +2378,6 @@ int sdhci_resume_host(struct sdhci_host *host)
23692378
{
23702379
int ret;
23712380

2372-
if (host->vmmc) {
2373-
int ret = regulator_enable(host->vmmc);
2374-
if (ret)
2375-
return ret;
2376-
}
2377-
23782381
if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
23792382
if (host->ops->enable_dma)
23802383
host->ops->enable_dma(host);
@@ -2936,8 +2939,6 @@ int sdhci_add_host(struct sdhci_host *host)
29362939
if (IS_ERR(host->vmmc)) {
29372940
pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc));
29382941
host->vmmc = NULL;
2939-
} else {
2940-
regulator_enable(host->vmmc);
29412942
}
29422943

29432944
sdhci_init(host, 0);
@@ -3026,10 +3027,8 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
30263027
tasklet_kill(&host->card_tasklet);
30273028
tasklet_kill(&host->finish_tasklet);
30283029

3029-
if (host->vmmc) {
3030-
regulator_disable(host->vmmc);
3030+
if (host->vmmc)
30313031
regulator_put(host->vmmc);
3032-
}
30333032

30343033
kfree(host->adma_desc);
30353034
kfree(host->align_buffer);

0 commit comments

Comments
 (0)