diff options
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/core/sdio.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 62df8e177585..48c465a8e34e 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c | |||
@@ -138,6 +138,32 @@ out: | |||
138 | return ret; | 138 | return ret; |
139 | } | 139 | } |
140 | 140 | ||
141 | static int sdio_enable_wide(struct mmc_card *card) | ||
142 | { | ||
143 | int ret; | ||
144 | u8 ctrl; | ||
145 | |||
146 | if (!(card->host->caps & MMC_CAP_4_BIT_DATA)) | ||
147 | return 0; | ||
148 | |||
149 | if (card->cccr.low_speed && !card->cccr.wide_bus) | ||
150 | return 0; | ||
151 | |||
152 | ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl); | ||
153 | if (ret) | ||
154 | return ret; | ||
155 | |||
156 | ctrl |= SDIO_BUS_WIDTH_4BIT; | ||
157 | |||
158 | ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL); | ||
159 | if (ret) | ||
160 | return ret; | ||
161 | |||
162 | mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); | ||
163 | |||
164 | return 0; | ||
165 | } | ||
166 | |||
141 | /* | 167 | /* |
142 | * Host is being removed. Free up the current card. | 168 | * Host is being removed. Free up the current card. |
143 | */ | 169 | */ |
@@ -300,6 +326,13 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) | |||
300 | mmc_set_clock(host, card->cis.max_dtr); | 326 | mmc_set_clock(host, card->cis.max_dtr); |
301 | 327 | ||
302 | /* | 328 | /* |
329 | * Switch to wider bus (if supported). | ||
330 | */ | ||
331 | err = sdio_enable_wide(card); | ||
332 | if (err) | ||
333 | goto remove; | ||
334 | |||
335 | /* | ||
303 | * Initialize (but don't add) all present functions. | 336 | * Initialize (but don't add) all present functions. |
304 | */ | 337 | */ |
305 | for (i = 0;i < funcs;i++) { | 338 | for (i = 0;i < funcs;i++) { |