diff options
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/core/sdio.c | 285 |
1 files changed, 196 insertions, 89 deletions
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 2d24a123f0b0..f4c8637fd072 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c | |||
@@ -218,6 +218,134 @@ static int sdio_enable_hs(struct mmc_card *card) | |||
218 | } | 218 | } |
219 | 219 | ||
220 | /* | 220 | /* |
221 | * Handle the detection and initialisation of a card. | ||
222 | * | ||
223 | * In the case of a resume, "oldcard" will contain the card | ||
224 | * we're trying to reinitialise. | ||
225 | */ | ||
226 | static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, | ||
227 | struct mmc_card *oldcard) | ||
228 | { | ||
229 | struct mmc_card *card; | ||
230 | int err; | ||
231 | |||
232 | BUG_ON(!host); | ||
233 | WARN_ON(!host->claimed); | ||
234 | |||
235 | /* | ||
236 | * Inform the card of the voltage | ||
237 | */ | ||
238 | err = mmc_send_io_op_cond(host, host->ocr, &ocr); | ||
239 | if (err) | ||
240 | goto err; | ||
241 | |||
242 | /* | ||
243 | * For SPI, enable CRC as appropriate. | ||
244 | */ | ||
245 | if (mmc_host_is_spi(host)) { | ||
246 | err = mmc_spi_set_crc(host, use_spi_crc); | ||
247 | if (err) | ||
248 | goto err; | ||
249 | } | ||
250 | |||
251 | /* | ||
252 | * Allocate card structure. | ||
253 | */ | ||
254 | card = mmc_alloc_card(host, NULL); | ||
255 | if (IS_ERR(card)) { | ||
256 | err = PTR_ERR(card); | ||
257 | goto err; | ||
258 | } | ||
259 | |||
260 | card->type = MMC_TYPE_SDIO; | ||
261 | |||
262 | /* | ||
263 | * For native busses: set card RCA and quit open drain mode. | ||
264 | */ | ||
265 | if (!mmc_host_is_spi(host)) { | ||
266 | err = mmc_send_relative_addr(host, &card->rca); | ||
267 | if (err) | ||
268 | goto remove; | ||
269 | |||
270 | mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); | ||
271 | } | ||
272 | |||
273 | /* | ||
274 | * Select card, as all following commands rely on that. | ||
275 | */ | ||
276 | if (!mmc_host_is_spi(host)) { | ||
277 | err = mmc_select_card(card); | ||
278 | if (err) | ||
279 | goto remove; | ||
280 | } | ||
281 | |||
282 | /* | ||
283 | * Read the common registers. | ||
284 | */ | ||
285 | err = sdio_read_cccr(card); | ||
286 | if (err) | ||
287 | goto remove; | ||
288 | |||
289 | /* | ||
290 | * Read the common CIS tuples. | ||
291 | */ | ||
292 | err = sdio_read_common_cis(card); | ||
293 | if (err) | ||
294 | goto remove; | ||
295 | |||
296 | if (oldcard) { | ||
297 | int same = (card->cis.vendor == oldcard->cis.vendor && | ||
298 | card->cis.device == oldcard->cis.device); | ||
299 | mmc_remove_card(card); | ||
300 | if (!same) { | ||
301 | err = -ENOENT; | ||
302 | goto err; | ||
303 | } | ||
304 | card = oldcard; | ||
305 | } | ||
306 | |||
307 | /* | ||
308 | * Switch to high-speed (if supported). | ||
309 | */ | ||
310 | err = sdio_enable_hs(card); | ||
311 | if (err) | ||
312 | goto remove; | ||
313 | |||
314 | /* | ||
315 | * Change to the card's maximum speed. | ||
316 | */ | ||
317 | if (mmc_card_highspeed(card)) { | ||
318 | /* | ||
319 | * The SDIO specification doesn't mention how | ||
320 | * the CIS transfer speed register relates to | ||
321 | * high-speed, but it seems that 50 MHz is | ||
322 | * mandatory. | ||
323 | */ | ||
324 | mmc_set_clock(host, 50000000); | ||
325 | } else { | ||
326 | mmc_set_clock(host, card->cis.max_dtr); | ||
327 | } | ||
328 | |||
329 | /* | ||
330 | * Switch to wider bus (if supported). | ||
331 | */ | ||
332 | err = sdio_enable_wide(card); | ||
333 | if (err) | ||
334 | goto remove; | ||
335 | |||
336 | if (!oldcard) | ||
337 | host->card = card; | ||
338 | return 0; | ||
339 | |||
340 | remove: | ||
341 | if (!oldcard) | ||
342 | mmc_remove_card(card); | ||
343 | |||
344 | err: | ||
345 | return err; | ||
346 | } | ||
347 | |||
348 | /* | ||
221 | * Host is being removed. Free up the current card. | 349 | * Host is being removed. Free up the current card. |
222 | */ | 350 | */ |
223 | static void mmc_sdio_remove(struct mmc_host *host) | 351 | static void mmc_sdio_remove(struct mmc_host *host) |
@@ -266,10 +394,74 @@ static void mmc_sdio_detect(struct mmc_host *host) | |||
266 | } | 394 | } |
267 | } | 395 | } |
268 | 396 | ||
397 | /* | ||
398 | * SDIO suspend. We need to suspend all functions separately. | ||
399 | * Therefore all registered functions must have drivers with suspend | ||
400 | * and resume methods. Failing that we simply remove the whole card. | ||
401 | */ | ||
402 | static void mmc_sdio_suspend(struct mmc_host *host) | ||
403 | { | ||
404 | int i; | ||
405 | |||
406 | /* make sure all registered functions can suspend/resume */ | ||
407 | for (i = 0; i < host->card->sdio_funcs; i++) { | ||
408 | struct sdio_func *func = host->card->sdio_func[i]; | ||
409 | if (func && sdio_func_present(func) && func->dev.driver) { | ||
410 | const struct dev_pm_ops *pmops = func->dev.driver->pm; | ||
411 | if (!pmops || !pmops->suspend || !pmops->resume) { | ||
412 | /* just remove the entire card in that case */ | ||
413 | mmc_sdio_remove(host); | ||
414 | mmc_claim_host(host); | ||
415 | mmc_detach_bus(host); | ||
416 | mmc_release_host(host); | ||
417 | return; | ||
418 | } | ||
419 | } | ||
420 | } | ||
421 | |||
422 | /* now suspend them */ | ||
423 | for (i = 0; i < host->card->sdio_funcs; i++) { | ||
424 | struct sdio_func *func = host->card->sdio_func[i]; | ||
425 | if (func && sdio_func_present(func) && func->dev.driver) { | ||
426 | const struct dev_pm_ops *pmops = func->dev.driver->pm; | ||
427 | pmops->suspend(&func->dev); | ||
428 | } | ||
429 | } | ||
430 | } | ||
431 | |||
432 | static void mmc_sdio_resume(struct mmc_host *host) | ||
433 | { | ||
434 | int i, err; | ||
435 | |||
436 | BUG_ON(!host); | ||
437 | BUG_ON(!host->card); | ||
438 | |||
439 | mmc_claim_host(host); | ||
440 | err = mmc_sdio_init_card(host, host->ocr, host->card); | ||
441 | mmc_release_host(host); | ||
442 | if (err) { | ||
443 | mmc_sdio_remove(host); | ||
444 | mmc_claim_host(host); | ||
445 | mmc_detach_bus(host); | ||
446 | mmc_release_host(host); | ||
447 | return; | ||
448 | } | ||
449 | |||
450 | /* resume all functions */ | ||
451 | for (i = 0; i < host->card->sdio_funcs; i++) { | ||
452 | struct sdio_func *func = host->card->sdio_func[i]; | ||
453 | if (func && sdio_func_present(func) && func->dev.driver) { | ||
454 | const struct dev_pm_ops *pmops = func->dev.driver->pm; | ||
455 | pmops->resume(&func->dev); | ||
456 | } | ||
457 | } | ||
458 | } | ||
269 | 459 | ||
270 | static const struct mmc_bus_ops mmc_sdio_ops = { | 460 | static const struct mmc_bus_ops mmc_sdio_ops = { |
271 | .remove = mmc_sdio_remove, | 461 | .remove = mmc_sdio_remove, |
272 | .detect = mmc_sdio_detect, | 462 | .detect = mmc_sdio_detect, |
463 | .suspend = mmc_sdio_suspend, | ||
464 | .resume = mmc_sdio_resume, | ||
273 | }; | 465 | }; |
274 | 466 | ||
275 | 467 | ||
@@ -309,103 +501,18 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) | |||
309 | } | 501 | } |
310 | 502 | ||
311 | /* | 503 | /* |
312 | * Inform the card of the voltage | 504 | * Detect and init the card. |
313 | */ | 505 | */ |
314 | err = mmc_send_io_op_cond(host, host->ocr, &ocr); | 506 | err = mmc_sdio_init_card(host, host->ocr, NULL); |
315 | if (err) | 507 | if (err) |
316 | goto err; | 508 | goto err; |
317 | 509 | card = host->card; | |
318 | /* | ||
319 | * For SPI, enable CRC as appropriate. | ||
320 | */ | ||
321 | if (mmc_host_is_spi(host)) { | ||
322 | err = mmc_spi_set_crc(host, use_spi_crc); | ||
323 | if (err) | ||
324 | goto err; | ||
325 | } | ||
326 | 510 | ||
327 | /* | 511 | /* |
328 | * The number of functions on the card is encoded inside | 512 | * The number of functions on the card is encoded inside |
329 | * the ocr. | 513 | * the ocr. |
330 | */ | 514 | */ |
331 | funcs = (ocr & 0x70000000) >> 28; | 515 | card->sdio_funcs = funcs = (ocr & 0x70000000) >> 28; |
332 | |||
333 | /* | ||
334 | * Allocate card structure. | ||
335 | */ | ||
336 | card = mmc_alloc_card(host, NULL); | ||
337 | if (IS_ERR(card)) { | ||
338 | err = PTR_ERR(card); | ||
339 | goto err; | ||
340 | } | ||
341 | |||
342 | card->type = MMC_TYPE_SDIO; | ||
343 | card->sdio_funcs = funcs; | ||
344 | |||
345 | host->card = card; | ||
346 | |||
347 | /* | ||
348 | * For native busses: set card RCA and quit open drain mode. | ||
349 | */ | ||
350 | if (!mmc_host_is_spi(host)) { | ||
351 | err = mmc_send_relative_addr(host, &card->rca); | ||
352 | if (err) | ||
353 | goto remove; | ||
354 | |||
355 | mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); | ||
356 | } | ||
357 | |||
358 | /* | ||
359 | * Select card, as all following commands rely on that. | ||
360 | */ | ||
361 | if (!mmc_host_is_spi(host)) { | ||
362 | err = mmc_select_card(card); | ||
363 | if (err) | ||
364 | goto remove; | ||
365 | } | ||
366 | |||
367 | /* | ||
368 | * Read the common registers. | ||
369 | */ | ||
370 | err = sdio_read_cccr(card); | ||
371 | if (err) | ||
372 | goto remove; | ||
373 | |||
374 | /* | ||
375 | * Read the common CIS tuples. | ||
376 | */ | ||
377 | err = sdio_read_common_cis(card); | ||
378 | if (err) | ||
379 | goto remove; | ||
380 | |||
381 | /* | ||
382 | * Switch to high-speed (if supported). | ||
383 | */ | ||
384 | err = sdio_enable_hs(card); | ||
385 | if (err) | ||
386 | goto remove; | ||
387 | |||
388 | /* | ||
389 | * Change to the card's maximum speed. | ||
390 | */ | ||
391 | if (mmc_card_highspeed(card)) { | ||
392 | /* | ||
393 | * The SDIO specification doesn't mention how | ||
394 | * the CIS transfer speed register relates to | ||
395 | * high-speed, but it seems that 50 MHz is | ||
396 | * mandatory. | ||
397 | */ | ||
398 | mmc_set_clock(host, 50000000); | ||
399 | } else { | ||
400 | mmc_set_clock(host, card->cis.max_dtr); | ||
401 | } | ||
402 | |||
403 | /* | ||
404 | * Switch to wider bus (if supported). | ||
405 | */ | ||
406 | err = sdio_enable_wide(card); | ||
407 | if (err) | ||
408 | goto remove; | ||
409 | 516 | ||
410 | /* | 517 | /* |
411 | * If needed, disconnect card detection pull-up resistor. | 518 | * If needed, disconnect card detection pull-up resistor. |