diff options
| -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); |
