diff options
| -rw-r--r-- | drivers/mmc/core/sd.c | 249 | ||||
| -rw-r--r-- | drivers/mmc/core/sd.h | 17 | ||||
| -rw-r--r-- | drivers/mmc/core/sdio.c | 39 |
3 files changed, 186 insertions, 119 deletions
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 5eac21df480..e6d7d9fab44 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c | |||
| @@ -59,7 +59,7 @@ static const unsigned int tacc_mant[] = { | |||
| 59 | /* | 59 | /* |
| 60 | * Given the decoded CSD structure, decode the raw CID to our CID structure. | 60 | * Given the decoded CSD structure, decode the raw CID to our CID structure. |
| 61 | */ | 61 | */ |
| 62 | static void mmc_decode_cid(struct mmc_card *card) | 62 | void mmc_decode_cid(struct mmc_card *card) |
| 63 | { | 63 | { |
| 64 | u32 *resp = card->raw_cid; | 64 | u32 *resp = card->raw_cid; |
| 65 | 65 | ||
| @@ -238,7 +238,7 @@ out: | |||
| 238 | /* | 238 | /* |
| 239 | * Test if the card supports high-speed mode and, if so, switch to it. | 239 | * Test if the card supports high-speed mode and, if so, switch to it. |
| 240 | */ | 240 | */ |
| 241 | static int mmc_switch_hs(struct mmc_card *card) | 241 | int mmc_sd_switch_hs(struct mmc_card *card) |
| 242 | { | 242 | { |
| 243 | int err; | 243 | int err; |
| 244 | u8 *status; | 244 | u8 *status; |
| @@ -272,9 +272,9 @@ static int mmc_switch_hs(struct mmc_card *card) | |||
| 272 | printk(KERN_WARNING "%s: Problem switching card " | 272 | printk(KERN_WARNING "%s: Problem switching card " |
| 273 | "into high-speed mode!\n", | 273 | "into high-speed mode!\n", |
| 274 | mmc_hostname(card->host)); | 274 | mmc_hostname(card->host)); |
| 275 | err = 0; | ||
| 275 | } else { | 276 | } else { |
| 276 | mmc_card_set_highspeed(card); | 277 | err = 1; |
| 277 | mmc_set_timing(card->host, MMC_TIMING_SD_HS); | ||
| 278 | } | 278 | } |
| 279 | 279 | ||
| 280 | out: | 280 | out: |
| @@ -320,26 +320,16 @@ static const struct attribute_group *sd_attr_groups[] = { | |||
| 320 | NULL, | 320 | NULL, |
| 321 | }; | 321 | }; |
| 322 | 322 | ||
| 323 | static struct device_type sd_type = { | 323 | struct device_type sd_type = { |
| 324 | .groups = sd_attr_groups, | 324 | .groups = sd_attr_groups, |
| 325 | }; | 325 | }; |
| 326 | 326 | ||
| 327 | /* | 327 | /* |
| 328 | * Handle the detection and initialisation of a card. | 328 | * Fetch CID from card. |
| 329 | * | ||
| 330 | * In the case of a resume, "oldcard" will contain the card | ||
| 331 | * we're trying to reinitialise. | ||
| 332 | */ | 329 | */ |
| 333 | static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | 330 | int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid) |
| 334 | struct mmc_card *oldcard) | ||
| 335 | { | 331 | { |
| 336 | struct mmc_card *card; | ||
| 337 | int err; | 332 | int err; |
| 338 | u32 cid[4]; | ||
| 339 | unsigned int max_dtr; | ||
| 340 | |||
| 341 | BUG_ON(!host); | ||
| 342 | WARN_ON(!host->claimed); | ||
| 343 | 333 | ||
| 344 | /* | 334 | /* |
| 345 | * Since we're changing the OCR value, we seem to | 335 | * Since we're changing the OCR value, we seem to |
| @@ -361,23 +351,136 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
| 361 | 351 | ||
| 362 | err = mmc_send_app_op_cond(host, ocr, NULL); | 352 | err = mmc_send_app_op_cond(host, ocr, NULL); |
| 363 | if (err) | 353 | if (err) |
| 364 | goto err; | 354 | return err; |
| 365 | 355 | ||
| 366 | /* | ||
| 367 | * Fetch CID from card. | ||
| 368 | */ | ||
| 369 | if (mmc_host_is_spi(host)) | 356 | if (mmc_host_is_spi(host)) |
| 370 | err = mmc_send_cid(host, cid); | 357 | err = mmc_send_cid(host, cid); |
| 371 | else | 358 | else |
| 372 | err = mmc_all_send_cid(host, cid); | 359 | err = mmc_all_send_cid(host, cid); |
| 360 | |||
| 361 | return err; | ||
| 362 | } | ||
| 363 | |||
| 364 | int mmc_sd_get_csd(struct mmc_host *host, struct mmc_card *card) | ||
| 365 | { | ||
| 366 | int err; | ||
| 367 | |||
| 368 | /* | ||
| 369 | * Fetch CSD from card. | ||
| 370 | */ | ||
| 371 | err = mmc_send_csd(card, card->raw_csd); | ||
| 373 | if (err) | 372 | if (err) |
| 374 | goto err; | 373 | return err; |
| 375 | 374 | ||
| 376 | if (oldcard) { | 375 | err = mmc_decode_csd(card); |
| 377 | if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) { | 376 | if (err) |
| 378 | err = -ENOENT; | 377 | return err; |
| 379 | goto err; | 378 | |
| 379 | return 0; | ||
| 380 | } | ||
| 381 | |||
| 382 | int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card, | ||
| 383 | bool reinit) | ||
| 384 | { | ||
| 385 | int err; | ||
| 386 | |||
| 387 | if (!reinit) { | ||
| 388 | /* | ||
| 389 | * Fetch SCR from card. | ||
| 390 | */ | ||
| 391 | err = mmc_app_send_scr(card, card->raw_scr); | ||
| 392 | if (err) | ||
| 393 | return err; | ||
| 394 | |||
| 395 | err = mmc_decode_scr(card); | ||
| 396 | if (err) | ||
| 397 | return err; | ||
| 398 | |||
| 399 | /* | ||
| 400 | * Fetch switch information from card. | ||
| 401 | */ | ||
| 402 | err = mmc_read_switch(card); | ||
| 403 | if (err) | ||
| 404 | return err; | ||
| 405 | } | ||
| 406 | |||
| 407 | /* | ||
| 408 | * For SPI, enable CRC as appropriate. | ||
| 409 | * This CRC enable is located AFTER the reading of the | ||
| 410 | * card registers because some SDHC cards are not able | ||
| 411 | * to provide valid CRCs for non-512-byte blocks. | ||
| 412 | */ | ||
| 413 | if (mmc_host_is_spi(host)) { | ||
| 414 | err = mmc_spi_set_crc(host, use_spi_crc); | ||
| 415 | if (err) | ||
| 416 | return err; | ||
| 417 | } | ||
| 418 | |||
| 419 | /* | ||
| 420 | * Check if read-only switch is active. | ||
| 421 | */ | ||
| 422 | if (!reinit) { | ||
| 423 | int ro = -1; | ||
| 424 | |||
| 425 | if (host->ops->get_ro) | ||
| 426 | ro = host->ops->get_ro(host); | ||
| 427 | |||
| 428 | if (ro < 0) { | ||
| 429 | printk(KERN_WARNING "%s: host does not " | ||
| 430 | "support reading read-only " | ||
| 431 | "switch. assuming write-enable.\n", | ||
| 432 | mmc_hostname(host)); | ||
| 433 | } else if (ro > 0) { | ||
| 434 | mmc_card_set_readonly(card); | ||
| 380 | } | 435 | } |
| 436 | } | ||
| 437 | |||
| 438 | return 0; | ||
| 439 | } | ||
| 440 | |||
| 441 | unsigned mmc_sd_get_max_clock(struct mmc_card *card) | ||
| 442 | { | ||
| 443 | unsigned max_dtr = (unsigned int)-1; | ||
| 444 | |||
| 445 | if (mmc_card_highspeed(card)) { | ||
| 446 | if (max_dtr > card->sw_caps.hs_max_dtr) | ||
| 447 | max_dtr = card->sw_caps.hs_max_dtr; | ||
| 448 | } else if (max_dtr > card->csd.max_dtr) { | ||
| 449 | max_dtr = card->csd.max_dtr; | ||
| 450 | } | ||
| 451 | |||
| 452 | return max_dtr; | ||
| 453 | } | ||
| 454 | |||
| 455 | void mmc_sd_go_highspeed(struct mmc_card *card) | ||
| 456 | { | ||
| 457 | mmc_card_set_highspeed(card); | ||
| 458 | mmc_set_timing(card->host, MMC_TIMING_SD_HS); | ||
| 459 | } | ||
| 460 | |||
| 461 | /* | ||
| 462 | * Handle the detection and initialisation of a card. | ||
| 463 | * | ||
| 464 | * In the case of a resume, "oldcard" will contain the card | ||
| 465 | * we're trying to reinitialise. | ||
| 466 | */ | ||
| 467 | static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | ||
| 468 | struct mmc_card *oldcard) | ||
| 469 | { | ||
| 470 | struct mmc_card *card; | ||
| 471 | int err; | ||
| 472 | u32 cid[4]; | ||
| 473 | |||
| 474 | BUG_ON(!host); | ||
| 475 | WARN_ON(!host->claimed); | ||
| 476 | |||
| 477 | err = mmc_sd_get_cid(host, ocr, cid); | ||
| 478 | if (err) | ||
| 479 | return err; | ||
| 480 | |||
| 481 | if (oldcard) { | ||
| 482 | if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) | ||
| 483 | return -ENOENT; | ||
| 381 | 484 | ||
| 382 | card = oldcard; | 485 | card = oldcard; |
| 383 | } else { | 486 | } else { |
| @@ -385,10 +488,8 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
| 385 | * Allocate card structure. | 488 | * Allocate card structure. |
| 386 | */ | 489 | */ |
| 387 | card = mmc_alloc_card(host, &sd_type); | 490 | card = mmc_alloc_card(host, &sd_type); |
| 388 | if (IS_ERR(card)) { | 491 | if (IS_ERR(card)) |
| 389 | err = PTR_ERR(card); | 492 | return PTR_ERR(card); |
| 390 | goto err; | ||
| 391 | } | ||
| 392 | 493 | ||
| 393 | card->type = MMC_TYPE_SD; | 494 | card->type = MMC_TYPE_SD; |
| 394 | memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); | 495 | memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); |
| @@ -400,22 +501,15 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
| 400 | if (!mmc_host_is_spi(host)) { | 501 | if (!mmc_host_is_spi(host)) { |
| 401 | err = mmc_send_relative_addr(host, &card->rca); | 502 | err = mmc_send_relative_addr(host, &card->rca); |
| 402 | if (err) | 503 | if (err) |
| 403 | goto free_card; | 504 | return err; |
| 404 | 505 | ||
| 405 | mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); | 506 | mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); |
| 406 | } | 507 | } |
| 407 | 508 | ||
| 408 | if (!oldcard) { | 509 | if (!oldcard) { |
| 409 | /* | 510 | err = mmc_sd_get_csd(host, card); |
| 410 | * Fetch CSD from card. | ||
| 411 | */ | ||
| 412 | err = mmc_send_csd(card, card->raw_csd); | ||
| 413 | if (err) | 511 | if (err) |
| 414 | goto free_card; | 512 | return err; |
| 415 | |||
| 416 | err = mmc_decode_csd(card); | ||
| 417 | if (err) | ||
| 418 | goto free_card; | ||
| 419 | 513 | ||
| 420 | mmc_decode_cid(card); | 514 | mmc_decode_cid(card); |
| 421 | } | 515 | } |
| @@ -426,61 +520,26 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
| 426 | if (!mmc_host_is_spi(host)) { | 520 | if (!mmc_host_is_spi(host)) { |
| 427 | err = mmc_select_card(card); | 521 | err = mmc_select_card(card); |
| 428 | if (err) | 522 | if (err) |
| 429 | goto free_card; | 523 | return err; |
| 430 | } | 524 | } |
| 431 | 525 | ||
| 432 | if (!oldcard) { | 526 | err = mmc_sd_setup_card(host, card, oldcard != NULL); |
| 433 | /* | 527 | if (err) |
| 434 | * Fetch SCR from card. | 528 | goto free_card; |
| 435 | */ | ||
| 436 | err = mmc_app_send_scr(card, card->raw_scr); | ||
| 437 | if (err) | ||
| 438 | goto free_card; | ||
| 439 | |||
| 440 | err = mmc_decode_scr(card); | ||
| 441 | if (err < 0) | ||
| 442 | goto free_card; | ||
| 443 | |||
| 444 | /* | ||
| 445 | * Fetch switch information from card. | ||
| 446 | */ | ||
| 447 | err = mmc_read_switch(card); | ||
| 448 | if (err) | ||
| 449 | goto free_card; | ||
| 450 | } | ||
| 451 | |||
| 452 | /* | ||
| 453 | * For SPI, enable CRC as appropriate. | ||
| 454 | * This CRC enable is located AFTER the reading of the | ||
| 455 | * card registers because some SDHC cards are not able | ||
| 456 | * to provide valid CRCs for non-512-byte blocks. | ||
| 457 | */ | ||
| 458 | if (mmc_host_is_spi(host)) { | ||
| 459 | err = mmc_spi_set_crc(host, use_spi_crc); | ||
| 460 | if (err) | ||
| 461 | goto free_card; | ||
| 462 | } | ||
| 463 | 529 | ||
| 464 | /* | 530 | /* |
| 465 | * Attempt to change to high-speed (if supported) | 531 | * Attempt to change to high-speed (if supported) |
| 466 | */ | 532 | */ |
| 467 | err = mmc_switch_hs(card); | 533 | err = mmc_sd_switch_hs(card); |
| 468 | if (err) | 534 | if (err > 0) |
| 535 | mmc_sd_go_highspeed(card); | ||
| 536 | else if (err) | ||
| 469 | goto free_card; | 537 | goto free_card; |
| 470 | 538 | ||
| 471 | /* | 539 | /* |
| 472 | * Compute bus speed. | 540 | * Set bus speed. |
| 473 | */ | 541 | */ |
| 474 | max_dtr = (unsigned int)-1; | 542 | mmc_set_clock(host, mmc_sd_get_max_clock(card)); |
| 475 | |||
| 476 | if (mmc_card_highspeed(card)) { | ||
| 477 | if (max_dtr > card->sw_caps.hs_max_dtr) | ||
| 478 | max_dtr = card->sw_caps.hs_max_dtr; | ||
| 479 | } else if (max_dtr > card->csd.max_dtr) { | ||
| 480 | max_dtr = card->csd.max_dtr; | ||
| 481 | } | ||
| 482 | |||
| 483 | mmc_set_clock(host, max_dtr); | ||
| 484 | 543 | ||
| 485 | /* | 544 | /* |
| 486 | * Switch to wider bus (if supported). | 545 | * Switch to wider bus (if supported). |
| @@ -494,30 +553,12 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
| 494 | mmc_set_bus_width(host, MMC_BUS_WIDTH_4); | 553 | mmc_set_bus_width(host, MMC_BUS_WIDTH_4); |
| 495 | } | 554 | } |
| 496 | 555 | ||
| 497 | /* | 556 | host->card = card; |
| 498 | * Check if read-only switch is active. | ||
| 499 | */ | ||
| 500 | if (!oldcard) { | ||
| 501 | if (!host->ops->get_ro || host->ops->get_ro(host) < 0) { | ||
| 502 | printk(KERN_WARNING "%s: host does not " | ||
| 503 | "support reading read-only " | ||
| 504 | "switch. assuming write-enable.\n", | ||
| 505 | mmc_hostname(host)); | ||
| 506 | } else { | ||
| 507 | if (host->ops->get_ro(host) > 0) | ||
| 508 | mmc_card_set_readonly(card); | ||
| 509 | } | ||
| 510 | } | ||
| 511 | |||
| 512 | if (!oldcard) | ||
| 513 | host->card = card; | ||
| 514 | |||
| 515 | return 0; | 557 | return 0; |
| 516 | 558 | ||
| 517 | free_card: | 559 | free_card: |
| 518 | if (!oldcard) | 560 | if (!oldcard) |
| 519 | mmc_remove_card(card); | 561 | mmc_remove_card(card); |
| 520 | err: | ||
| 521 | 562 | ||
| 522 | return err; | 563 | return err; |
| 523 | } | 564 | } |
diff --git a/drivers/mmc/core/sd.h b/drivers/mmc/core/sd.h new file mode 100644 index 00000000000..3d8800fa760 --- /dev/null +++ b/drivers/mmc/core/sd.h | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | #ifndef _MMC_CORE_SD_H | ||
| 2 | #define _MMC_CORE_SD_H | ||
| 3 | |||
| 4 | #include <linux/mmc/card.h> | ||
| 5 | |||
| 6 | extern struct device_type sd_type; | ||
| 7 | |||
| 8 | int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid); | ||
| 9 | int mmc_sd_get_csd(struct mmc_host *host, struct mmc_card *card); | ||
| 10 | void mmc_decode_cid(struct mmc_card *card); | ||
| 11 | int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card, | ||
| 12 | bool reinit); | ||
| 13 | unsigned mmc_sd_get_max_clock(struct mmc_card *card); | ||
| 14 | int mmc_sd_switch_hs(struct mmc_card *card); | ||
| 15 | void mmc_sd_go_highspeed(struct mmc_card *card); | ||
| 16 | |||
| 17 | #endif | ||
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index b9dee28ee7d..47d1708810b 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | 18 | ||
| 19 | #include "core.h" | 19 | #include "core.h" |
| 20 | #include "bus.h" | 20 | #include "bus.h" |
| 21 | #include "sd.h" | ||
| 21 | #include "sdio_bus.h" | 22 | #include "sdio_bus.h" |
| 22 | #include "mmc_ops.h" | 23 | #include "mmc_ops.h" |
| 23 | #include "sd_ops.h" | 24 | #include "sd_ops.h" |
| @@ -245,10 +246,26 @@ static int sdio_enable_hs(struct mmc_card *card) | |||
| 245 | if (ret) | 246 | if (ret) |
| 246 | return ret; | 247 | return ret; |
| 247 | 248 | ||
| 248 | mmc_card_set_highspeed(card); | 249 | return 1; |
| 249 | mmc_set_timing(card->host, MMC_TIMING_SD_HS); | 250 | } |
| 250 | 251 | ||
| 251 | return 0; | 252 | static unsigned mmc_sdio_get_max_clock(struct mmc_card *card) |
| 253 | { | ||
| 254 | unsigned max_dtr; | ||
| 255 | |||
| 256 | if (mmc_card_highspeed(card)) { | ||
| 257 | /* | ||
| 258 | * The SDIO specification doesn't mention how | ||
| 259 | * the CIS transfer speed register relates to | ||
| 260 | * high-speed, but it seems that 50 MHz is | ||
| 261 | * mandatory. | ||
| 262 | */ | ||
| 263 | max_dtr = 50000000; | ||
| 264 | } else { | ||
| 265 | max_dtr = card->cis.max_dtr; | ||
| 266 | } | ||
| 267 | |||
| 268 | return max_dtr; | ||
| 252 | } | 269 | } |
| 253 | 270 | ||
| 254 | /* | 271 | /* |
| @@ -351,23 +368,15 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, | |||
| 351 | * Switch to high-speed (if supported). | 368 | * Switch to high-speed (if supported). |
| 352 | */ | 369 | */ |
| 353 | err = sdio_enable_hs(card); | 370 | err = sdio_enable_hs(card); |
| 354 | if (err) | 371 | if (err > 0) |
| 372 | mmc_sd_go_highspeed(card); | ||
| 373 | else if (err) | ||
| 355 | goto remove; | 374 | goto remove; |
| 356 | 375 | ||
| 357 | /* | 376 | /* |
| 358 | * Change to the card's maximum speed. | 377 | * Change to the card's maximum speed. |
| 359 | */ | 378 | */ |
| 360 | if (mmc_card_highspeed(card)) { | 379 | mmc_set_clock(host, mmc_sdio_get_max_clock(card)); |
| 361 | /* | ||
| 362 | * The SDIO specification doesn't mention how | ||
| 363 | * the CIS transfer speed register relates to | ||
| 364 | * high-speed, but it seems that 50 MHz is | ||
| 365 | * mandatory. | ||
| 366 | */ | ||
| 367 | mmc_set_clock(host, 50000000); | ||
| 368 | } else { | ||
| 369 | mmc_set_clock(host, card->cis.max_dtr); | ||
| 370 | } | ||
| 371 | 380 | ||
| 372 | /* | 381 | /* |
| 373 | * Switch to wider bus (if supported). | 382 | * Switch to wider bus (if supported). |
