aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorNicolas Pitre <nico@fluxnic.net>2009-09-22 19:45:28 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-23 10:39:38 -0400
commit17d33e14f7ffc05f8c81e4a3bdb9a8003a05dcce (patch)
treefc5c75b7886cf6ac0af054fd68bb837c88e09dc5 /drivers/mmc
parentd08ebeddfb3293fa4bdfca9c610daf1e8ec8b233 (diff)
mmc: core SDIO suspend/resume support
Currently, all SDIO cards are virtually removed upon a suspend, and completely reprobed upon a resume. This adds the suspend and resume methods to the SDIO bus driver so to be able to dispatch those events to the actual SDIO function drivers for real suspend/resume instead. All active functions on a card must have a driver with both a suspend and a resume method though. Failing that, we fall back to the current behavior of simply "removing" the card when suspending. When resuming, we make sure the same card is still inserted by comparing the vendor and product IDs. If there is a mismatch, or if there is simply no card anymore in the slot, then the previous card is "removed" and the new card is detected. This is further enhanced with the next patch. [akpm@linux-foundation.org: fix warnings] Signed-off-by: Nicolas Pitre <nico@marvell.com> Cc: <linux-mmc@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/core/sdio.c285
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 */
226static 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
340remove:
341 if (!oldcard)
342 mmc_remove_card(card);
343
344err:
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 */
223static void mmc_sdio_remove(struct mmc_host *host) 351static 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 */
402static 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
432static 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
270static const struct mmc_bus_ops mmc_sdio_ops = { 460static 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.