diff options
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/Kconfig | 2 | ||||
-rw-r--r-- | drivers/mmc/core/Kconfig | 17 | ||||
-rw-r--r-- | drivers/mmc/core/core.c | 29 | ||||
-rw-r--r-- | drivers/mmc/core/core.h | 2 | ||||
-rw-r--r-- | drivers/mmc/core/mmc.c | 289 | ||||
-rw-r--r-- | drivers/mmc/core/sd.c | 318 |
6 files changed, 444 insertions, 213 deletions
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index c7d64c0187fb..6c97491543db 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig | |||
@@ -19,6 +19,8 @@ config MMC_DEBUG | |||
19 | This is an option for use by developers; most people should | 19 | This is an option for use by developers; most people should |
20 | say N here. This enables MMC core and driver debugging. | 20 | say N here. This enables MMC core and driver debugging. |
21 | 21 | ||
22 | source "drivers/mmc/core/Kconfig" | ||
23 | |||
22 | source "drivers/mmc/card/Kconfig" | 24 | source "drivers/mmc/card/Kconfig" |
23 | 25 | ||
24 | source "drivers/mmc/host/Kconfig" | 26 | source "drivers/mmc/host/Kconfig" |
diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig new file mode 100644 index 000000000000..94222b9a15ea --- /dev/null +++ b/drivers/mmc/core/Kconfig | |||
@@ -0,0 +1,17 @@ | |||
1 | # | ||
2 | # MMC core configuration | ||
3 | # | ||
4 | |||
5 | config MMC_UNSAFE_RESUME | ||
6 | bool "Allow unsafe resume (DANGEROUS)" | ||
7 | depends on MMC != n | ||
8 | help | ||
9 | If you say Y here, the MMC layer will assume that all cards | ||
10 | stayed in their respective slots during the suspend. The | ||
11 | normal behaviour is to remove them at suspend and | ||
12 | redetecting them at resume. Breaking this assumption will | ||
13 | in most cases result in data corruption. | ||
14 | |||
15 | This option is usually just for embedded systems which use | ||
16 | a MMC/SD card for rootfs. Most people should say N here. | ||
17 | |||
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 75333a2461df..72c7cf4a9f9d 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -677,14 +677,19 @@ int mmc_suspend_host(struct mmc_host *host, pm_message_t state) | |||
677 | 677 | ||
678 | mmc_bus_get(host); | 678 | mmc_bus_get(host); |
679 | if (host->bus_ops && !host->bus_dead) { | 679 | if (host->bus_ops && !host->bus_dead) { |
680 | if (host->bus_ops->remove) | 680 | if (host->bus_ops->suspend) |
681 | host->bus_ops->remove(host); | 681 | host->bus_ops->suspend(host); |
682 | mmc_detach_bus(host); | 682 | if (!host->bus_ops->resume) { |
683 | if (host->bus_ops->remove) | ||
684 | host->bus_ops->remove(host); | ||
685 | |||
686 | mmc_claim_host(host); | ||
687 | mmc_detach_bus(host); | ||
688 | mmc_release_host(host); | ||
689 | } | ||
683 | } | 690 | } |
684 | mmc_bus_put(host); | 691 | mmc_bus_put(host); |
685 | 692 | ||
686 | BUG_ON(host->card); | ||
687 | |||
688 | mmc_power_off(host); | 693 | mmc_power_off(host); |
689 | 694 | ||
690 | return 0; | 695 | return 0; |
@@ -698,7 +703,19 @@ EXPORT_SYMBOL(mmc_suspend_host); | |||
698 | */ | 703 | */ |
699 | int mmc_resume_host(struct mmc_host *host) | 704 | int mmc_resume_host(struct mmc_host *host) |
700 | { | 705 | { |
701 | mmc_rescan(&host->detect.work); | 706 | mmc_bus_get(host); |
707 | if (host->bus_ops && !host->bus_dead) { | ||
708 | mmc_power_up(host); | ||
709 | BUG_ON(!host->bus_ops->resume); | ||
710 | host->bus_ops->resume(host); | ||
711 | } | ||
712 | mmc_bus_put(host); | ||
713 | |||
714 | /* | ||
715 | * We add a slight delay here so that resume can progress | ||
716 | * in parallel. | ||
717 | */ | ||
718 | mmc_detect_change(host, 1); | ||
702 | 719 | ||
703 | return 0; | 720 | return 0; |
704 | } | 721 | } |
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index fad8edc38099..177264d090ac 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h | |||
@@ -18,6 +18,8 @@ | |||
18 | struct mmc_bus_ops { | 18 | struct mmc_bus_ops { |
19 | void (*remove)(struct mmc_host *); | 19 | void (*remove)(struct mmc_host *); |
20 | void (*detect)(struct mmc_host *); | 20 | void (*detect)(struct mmc_host *); |
21 | void (*suspend)(struct mmc_host *); | ||
22 | void (*resume)(struct mmc_host *); | ||
21 | }; | 23 | }; |
22 | 24 | ||
23 | void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); | 25 | void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); |
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 47449e870131..619581e49163 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -229,55 +229,13 @@ out: | |||
229 | } | 229 | } |
230 | 230 | ||
231 | /* | 231 | /* |
232 | * Host is being removed. Free up the current card. | 232 | * Handle the detection and initialisation of a card. |
233 | */ | 233 | * |
234 | static void mmc_remove(struct mmc_host *host) | 234 | * In the case of a resume, "curcard" will contain the card |
235 | { | 235 | * we're trying to reinitialise. |
236 | BUG_ON(!host); | ||
237 | BUG_ON(!host->card); | ||
238 | |||
239 | mmc_remove_card(host->card); | ||
240 | host->card = NULL; | ||
241 | } | ||
242 | |||
243 | /* | ||
244 | * Card detection callback from host. | ||
245 | */ | ||
246 | static void mmc_detect(struct mmc_host *host) | ||
247 | { | ||
248 | int err; | ||
249 | |||
250 | BUG_ON(!host); | ||
251 | BUG_ON(!host->card); | ||
252 | |||
253 | mmc_claim_host(host); | ||
254 | |||
255 | /* | ||
256 | * Just check if our card has been removed. | ||
257 | */ | ||
258 | err = mmc_send_status(host->card, NULL); | ||
259 | |||
260 | mmc_release_host(host); | ||
261 | |||
262 | if (err != MMC_ERR_NONE) { | ||
263 | mmc_remove_card(host->card); | ||
264 | host->card = NULL; | ||
265 | |||
266 | mmc_claim_host(host); | ||
267 | mmc_detach_bus(host); | ||
268 | mmc_release_host(host); | ||
269 | } | ||
270 | } | ||
271 | |||
272 | static const struct mmc_bus_ops mmc_ops = { | ||
273 | .remove = mmc_remove, | ||
274 | .detect = mmc_detect, | ||
275 | }; | ||
276 | |||
277 | /* | ||
278 | * Starting point for MMC card init. | ||
279 | */ | 236 | */ |
280 | int mmc_attach_mmc(struct mmc_host *host, u32 ocr) | 237 | static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, |
238 | struct mmc_card *oldcard) | ||
281 | { | 239 | { |
282 | struct mmc_card *card; | 240 | struct mmc_card *card; |
283 | int err; | 241 | int err; |
@@ -287,27 +245,6 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr) | |||
287 | BUG_ON(!host); | 245 | BUG_ON(!host); |
288 | BUG_ON(!host->claimed); | 246 | BUG_ON(!host->claimed); |
289 | 247 | ||
290 | mmc_attach_bus(host, &mmc_ops); | ||
291 | |||
292 | /* | ||
293 | * Sanity check the voltages that the card claims to | ||
294 | * support. | ||
295 | */ | ||
296 | if (ocr & 0x7F) { | ||
297 | printk(KERN_WARNING "%s: card claims to support voltages " | ||
298 | "below the defined range. These will be ignored.\n", | ||
299 | mmc_hostname(host)); | ||
300 | ocr &= ~0x7F; | ||
301 | } | ||
302 | |||
303 | host->ocr = mmc_select_voltage(host, ocr); | ||
304 | |||
305 | /* | ||
306 | * Can we support the voltage of the card? | ||
307 | */ | ||
308 | if (!host->ocr) | ||
309 | goto err; | ||
310 | |||
311 | /* | 248 | /* |
312 | * Since we're changing the OCR value, we seem to | 249 | * Since we're changing the OCR value, we seem to |
313 | * need to tell some cards to go back to the idle | 250 | * need to tell some cards to go back to the idle |
@@ -317,7 +254,9 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr) | |||
317 | mmc_go_idle(host); | 254 | mmc_go_idle(host); |
318 | 255 | ||
319 | /* The extra bit indicates that we support high capacity */ | 256 | /* The extra bit indicates that we support high capacity */ |
320 | mmc_send_op_cond(host, host->ocr | (1 << 30), NULL); | 257 | err = mmc_send_op_cond(host, ocr | (1 << 30), NULL); |
258 | if (err != MMC_ERR_NONE) | ||
259 | goto err; | ||
321 | 260 | ||
322 | /* | 261 | /* |
323 | * Fetch CID from card. | 262 | * Fetch CID from card. |
@@ -326,16 +265,23 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr) | |||
326 | if (err != MMC_ERR_NONE) | 265 | if (err != MMC_ERR_NONE) |
327 | goto err; | 266 | goto err; |
328 | 267 | ||
329 | /* | 268 | if (oldcard) { |
330 | * Allocate card structure. | 269 | if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) |
331 | */ | 270 | goto err; |
332 | card = mmc_alloc_card(host); | 271 | |
333 | if (IS_ERR(card)) | 272 | card = oldcard; |
334 | goto err; | 273 | } else { |
274 | /* | ||
275 | * Allocate card structure. | ||
276 | */ | ||
277 | card = mmc_alloc_card(host); | ||
278 | if (IS_ERR(card)) | ||
279 | goto err; | ||
335 | 280 | ||
336 | card->type = MMC_TYPE_MMC; | 281 | card->type = MMC_TYPE_MMC; |
337 | card->rca = 1; | 282 | card->rca = 1; |
338 | memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); | 283 | memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); |
284 | } | ||
339 | 285 | ||
340 | /* | 286 | /* |
341 | * Set card RCA. | 287 | * Set card RCA. |
@@ -346,15 +292,17 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr) | |||
346 | 292 | ||
347 | mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); | 293 | mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); |
348 | 294 | ||
349 | /* | 295 | if (!oldcard) { |
350 | * Fetch CSD from card. | 296 | /* |
351 | */ | 297 | * Fetch CSD from card. |
352 | err = mmc_send_csd(card, card->raw_csd); | 298 | */ |
353 | if (err != MMC_ERR_NONE) | 299 | err = mmc_send_csd(card, card->raw_csd); |
354 | goto free_card; | 300 | if (err != MMC_ERR_NONE) |
301 | goto free_card; | ||
355 | 302 | ||
356 | mmc_decode_csd(card); | 303 | mmc_decode_csd(card); |
357 | mmc_decode_cid(card); | 304 | mmc_decode_cid(card); |
305 | } | ||
358 | 306 | ||
359 | /* | 307 | /* |
360 | * Select card, as all following commands rely on that. | 308 | * Select card, as all following commands rely on that. |
@@ -363,12 +311,14 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr) | |||
363 | if (err != MMC_ERR_NONE) | 311 | if (err != MMC_ERR_NONE) |
364 | goto free_card; | 312 | goto free_card; |
365 | 313 | ||
366 | /* | 314 | if (!oldcard) { |
367 | * Fetch and process extened CSD. | 315 | /* |
368 | */ | 316 | * Fetch and process extened CSD. |
369 | err = mmc_read_ext_csd(card); | 317 | */ |
370 | if (err != MMC_ERR_NONE) | 318 | err = mmc_read_ext_csd(card); |
371 | goto free_card; | 319 | if (err != MMC_ERR_NONE) |
320 | goto free_card; | ||
321 | } | ||
372 | 322 | ||
373 | /* | 323 | /* |
374 | * Activate high speed (if supported) | 324 | * Activate high speed (if supported) |
@@ -412,11 +362,157 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr) | |||
412 | mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); | 362 | mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); |
413 | } | 363 | } |
414 | 364 | ||
415 | host->card = card; | 365 | if (!oldcard) |
366 | host->card = card; | ||
367 | |||
368 | return MMC_ERR_NONE; | ||
369 | |||
370 | free_card: | ||
371 | if (!oldcard) | ||
372 | mmc_remove_card(card); | ||
373 | err: | ||
374 | |||
375 | return MMC_ERR_FAILED; | ||
376 | } | ||
377 | |||
378 | /* | ||
379 | * Host is being removed. Free up the current card. | ||
380 | */ | ||
381 | static void mmc_remove(struct mmc_host *host) | ||
382 | { | ||
383 | BUG_ON(!host); | ||
384 | BUG_ON(!host->card); | ||
385 | |||
386 | mmc_remove_card(host->card); | ||
387 | host->card = NULL; | ||
388 | } | ||
389 | |||
390 | /* | ||
391 | * Card detection callback from host. | ||
392 | */ | ||
393 | static void mmc_detect(struct mmc_host *host) | ||
394 | { | ||
395 | int err; | ||
396 | |||
397 | BUG_ON(!host); | ||
398 | BUG_ON(!host->card); | ||
399 | |||
400 | mmc_claim_host(host); | ||
401 | |||
402 | /* | ||
403 | * Just check if our card has been removed. | ||
404 | */ | ||
405 | err = mmc_send_status(host->card, NULL); | ||
406 | |||
407 | mmc_release_host(host); | ||
408 | |||
409 | if (err != MMC_ERR_NONE) { | ||
410 | mmc_remove_card(host->card); | ||
411 | host->card = NULL; | ||
412 | |||
413 | mmc_claim_host(host); | ||
414 | mmc_detach_bus(host); | ||
415 | mmc_release_host(host); | ||
416 | } | ||
417 | } | ||
418 | |||
419 | #ifdef CONFIG_MMC_UNSAFE_RESUME | ||
420 | |||
421 | /* | ||
422 | * Suspend callback from host. | ||
423 | */ | ||
424 | static void mmc_suspend(struct mmc_host *host) | ||
425 | { | ||
426 | BUG_ON(!host); | ||
427 | BUG_ON(!host->card); | ||
416 | 428 | ||
429 | mmc_claim_host(host); | ||
430 | mmc_deselect_cards(host); | ||
431 | host->card->state &= ~MMC_STATE_HIGHSPEED; | ||
417 | mmc_release_host(host); | 432 | mmc_release_host(host); |
433 | } | ||
418 | 434 | ||
419 | err = mmc_register_card(card); | 435 | /* |
436 | * Resume callback from host. | ||
437 | * | ||
438 | * This function tries to determine if the same card is still present | ||
439 | * and, if so, restore all state to it. | ||
440 | */ | ||
441 | static void mmc_resume(struct mmc_host *host) | ||
442 | { | ||
443 | int err; | ||
444 | |||
445 | BUG_ON(!host); | ||
446 | BUG_ON(!host->card); | ||
447 | |||
448 | mmc_claim_host(host); | ||
449 | |||
450 | err = mmc_sd_init_card(host, host->ocr, host->card); | ||
451 | if (err != MMC_ERR_NONE) { | ||
452 | mmc_remove_card(host->card); | ||
453 | host->card = NULL; | ||
454 | |||
455 | mmc_detach_bus(host); | ||
456 | } | ||
457 | |||
458 | mmc_release_host(host); | ||
459 | } | ||
460 | |||
461 | #else | ||
462 | |||
463 | #define mmc_suspend NULL | ||
464 | #define mmc_resume NULL | ||
465 | |||
466 | #endif | ||
467 | |||
468 | static const struct mmc_bus_ops mmc_ops = { | ||
469 | .remove = mmc_remove, | ||
470 | .detect = mmc_detect, | ||
471 | .suspend = mmc_suspend, | ||
472 | .resume = mmc_resume, | ||
473 | }; | ||
474 | |||
475 | /* | ||
476 | * Starting point for MMC card init. | ||
477 | */ | ||
478 | int mmc_attach_mmc(struct mmc_host *host, u32 ocr) | ||
479 | { | ||
480 | int err; | ||
481 | |||
482 | BUG_ON(!host); | ||
483 | BUG_ON(!host->claimed); | ||
484 | |||
485 | mmc_attach_bus(host, &mmc_ops); | ||
486 | |||
487 | /* | ||
488 | * Sanity check the voltages that the card claims to | ||
489 | * support. | ||
490 | */ | ||
491 | if (ocr & 0x7F) { | ||
492 | printk(KERN_WARNING "%s: card claims to support voltages " | ||
493 | "below the defined range. These will be ignored.\n", | ||
494 | mmc_hostname(host)); | ||
495 | ocr &= ~0x7F; | ||
496 | } | ||
497 | |||
498 | host->ocr = mmc_select_voltage(host, ocr); | ||
499 | |||
500 | /* | ||
501 | * Can we support the voltage of the card? | ||
502 | */ | ||
503 | if (!host->ocr) | ||
504 | goto err; | ||
505 | |||
506 | /* | ||
507 | * Detect and init the card. | ||
508 | */ | ||
509 | err = mmc_sd_init_card(host, host->ocr, NULL); | ||
510 | if (err != MMC_ERR_NONE) | ||
511 | goto err; | ||
512 | |||
513 | mmc_release_host(host); | ||
514 | |||
515 | err = mmc_register_card(host->card); | ||
420 | if (err) | 516 | if (err) |
421 | goto reclaim_host; | 517 | goto reclaim_host; |
422 | 518 | ||
@@ -424,8 +520,7 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr) | |||
424 | 520 | ||
425 | reclaim_host: | 521 | reclaim_host: |
426 | mmc_claim_host(host); | 522 | mmc_claim_host(host); |
427 | free_card: | 523 | mmc_remove_card(host->card); |
428 | mmc_remove_card(card); | ||
429 | host->card = NULL; | 524 | host->card = NULL; |
430 | err: | 525 | err: |
431 | mmc_detach_bus(host); | 526 | mmc_detach_bus(host); |
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index ae54e8eb7fea..6597e778f70e 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c | |||
@@ -263,55 +263,13 @@ out: | |||
263 | } | 263 | } |
264 | 264 | ||
265 | /* | 265 | /* |
266 | * Host is being removed. Free up the current card. | 266 | * Handle the detection and initialisation of a card. |
267 | */ | 267 | * |
268 | static void mmc_sd_remove(struct mmc_host *host) | 268 | * In the case of a resume, "curcard" will contain the card |
269 | { | 269 | * we're trying to reinitialise. |
270 | BUG_ON(!host); | ||
271 | BUG_ON(!host->card); | ||
272 | |||
273 | mmc_remove_card(host->card); | ||
274 | host->card = NULL; | ||
275 | } | ||
276 | |||
277 | /* | ||
278 | * Card detection callback from host. | ||
279 | */ | ||
280 | static void mmc_sd_detect(struct mmc_host *host) | ||
281 | { | ||
282 | int err; | ||
283 | |||
284 | BUG_ON(!host); | ||
285 | BUG_ON(!host->card); | ||
286 | |||
287 | mmc_claim_host(host); | ||
288 | |||
289 | /* | ||
290 | * Just check if our card has been removed. | ||
291 | */ | ||
292 | err = mmc_send_status(host->card, NULL); | ||
293 | |||
294 | mmc_release_host(host); | ||
295 | |||
296 | if (err != MMC_ERR_NONE) { | ||
297 | mmc_remove_card(host->card); | ||
298 | host->card = NULL; | ||
299 | |||
300 | mmc_claim_host(host); | ||
301 | mmc_detach_bus(host); | ||
302 | mmc_release_host(host); | ||
303 | } | ||
304 | } | ||
305 | |||
306 | static const struct mmc_bus_ops mmc_sd_ops = { | ||
307 | .remove = mmc_sd_remove, | ||
308 | .detect = mmc_sd_detect, | ||
309 | }; | ||
310 | |||
311 | /* | ||
312 | * Starting point for SD card init. | ||
313 | */ | 270 | */ |
314 | int mmc_attach_sd(struct mmc_host *host, u32 ocr) | 271 | static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, |
272 | struct mmc_card *oldcard) | ||
315 | { | 273 | { |
316 | struct mmc_card *card; | 274 | struct mmc_card *card; |
317 | int err; | 275 | int err; |
@@ -321,34 +279,6 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr) | |||
321 | BUG_ON(!host); | 279 | BUG_ON(!host); |
322 | BUG_ON(!host->claimed); | 280 | BUG_ON(!host->claimed); |
323 | 281 | ||
324 | mmc_attach_bus(host, &mmc_sd_ops); | ||
325 | |||
326 | /* | ||
327 | * Sanity check the voltages that the card claims to | ||
328 | * support. | ||
329 | */ | ||
330 | if (ocr & 0x7F) { | ||
331 | printk(KERN_WARNING "%s: card claims to support voltages " | ||
332 | "below the defined range. These will be ignored.\n", | ||
333 | mmc_hostname(host)); | ||
334 | ocr &= ~0x7F; | ||
335 | } | ||
336 | |||
337 | if (ocr & MMC_VDD_165_195) { | ||
338 | printk(KERN_WARNING "%s: SD card claims to support the " | ||
339 | "incompletely defined 'low voltage range'. This " | ||
340 | "will be ignored.\n", mmc_hostname(host)); | ||
341 | ocr &= ~MMC_VDD_165_195; | ||
342 | } | ||
343 | |||
344 | host->ocr = mmc_select_voltage(host, ocr); | ||
345 | |||
346 | /* | ||
347 | * Can we support the voltage(s) of the card(s)? | ||
348 | */ | ||
349 | if (!host->ocr) | ||
350 | goto err; | ||
351 | |||
352 | /* | 282 | /* |
353 | * Since we're changing the OCR value, we seem to | 283 | * Since we're changing the OCR value, we seem to |
354 | * need to tell some cards to go back to the idle | 284 | * need to tell some cards to go back to the idle |
@@ -363,11 +293,13 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr) | |||
363 | * of the ocr to indicate that we can handle | 293 | * of the ocr to indicate that we can handle |
364 | * block-addressed SDHC cards. | 294 | * block-addressed SDHC cards. |
365 | */ | 295 | */ |
366 | err = mmc_send_if_cond(host, host->ocr); | 296 | err = mmc_send_if_cond(host, ocr); |
367 | if (err == MMC_ERR_NONE) | 297 | if (err == MMC_ERR_NONE) |
368 | ocr = host->ocr | (1 << 30); | 298 | ocr |= 1 << 30; |
369 | 299 | ||
370 | mmc_send_app_op_cond(host, ocr, NULL); | 300 | err = mmc_send_app_op_cond(host, ocr, NULL); |
301 | if (err != MMC_ERR_NONE) | ||
302 | goto err; | ||
371 | 303 | ||
372 | /* | 304 | /* |
373 | * Fetch CID from card. | 305 | * Fetch CID from card. |
@@ -376,15 +308,22 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr) | |||
376 | if (err != MMC_ERR_NONE) | 308 | if (err != MMC_ERR_NONE) |
377 | goto err; | 309 | goto err; |
378 | 310 | ||
379 | /* | 311 | if (oldcard) { |
380 | * Allocate card structure. | 312 | if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) |
381 | */ | 313 | goto err; |
382 | card = mmc_alloc_card(host); | ||
383 | if (IS_ERR(card)) | ||
384 | goto err; | ||
385 | 314 | ||
386 | card->type = MMC_TYPE_SD; | 315 | card = oldcard; |
387 | memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); | 316 | } else { |
317 | /* | ||
318 | * Allocate card structure. | ||
319 | */ | ||
320 | card = mmc_alloc_card(host); | ||
321 | if (IS_ERR(card)) | ||
322 | goto err; | ||
323 | |||
324 | card->type = MMC_TYPE_SD; | ||
325 | memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); | ||
326 | } | ||
388 | 327 | ||
389 | /* | 328 | /* |
390 | * Set card RCA. | 329 | * Set card RCA. |
@@ -395,35 +334,42 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr) | |||
395 | 334 | ||
396 | mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); | 335 | mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); |
397 | 336 | ||
398 | /* | 337 | if (!oldcard) { |
399 | * Fetch CSD from card. | 338 | /* |
400 | */ | 339 | * Fetch CSD from card. |
401 | err = mmc_send_csd(card, card->raw_csd); | 340 | */ |
402 | if (err != MMC_ERR_NONE) | 341 | err = mmc_send_csd(card, card->raw_csd); |
403 | goto free_card; | 342 | if (err != MMC_ERR_NONE) |
343 | goto free_card; | ||
404 | 344 | ||
405 | mmc_decode_csd(card); | 345 | mmc_decode_csd(card); |
406 | mmc_decode_cid(card); | 346 | mmc_decode_cid(card); |
347 | } | ||
407 | 348 | ||
408 | /* | 349 | /* |
409 | * Fetch SCR from card. | 350 | * Select card, as all following commands rely on that. |
410 | */ | 351 | */ |
411 | err = mmc_select_card(card); | 352 | err = mmc_select_card(card); |
412 | if (err != MMC_ERR_NONE) | 353 | if (err != MMC_ERR_NONE) |
413 | goto free_card; | 354 | goto free_card; |
414 | 355 | ||
415 | err = mmc_app_send_scr(card, card->raw_scr); | 356 | if (!oldcard) { |
416 | if (err != MMC_ERR_NONE) | 357 | /* |
417 | goto free_card; | 358 | * Fetch SCR from card. |
359 | */ | ||
360 | err = mmc_app_send_scr(card, card->raw_scr); | ||
361 | if (err != MMC_ERR_NONE) | ||
362 | goto free_card; | ||
418 | 363 | ||
419 | mmc_decode_scr(card); | 364 | mmc_decode_scr(card); |
420 | 365 | ||
421 | /* | 366 | /* |
422 | * Fetch switch information from card. | 367 | * Fetch switch information from card. |
423 | */ | 368 | */ |
424 | err = mmc_read_switch(card); | 369 | err = mmc_read_switch(card); |
425 | if (err != MMC_ERR_NONE) | 370 | if (err != MMC_ERR_NONE) |
426 | goto free_card; | 371 | goto free_card; |
372 | } | ||
427 | 373 | ||
428 | /* | 374 | /* |
429 | * Attempt to change to high-speed (if supported) | 375 | * Attempt to change to high-speed (if supported) |
@@ -458,11 +404,164 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr) | |||
458 | mmc_set_bus_width(host, MMC_BUS_WIDTH_4); | 404 | mmc_set_bus_width(host, MMC_BUS_WIDTH_4); |
459 | } | 405 | } |
460 | 406 | ||
461 | host->card = card; | 407 | if (!oldcard) |
408 | host->card = card; | ||
409 | |||
410 | return MMC_ERR_NONE; | ||
411 | |||
412 | free_card: | ||
413 | if (!oldcard) | ||
414 | mmc_remove_card(card); | ||
415 | err: | ||
416 | |||
417 | return MMC_ERR_FAILED; | ||
418 | } | ||
419 | |||
420 | /* | ||
421 | * Host is being removed. Free up the current card. | ||
422 | */ | ||
423 | static void mmc_sd_remove(struct mmc_host *host) | ||
424 | { | ||
425 | BUG_ON(!host); | ||
426 | BUG_ON(!host->card); | ||
427 | |||
428 | mmc_remove_card(host->card); | ||
429 | host->card = NULL; | ||
430 | } | ||
431 | |||
432 | /* | ||
433 | * Card detection callback from host. | ||
434 | */ | ||
435 | static void mmc_sd_detect(struct mmc_host *host) | ||
436 | { | ||
437 | int err; | ||
438 | |||
439 | BUG_ON(!host); | ||
440 | BUG_ON(!host->card); | ||
441 | |||
442 | mmc_claim_host(host); | ||
443 | |||
444 | /* | ||
445 | * Just check if our card has been removed. | ||
446 | */ | ||
447 | err = mmc_send_status(host->card, NULL); | ||
462 | 448 | ||
463 | mmc_release_host(host); | 449 | mmc_release_host(host); |
464 | 450 | ||
465 | err = mmc_register_card(card); | 451 | if (err != MMC_ERR_NONE) { |
452 | mmc_remove_card(host->card); | ||
453 | host->card = NULL; | ||
454 | |||
455 | mmc_claim_host(host); | ||
456 | mmc_detach_bus(host); | ||
457 | mmc_release_host(host); | ||
458 | } | ||
459 | } | ||
460 | |||
461 | #ifdef CONFIG_MMC_UNSAFE_RESUME | ||
462 | |||
463 | /* | ||
464 | * Suspend callback from host. | ||
465 | */ | ||
466 | static void mmc_sd_suspend(struct mmc_host *host) | ||
467 | { | ||
468 | BUG_ON(!host); | ||
469 | BUG_ON(!host->card); | ||
470 | |||
471 | mmc_claim_host(host); | ||
472 | mmc_deselect_cards(host); | ||
473 | host->card->state &= ~MMC_STATE_HIGHSPEED; | ||
474 | mmc_release_host(host); | ||
475 | } | ||
476 | |||
477 | /* | ||
478 | * Resume callback from host. | ||
479 | * | ||
480 | * This function tries to determine if the same card is still present | ||
481 | * and, if so, restore all state to it. | ||
482 | */ | ||
483 | static void mmc_sd_resume(struct mmc_host *host) | ||
484 | { | ||
485 | int err; | ||
486 | |||
487 | BUG_ON(!host); | ||
488 | BUG_ON(!host->card); | ||
489 | |||
490 | mmc_claim_host(host); | ||
491 | |||
492 | err = mmc_sd_init_card(host, host->ocr, host->card); | ||
493 | if (err != MMC_ERR_NONE) { | ||
494 | mmc_remove_card(host->card); | ||
495 | host->card = NULL; | ||
496 | |||
497 | mmc_detach_bus(host); | ||
498 | } | ||
499 | |||
500 | mmc_release_host(host); | ||
501 | } | ||
502 | |||
503 | #else | ||
504 | |||
505 | #define mmc_sd_suspend NULL | ||
506 | #define mmc_sd_resume NULL | ||
507 | |||
508 | #endif | ||
509 | |||
510 | static const struct mmc_bus_ops mmc_sd_ops = { | ||
511 | .remove = mmc_sd_remove, | ||
512 | .detect = mmc_sd_detect, | ||
513 | .suspend = mmc_sd_suspend, | ||
514 | .resume = mmc_sd_resume, | ||
515 | }; | ||
516 | |||
517 | /* | ||
518 | * Starting point for SD card init. | ||
519 | */ | ||
520 | int mmc_attach_sd(struct mmc_host *host, u32 ocr) | ||
521 | { | ||
522 | int err; | ||
523 | |||
524 | BUG_ON(!host); | ||
525 | BUG_ON(!host->claimed); | ||
526 | |||
527 | mmc_attach_bus(host, &mmc_sd_ops); | ||
528 | |||
529 | /* | ||
530 | * Sanity check the voltages that the card claims to | ||
531 | * support. | ||
532 | */ | ||
533 | if (ocr & 0x7F) { | ||
534 | printk(KERN_WARNING "%s: card claims to support voltages " | ||
535 | "below the defined range. These will be ignored.\n", | ||
536 | mmc_hostname(host)); | ||
537 | ocr &= ~0x7F; | ||
538 | } | ||
539 | |||
540 | if (ocr & MMC_VDD_165_195) { | ||
541 | printk(KERN_WARNING "%s: SD card claims to support the " | ||
542 | "incompletely defined 'low voltage range'. This " | ||
543 | "will be ignored.\n", mmc_hostname(host)); | ||
544 | ocr &= ~MMC_VDD_165_195; | ||
545 | } | ||
546 | |||
547 | host->ocr = mmc_select_voltage(host, ocr); | ||
548 | |||
549 | /* | ||
550 | * Can we support the voltage(s) of the card(s)? | ||
551 | */ | ||
552 | if (!host->ocr) | ||
553 | goto err; | ||
554 | |||
555 | /* | ||
556 | * Detect and init the card. | ||
557 | */ | ||
558 | err = mmc_sd_init_card(host, host->ocr, NULL); | ||
559 | if (err != MMC_ERR_NONE) | ||
560 | goto err; | ||
561 | |||
562 | mmc_release_host(host); | ||
563 | |||
564 | err = mmc_register_card(host->card); | ||
466 | if (err) | 565 | if (err) |
467 | goto reclaim_host; | 566 | goto reclaim_host; |
468 | 567 | ||
@@ -470,8 +569,7 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr) | |||
470 | 569 | ||
471 | reclaim_host: | 570 | reclaim_host: |
472 | mmc_claim_host(host); | 571 | mmc_claim_host(host); |
473 | free_card: | 572 | mmc_remove_card(host->card); |
474 | mmc_remove_card(card); | ||
475 | host->card = NULL; | 573 | host->card = NULL; |
476 | err: | 574 | err: |
477 | mmc_detach_bus(host); | 575 | mmc_detach_bus(host); |