summaryrefslogtreecommitdiff
path: root/drivers/mmc/core/sdio.c
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2020-08-25 13:01:46 +0300
committerMark Brown <broonie@kernel.org>2020-08-25 13:01:46 +0300
commit3bec5b6aae830355e786e204b20a7cea38c3a8ed (patch)
treefd597b87faf55ceb2a207ee94f4feca6276696db /drivers/mmc/core/sdio.c
parenta577f3456c0a2fac3dee037c483753e6e68f3e49 (diff)
parentd012a7190fc1fd72ed48911e77ca97ba4521bccd (diff)
downloadlinux-3bec5b6aae830355e786e204b20a7cea38c3a8ed.tar.xz
Merge tag 'v5.9-rc2' into regulator-5.9
Linux 5.9-rc2
Diffstat (limited to 'drivers/mmc/core/sdio.c')
-rw-r--r--drivers/mmc/core/sdio.c64
1 files changed, 42 insertions, 22 deletions
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index b65b26f76d71..7b40553d3934 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -176,15 +176,18 @@ static int sdio_read_cccr(struct mmc_card *card, u32 ocr)
if (mmc_host_uhs(card->host)) {
if (data & SDIO_UHS_DDR50)
card->sw_caps.sd3_bus_mode
- |= SD_MODE_UHS_DDR50;
+ |= SD_MODE_UHS_DDR50 | SD_MODE_UHS_SDR50
+ | SD_MODE_UHS_SDR25 | SD_MODE_UHS_SDR12;
if (data & SDIO_UHS_SDR50)
card->sw_caps.sd3_bus_mode
- |= SD_MODE_UHS_SDR50;
+ |= SD_MODE_UHS_SDR50 | SD_MODE_UHS_SDR25
+ | SD_MODE_UHS_SDR12;
if (data & SDIO_UHS_SDR104)
card->sw_caps.sd3_bus_mode
- |= SD_MODE_UHS_SDR104;
+ |= SD_MODE_UHS_SDR104 | SD_MODE_UHS_SDR50
+ | SD_MODE_UHS_SDR25 | SD_MODE_UHS_SDR12;
}
ret = mmc_io_rw_direct(card, 0, 0,
@@ -303,30 +306,49 @@ static int sdio_disable_wide(struct mmc_card *card)
return 0;
}
+static int sdio_disable_4bit_bus(struct mmc_card *card)
+{
+ int err;
+
+ if (card->type == MMC_TYPE_SDIO)
+ goto out;
+
+ if (!(card->host->caps & MMC_CAP_4_BIT_DATA))
+ return 0;
+
+ if (!(card->scr.bus_widths & SD_SCR_BUS_WIDTH_4))
+ return 0;
+
+ err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_1);
+ if (err)
+ return err;
+
+out:
+ return sdio_disable_wide(card);
+}
+
static int sdio_enable_4bit_bus(struct mmc_card *card)
{
int err;
+ err = sdio_enable_wide(card);
+ if (err <= 0)
+ return err;
if (card->type == MMC_TYPE_SDIO)
- err = sdio_enable_wide(card);
- else if ((card->host->caps & MMC_CAP_4_BIT_DATA) &&
- (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
+ goto out;
+
+ if (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4) {
err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
- if (err)
+ if (err) {
+ sdio_disable_wide(card);
return err;
- err = sdio_enable_wide(card);
- if (err <= 0)
- mmc_app_set_bus_width(card, MMC_BUS_WIDTH_1);
- } else
- return 0;
-
- if (err > 0) {
- mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
- err = 0;
+ }
}
+out:
+ mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
- return err;
+ return 0;
}
@@ -518,10 +540,8 @@ static int sdio_set_bus_speed_mode(struct mmc_card *card)
max_rate = min_not_zero(card->quirk_max_rate,
card->sw_caps.uhs_max_dtr);
- if (bus_speed) {
- mmc_set_timing(card->host, timing);
- mmc_set_clock(card->host, max_rate);
- }
+ mmc_set_timing(card->host, timing);
+ mmc_set_clock(card->host, max_rate);
return 0;
}
@@ -972,7 +992,7 @@ static int mmc_sdio_suspend(struct mmc_host *host)
mmc_claim_host(host);
if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host))
- sdio_disable_wide(host->card);
+ sdio_disable_4bit_bus(host->card);
if (!mmc_card_keep_power(host)) {
mmc_power_off(host);