diff options
Diffstat (limited to 'drivers/mmc')
| -rw-r--r-- | drivers/mmc/mmc.c | 530 | ||||
| -rw-r--r-- | drivers/mmc/mmc_block.c | 9 | ||||
| -rw-r--r-- | drivers/mmc/mmc_sysfs.c | 21 | ||||
| -rw-r--r-- | drivers/mmc/mmci.c | 2 | ||||
| -rw-r--r-- | drivers/mmc/pxamci.c | 15 | ||||
| -rw-r--r-- | drivers/mmc/wbsd.c | 89 | ||||
| -rw-r--r-- | drivers/mmc/wbsd.h | 3 |
7 files changed, 545 insertions, 124 deletions
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 0a8165974ba7..ceae379a4d4c 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | * linux/drivers/mmc/mmc.c | 2 | * linux/drivers/mmc/mmc.c |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2003-2004 Russell King, All Rights Reserved. | 4 | * Copyright (C) 2003-2004 Russell King, All Rights Reserved. |
| 5 | * SD support Copyright (C) 2004 Ian Molton, All Rights Reserved. | ||
| 6 | * SD support Copyright (C) 2005 Pierre Ossman, All Rights Reserved. | ||
| 5 | * | 7 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
| @@ -16,6 +18,8 @@ | |||
| 16 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
| 17 | #include <linux/pagemap.h> | 19 | #include <linux/pagemap.h> |
| 18 | #include <linux/err.h> | 20 | #include <linux/err.h> |
| 21 | #include <asm/scatterlist.h> | ||
| 22 | #include <linux/scatterlist.h> | ||
| 19 | 23 | ||
| 20 | #include <linux/mmc/card.h> | 24 | #include <linux/mmc/card.h> |
| 21 | #include <linux/mmc/host.h> | 25 | #include <linux/mmc/host.h> |
| @@ -172,7 +176,81 @@ int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries | |||
| 172 | 176 | ||
| 173 | EXPORT_SYMBOL(mmc_wait_for_cmd); | 177 | EXPORT_SYMBOL(mmc_wait_for_cmd); |
| 174 | 178 | ||
| 179 | /** | ||
| 180 | * mmc_wait_for_app_cmd - start an application command and wait for | ||
| 181 | completion | ||
| 182 | * @host: MMC host to start command | ||
| 183 | * @rca: RCA to send MMC_APP_CMD to | ||
| 184 | * @cmd: MMC command to start | ||
| 185 | * @retries: maximum number of retries | ||
| 186 | * | ||
| 187 | * Sends a MMC_APP_CMD, checks the card response, sends the command | ||
| 188 | * in the parameter and waits for it to complete. Return any error | ||
| 189 | * that occurred while the command was executing. Do not attempt to | ||
| 190 | * parse the response. | ||
| 191 | */ | ||
| 192 | int mmc_wait_for_app_cmd(struct mmc_host *host, unsigned int rca, | ||
| 193 | struct mmc_command *cmd, int retries) | ||
| 194 | { | ||
| 195 | struct mmc_request mrq; | ||
| 196 | struct mmc_command appcmd; | ||
| 197 | |||
| 198 | int i, err; | ||
| 199 | |||
| 200 | BUG_ON(host->card_busy == NULL); | ||
| 201 | BUG_ON(retries < 0); | ||
| 202 | |||
| 203 | err = MMC_ERR_INVALID; | ||
| 204 | |||
| 205 | /* | ||
| 206 | * We have to resend MMC_APP_CMD for each attempt so | ||
| 207 | * we cannot use the retries field in mmc_command. | ||
| 208 | */ | ||
| 209 | for (i = 0;i <= retries;i++) { | ||
| 210 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
| 211 | |||
| 212 | appcmd.opcode = MMC_APP_CMD; | ||
| 213 | appcmd.arg = rca << 16; | ||
| 214 | appcmd.flags = MMC_RSP_R1; | ||
| 215 | appcmd.retries = 0; | ||
| 216 | memset(appcmd.resp, 0, sizeof(appcmd.resp)); | ||
| 217 | appcmd.data = NULL; | ||
| 218 | |||
| 219 | mrq.cmd = &appcmd; | ||
| 220 | appcmd.data = NULL; | ||
| 221 | |||
| 222 | mmc_wait_for_req(host, &mrq); | ||
| 223 | |||
| 224 | if (appcmd.error) { | ||
| 225 | err = appcmd.error; | ||
| 226 | continue; | ||
| 227 | } | ||
| 228 | |||
| 229 | /* Check that card supported application commands */ | ||
| 230 | if (!(appcmd.resp[0] & R1_APP_CMD)) | ||
| 231 | return MMC_ERR_FAILED; | ||
| 232 | |||
| 233 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
| 234 | |||
| 235 | memset(cmd->resp, 0, sizeof(cmd->resp)); | ||
| 236 | cmd->retries = 0; | ||
| 237 | |||
| 238 | mrq.cmd = cmd; | ||
| 239 | cmd->data = NULL; | ||
| 175 | 240 | ||
| 241 | mmc_wait_for_req(host, &mrq); | ||
| 242 | |||
| 243 | err = cmd->error; | ||
| 244 | if (cmd->error == MMC_ERR_NONE) | ||
| 245 | break; | ||
| 246 | } | ||
| 247 | |||
| 248 | return err; | ||
| 249 | } | ||
| 250 | |||
| 251 | EXPORT_SYMBOL(mmc_wait_for_app_cmd); | ||
| 252 | |||
| 253 | static int mmc_select_card(struct mmc_host *host, struct mmc_card *card); | ||
| 176 | 254 | ||
| 177 | /** | 255 | /** |
| 178 | * __mmc_claim_host - exclusively claim a host | 256 | * __mmc_claim_host - exclusively claim a host |
| @@ -206,16 +284,10 @@ int __mmc_claim_host(struct mmc_host *host, struct mmc_card *card) | |||
| 206 | spin_unlock_irqrestore(&host->lock, flags); | 284 | spin_unlock_irqrestore(&host->lock, flags); |
| 207 | remove_wait_queue(&host->wq, &wait); | 285 | remove_wait_queue(&host->wq, &wait); |
| 208 | 286 | ||
| 209 | if (card != (void *)-1 && host->card_selected != card) { | 287 | if (card != (void *)-1) { |
| 210 | struct mmc_command cmd; | 288 | err = mmc_select_card(host, card); |
| 211 | 289 | if (err != MMC_ERR_NONE) | |
| 212 | host->card_selected = card; | 290 | return err; |
| 213 | |||
| 214 | cmd.opcode = MMC_SELECT_CARD; | ||
| 215 | cmd.arg = card->rca << 16; | ||
| 216 | cmd.flags = MMC_RSP_R1; | ||
| 217 | |||
| 218 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | ||
| 219 | } | 291 | } |
| 220 | 292 | ||
| 221 | return err; | 293 | return err; |
| @@ -245,6 +317,63 @@ void mmc_release_host(struct mmc_host *host) | |||
| 245 | 317 | ||
| 246 | EXPORT_SYMBOL(mmc_release_host); | 318 | EXPORT_SYMBOL(mmc_release_host); |
| 247 | 319 | ||
| 320 | static int mmc_select_card(struct mmc_host *host, struct mmc_card *card) | ||
| 321 | { | ||
| 322 | int err; | ||
| 323 | struct mmc_command cmd; | ||
| 324 | |||
| 325 | BUG_ON(host->card_busy == NULL); | ||
| 326 | |||
| 327 | if (host->card_selected == card) | ||
| 328 | return MMC_ERR_NONE; | ||
| 329 | |||
| 330 | host->card_selected = card; | ||
| 331 | |||
| 332 | cmd.opcode = MMC_SELECT_CARD; | ||
| 333 | cmd.arg = card->rca << 16; | ||
| 334 | cmd.flags = MMC_RSP_R1; | ||
| 335 | |||
| 336 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | ||
| 337 | if (err != MMC_ERR_NONE) | ||
| 338 | return err; | ||
| 339 | |||
| 340 | /* | ||
| 341 | * Default bus width is 1 bit. | ||
| 342 | */ | ||
| 343 | host->ios.bus_width = MMC_BUS_WIDTH_1; | ||
| 344 | |||
| 345 | /* | ||
| 346 | * We can only change the bus width of the selected | ||
| 347 | * card so therefore we have to put the handling | ||
| 348 | * here. | ||
| 349 | */ | ||
| 350 | if (host->caps & MMC_CAP_4_BIT_DATA) { | ||
| 351 | /* | ||
| 352 | * The card is in 1 bit mode by default so | ||
| 353 | * we only need to change if it supports the | ||
| 354 | * wider version. | ||
| 355 | */ | ||
| 356 | if (mmc_card_sd(card) && | ||
| 357 | (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { | ||
| 358 | struct mmc_command cmd; | ||
| 359 | cmd.opcode = SD_APP_SET_BUS_WIDTH; | ||
| 360 | cmd.arg = SD_BUS_WIDTH_4; | ||
| 361 | cmd.flags = MMC_RSP_R1; | ||
| 362 | |||
| 363 | err = mmc_wait_for_app_cmd(host, card->rca, &cmd, | ||
| 364 | CMD_RETRIES); | ||
| 365 | if (err != MMC_ERR_NONE) | ||
| 366 | return err; | ||
| 367 | |||
| 368 | host->ios.bus_width = MMC_BUS_WIDTH_4; | ||
| 369 | } | ||
| 370 | } | ||
| 371 | |||
| 372 | host->ops->set_ios(host, &host->ios); | ||
| 373 | |||
| 374 | return MMC_ERR_NONE; | ||
| 375 | } | ||
| 376 | |||
| 248 | /* | 377 | /* |
| 249 | * Ensure that no card is selected. | 378 | * Ensure that no card is selected. |
| 250 | */ | 379 | */ |
| @@ -322,48 +451,69 @@ static void mmc_decode_cid(struct mmc_card *card) | |||
| 322 | 451 | ||
| 323 | memset(&card->cid, 0, sizeof(struct mmc_cid)); | 452 | memset(&card->cid, 0, sizeof(struct mmc_cid)); |
| 324 | 453 | ||
| 325 | /* | 454 | if (mmc_card_sd(card)) { |
| 326 | * The selection of the format here is guesswork based upon | 455 | /* |
| 327 | * information people have sent to date. | 456 | * SD doesn't currently have a version field so we will |
| 328 | */ | 457 | * have to assume we can parse this. |
| 329 | switch (card->csd.mmca_vsn) { | 458 | */ |
| 330 | case 0: /* MMC v1.? */ | 459 | card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); |
| 331 | case 1: /* MMC v1.4 */ | 460 | card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); |
| 332 | card->cid.manfid = UNSTUFF_BITS(resp, 104, 24); | 461 | card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); |
| 333 | card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); | 462 | card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); |
| 334 | card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); | 463 | card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); |
| 335 | card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); | 464 | card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); |
| 336 | card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); | 465 | card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); |
| 337 | card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); | 466 | card->cid.hwrev = UNSTUFF_BITS(resp, 60, 4); |
| 338 | card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8); | 467 | card->cid.fwrev = UNSTUFF_BITS(resp, 56, 4); |
| 339 | card->cid.prod_name[6] = UNSTUFF_BITS(resp, 48, 8); | 468 | card->cid.serial = UNSTUFF_BITS(resp, 24, 32); |
| 340 | card->cid.hwrev = UNSTUFF_BITS(resp, 44, 4); | 469 | card->cid.year = UNSTUFF_BITS(resp, 12, 8); |
| 341 | card->cid.fwrev = UNSTUFF_BITS(resp, 40, 4); | 470 | card->cid.month = UNSTUFF_BITS(resp, 8, 4); |
| 342 | card->cid.serial = UNSTUFF_BITS(resp, 16, 24); | 471 | |
| 343 | card->cid.month = UNSTUFF_BITS(resp, 12, 4); | 472 | card->cid.year += 2000; /* SD cards year offset */ |
| 344 | card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997; | 473 | } else { |
| 345 | break; | 474 | /* |
| 346 | 475 | * The selection of the format here is based upon published | |
| 347 | case 2: /* MMC v2.x ? */ | 476 | * specs from sandisk and from what people have reported. |
| 348 | case 3: /* MMC v3.x ? */ | 477 | */ |
| 349 | card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); | 478 | switch (card->csd.mmca_vsn) { |
| 350 | card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); | 479 | case 0: /* MMC v1.0 - v1.2 */ |
| 351 | card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); | 480 | case 1: /* MMC v1.4 */ |
| 352 | card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); | 481 | card->cid.manfid = UNSTUFF_BITS(resp, 104, 24); |
| 353 | card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); | 482 | card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); |
| 354 | card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); | 483 | card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); |
| 355 | card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); | 484 | card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); |
| 356 | card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8); | 485 | card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); |
| 357 | card->cid.serial = UNSTUFF_BITS(resp, 16, 32); | 486 | card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); |
| 358 | card->cid.month = UNSTUFF_BITS(resp, 12, 4); | 487 | card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8); |
| 359 | card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997; | 488 | card->cid.prod_name[6] = UNSTUFF_BITS(resp, 48, 8); |
| 360 | break; | 489 | card->cid.hwrev = UNSTUFF_BITS(resp, 44, 4); |
| 361 | 490 | card->cid.fwrev = UNSTUFF_BITS(resp, 40, 4); | |
| 362 | default: | 491 | card->cid.serial = UNSTUFF_BITS(resp, 16, 24); |
| 363 | printk("%s: card has unknown MMCA version %d\n", | 492 | card->cid.month = UNSTUFF_BITS(resp, 12, 4); |
| 364 | mmc_hostname(card->host), card->csd.mmca_vsn); | 493 | card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997; |
| 365 | mmc_card_set_bad(card); | 494 | break; |
| 366 | break; | 495 | |
| 496 | case 2: /* MMC v2.0 - v2.2 */ | ||
| 497 | case 3: /* MMC v3.1 - v3.3 */ | ||
| 498 | card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); | ||
| 499 | card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); | ||
| 500 | card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); | ||
| 501 | card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); | ||
| 502 | card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); | ||
| 503 | card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); | ||
| 504 | card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); | ||
| 505 | card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8); | ||
| 506 | card->cid.serial = UNSTUFF_BITS(resp, 16, 32); | ||
| 507 | card->cid.month = UNSTUFF_BITS(resp, 12, 4); | ||
| 508 | card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997; | ||
| 509 | break; | ||
| 510 | |||
| 511 | default: | ||
| 512 | printk("%s: card has unknown MMCA version %d\n", | ||
| 513 | mmc_hostname(card->host), card->csd.mmca_vsn); | ||
| 514 | mmc_card_set_bad(card); | ||
| 515 | break; | ||
| 516 | } | ||
| 367 | } | 517 | } |
| 368 | } | 518 | } |
| 369 | 519 | ||
| @@ -376,34 +526,86 @@ static void mmc_decode_csd(struct mmc_card *card) | |||
| 376 | unsigned int e, m, csd_struct; | 526 | unsigned int e, m, csd_struct; |
| 377 | u32 *resp = card->raw_csd; | 527 | u32 *resp = card->raw_csd; |
| 378 | 528 | ||
| 379 | /* | 529 | if (mmc_card_sd(card)) { |
| 380 | * We only understand CSD structure v1.1 and v2. | 530 | csd_struct = UNSTUFF_BITS(resp, 126, 2); |
| 381 | * v2 has extra information in bits 15, 11 and 10. | 531 | if (csd_struct != 0) { |
| 382 | */ | 532 | printk("%s: unrecognised CSD structure version %d\n", |
| 383 | csd_struct = UNSTUFF_BITS(resp, 126, 2); | 533 | mmc_hostname(card->host), csd_struct); |
| 384 | if (csd_struct != 1 && csd_struct != 2) { | 534 | mmc_card_set_bad(card); |
| 385 | printk("%s: unrecognised CSD structure version %d\n", | 535 | return; |
| 386 | mmc_hostname(card->host), csd_struct); | 536 | } |
| 387 | mmc_card_set_bad(card); | 537 | |
| 388 | return; | 538 | m = UNSTUFF_BITS(resp, 115, 4); |
| 539 | e = UNSTUFF_BITS(resp, 112, 3); | ||
| 540 | csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10; | ||
| 541 | csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100; | ||
| 542 | |||
| 543 | m = UNSTUFF_BITS(resp, 99, 4); | ||
| 544 | e = UNSTUFF_BITS(resp, 96, 3); | ||
| 545 | csd->max_dtr = tran_exp[e] * tran_mant[m]; | ||
| 546 | csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); | ||
| 547 | |||
| 548 | e = UNSTUFF_BITS(resp, 47, 3); | ||
| 549 | m = UNSTUFF_BITS(resp, 62, 12); | ||
| 550 | csd->capacity = (1 + m) << (e + 2); | ||
| 551 | |||
| 552 | csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); | ||
| 553 | } else { | ||
| 554 | /* | ||
| 555 | * We only understand CSD structure v1.1 and v1.2. | ||
| 556 | * v1.2 has extra information in bits 15, 11 and 10. | ||
| 557 | */ | ||
| 558 | csd_struct = UNSTUFF_BITS(resp, 126, 2); | ||
| 559 | if (csd_struct != 1 && csd_struct != 2) { | ||
| 560 | printk("%s: unrecognised CSD structure version %d\n", | ||
| 561 | mmc_hostname(card->host), csd_struct); | ||
| 562 | mmc_card_set_bad(card); | ||
| 563 | return; | ||
| 564 | } | ||
| 565 | |||
| 566 | csd->mmca_vsn = UNSTUFF_BITS(resp, 122, 4); | ||
| 567 | m = UNSTUFF_BITS(resp, 115, 4); | ||
| 568 | e = UNSTUFF_BITS(resp, 112, 3); | ||
| 569 | csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10; | ||
| 570 | csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100; | ||
| 571 | |||
| 572 | m = UNSTUFF_BITS(resp, 99, 4); | ||
| 573 | e = UNSTUFF_BITS(resp, 96, 3); | ||
| 574 | csd->max_dtr = tran_exp[e] * tran_mant[m]; | ||
| 575 | csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); | ||
| 576 | |||
| 577 | e = UNSTUFF_BITS(resp, 47, 3); | ||
| 578 | m = UNSTUFF_BITS(resp, 62, 12); | ||
| 579 | csd->capacity = (1 + m) << (e + 2); | ||
| 580 | |||
| 581 | csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); | ||
| 389 | } | 582 | } |
| 583 | } | ||
| 390 | 584 | ||
| 391 | csd->mmca_vsn = UNSTUFF_BITS(resp, 122, 4); | 585 | /* |
| 392 | m = UNSTUFF_BITS(resp, 115, 4); | 586 | * Given a 64-bit response, decode to our card SCR structure. |
| 393 | e = UNSTUFF_BITS(resp, 112, 3); | 587 | */ |
| 394 | csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10; | 588 | static void mmc_decode_scr(struct mmc_card *card) |
| 395 | csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100; | 589 | { |
| 590 | struct sd_scr *scr = &card->scr; | ||
| 591 | unsigned int scr_struct; | ||
| 592 | u32 resp[4]; | ||
| 593 | |||
| 594 | BUG_ON(!mmc_card_sd(card)); | ||
| 396 | 595 | ||
| 397 | m = UNSTUFF_BITS(resp, 99, 4); | 596 | resp[3] = card->raw_scr[1]; |
| 398 | e = UNSTUFF_BITS(resp, 96, 3); | 597 | resp[2] = card->raw_scr[0]; |
| 399 | csd->max_dtr = tran_exp[e] * tran_mant[m]; | ||
| 400 | csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); | ||
| 401 | 598 | ||
| 402 | e = UNSTUFF_BITS(resp, 47, 3); | 599 | scr_struct = UNSTUFF_BITS(resp, 60, 4); |
| 403 | m = UNSTUFF_BITS(resp, 62, 12); | 600 | if (scr_struct != 0) { |
| 404 | csd->capacity = (1 + m) << (e + 2); | 601 | printk("%s: unrecognised SCR structure version %d\n", |
| 602 | mmc_hostname(card->host), scr_struct); | ||
| 603 | mmc_card_set_bad(card); | ||
| 604 | return; | ||
| 605 | } | ||
| 405 | 606 | ||
| 406 | csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); | 607 | scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4); |
| 608 | scr->bus_widths = UNSTUFF_BITS(resp, 48, 4); | ||
| 407 | } | 609 | } |
| 408 | 610 | ||
| 409 | /* | 611 | /* |
| @@ -487,6 +689,7 @@ static void mmc_power_up(struct mmc_host *host) | |||
| 487 | host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; | 689 | host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; |
| 488 | host->ios.chip_select = MMC_CS_DONTCARE; | 690 | host->ios.chip_select = MMC_CS_DONTCARE; |
| 489 | host->ios.power_mode = MMC_POWER_UP; | 691 | host->ios.power_mode = MMC_POWER_UP; |
| 692 | host->ios.bus_width = MMC_BUS_WIDTH_1; | ||
| 490 | host->ops->set_ios(host, &host->ios); | 693 | host->ops->set_ios(host, &host->ios); |
| 491 | 694 | ||
| 492 | mmc_delay(1); | 695 | mmc_delay(1); |
| @@ -505,6 +708,7 @@ static void mmc_power_off(struct mmc_host *host) | |||
| 505 | host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; | 708 | host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; |
| 506 | host->ios.chip_select = MMC_CS_DONTCARE; | 709 | host->ios.chip_select = MMC_CS_DONTCARE; |
| 507 | host->ios.power_mode = MMC_POWER_OFF; | 710 | host->ios.power_mode = MMC_POWER_OFF; |
| 711 | host->ios.bus_width = MMC_BUS_WIDTH_1; | ||
| 508 | host->ops->set_ios(host, &host->ios); | 712 | host->ops->set_ios(host, &host->ios); |
| 509 | } | 713 | } |
| 510 | 714 | ||
| @@ -536,6 +740,34 @@ static int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | |||
| 536 | return err; | 740 | return err; |
| 537 | } | 741 | } |
| 538 | 742 | ||
| 743 | static int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | ||
| 744 | { | ||
| 745 | struct mmc_command cmd; | ||
| 746 | int i, err = 0; | ||
| 747 | |||
| 748 | cmd.opcode = SD_APP_OP_COND; | ||
| 749 | cmd.arg = ocr; | ||
| 750 | cmd.flags = MMC_RSP_R3; | ||
| 751 | |||
| 752 | for (i = 100; i; i--) { | ||
| 753 | err = mmc_wait_for_app_cmd(host, 0, &cmd, CMD_RETRIES); | ||
| 754 | if (err != MMC_ERR_NONE) | ||
| 755 | break; | ||
| 756 | |||
| 757 | if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) | ||
| 758 | break; | ||
| 759 | |||
| 760 | err = MMC_ERR_TIMEOUT; | ||
| 761 | |||
| 762 | mmc_delay(10); | ||
| 763 | } | ||
| 764 | |||
| 765 | if (rocr) | ||
| 766 | *rocr = cmd.resp[0]; | ||
| 767 | |||
| 768 | return err; | ||
| 769 | } | ||
| 770 | |||
| 539 | /* | 771 | /* |
| 540 | * Discover cards by requesting their CID. If this command | 772 | * Discover cards by requesting their CID. If this command |
| 541 | * times out, it is not an error; there are no further cards | 773 | * times out, it is not an error; there are no further cards |
| @@ -579,13 +811,38 @@ static void mmc_discover_cards(struct mmc_host *host) | |||
| 579 | 811 | ||
| 580 | card->state &= ~MMC_STATE_DEAD; | 812 | card->state &= ~MMC_STATE_DEAD; |
| 581 | 813 | ||
| 582 | cmd.opcode = MMC_SET_RELATIVE_ADDR; | 814 | if (host->mode == MMC_MODE_SD) { |
| 583 | cmd.arg = card->rca << 16; | 815 | mmc_card_set_sd(card); |
| 584 | cmd.flags = MMC_RSP_R1; | ||
| 585 | 816 | ||
| 586 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | 817 | cmd.opcode = SD_SEND_RELATIVE_ADDR; |
| 587 | if (err != MMC_ERR_NONE) | 818 | cmd.arg = 0; |
| 588 | mmc_card_set_dead(card); | 819 | cmd.flags = MMC_RSP_R1; |
| 820 | |||
| 821 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | ||
| 822 | if (err != MMC_ERR_NONE) | ||
| 823 | mmc_card_set_dead(card); | ||
| 824 | else { | ||
| 825 | card->rca = cmd.resp[0] >> 16; | ||
| 826 | |||
| 827 | if (!host->ops->get_ro) { | ||
| 828 | printk(KERN_WARNING "%s: host does not " | ||
| 829 | "support reading read-only " | ||
| 830 | "switch. assuming write-enable.\n", | ||
| 831 | mmc_hostname(host)); | ||
| 832 | } else { | ||
| 833 | if (host->ops->get_ro(host)) | ||
| 834 | mmc_card_set_readonly(card); | ||
| 835 | } | ||
| 836 | } | ||
| 837 | } else { | ||
| 838 | cmd.opcode = MMC_SET_RELATIVE_ADDR; | ||
| 839 | cmd.arg = card->rca << 16; | ||
| 840 | cmd.flags = MMC_RSP_R1; | ||
| 841 | |||
| 842 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | ||
| 843 | if (err != MMC_ERR_NONE) | ||
| 844 | mmc_card_set_dead(card); | ||
| 845 | } | ||
| 589 | } | 846 | } |
| 590 | } | 847 | } |
| 591 | 848 | ||
| @@ -617,6 +874,79 @@ static void mmc_read_csds(struct mmc_host *host) | |||
| 617 | } | 874 | } |
| 618 | } | 875 | } |
| 619 | 876 | ||
| 877 | static void mmc_read_scrs(struct mmc_host *host) | ||
| 878 | { | ||
| 879 | int err; | ||
| 880 | struct mmc_card *card; | ||
| 881 | |||
| 882 | struct mmc_request mrq; | ||
| 883 | struct mmc_command cmd; | ||
| 884 | struct mmc_data data; | ||
| 885 | |||
| 886 | struct scatterlist sg; | ||
| 887 | |||
| 888 | list_for_each_entry(card, &host->cards, node) { | ||
| 889 | if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT)) | ||
| 890 | continue; | ||
| 891 | if (!mmc_card_sd(card)) | ||
| 892 | continue; | ||
| 893 | |||
| 894 | err = mmc_select_card(host, card); | ||
| 895 | if (err != MMC_ERR_NONE) { | ||
| 896 | mmc_card_set_dead(card); | ||
| 897 | continue; | ||
| 898 | } | ||
| 899 | |||
| 900 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 901 | |||
| 902 | cmd.opcode = MMC_APP_CMD; | ||
| 903 | cmd.arg = card->rca << 16; | ||
| 904 | cmd.flags = MMC_RSP_R1; | ||
| 905 | |||
| 906 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
| 907 | if ((err != MMC_ERR_NONE) || !(cmd.resp[0] & R1_APP_CMD)) { | ||
| 908 | mmc_card_set_dead(card); | ||
| 909 | continue; | ||
| 910 | } | ||
| 911 | |||
| 912 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 913 | |||
| 914 | cmd.opcode = SD_APP_SEND_SCR; | ||
| 915 | cmd.arg = 0; | ||
| 916 | cmd.flags = MMC_RSP_R1; | ||
| 917 | |||
| 918 | memset(&data, 0, sizeof(struct mmc_data)); | ||
| 919 | |||
| 920 | data.timeout_ns = card->csd.tacc_ns * 10; | ||
| 921 | data.timeout_clks = card->csd.tacc_clks * 10; | ||
| 922 | data.blksz_bits = 3; | ||
| 923 | data.blocks = 1; | ||
| 924 | data.flags = MMC_DATA_READ; | ||
| 925 | data.sg = &sg; | ||
| 926 | data.sg_len = 1; | ||
| 927 | |||
| 928 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
| 929 | |||
| 930 | mrq.cmd = &cmd; | ||
| 931 | mrq.data = &data; | ||
| 932 | |||
| 933 | sg_init_one(&sg, (u8*)card->raw_scr, 8); | ||
| 934 | |||
| 935 | err = mmc_wait_for_req(host, &mrq); | ||
| 936 | if (err != MMC_ERR_NONE) { | ||
| 937 | mmc_card_set_dead(card); | ||
| 938 | continue; | ||
| 939 | } | ||
| 940 | |||
| 941 | card->raw_scr[0] = ntohl(card->raw_scr[0]); | ||
| 942 | card->raw_scr[1] = ntohl(card->raw_scr[1]); | ||
| 943 | |||
| 944 | mmc_decode_scr(card); | ||
| 945 | } | ||
| 946 | |||
| 947 | mmc_deselect_cards(host); | ||
| 948 | } | ||
| 949 | |||
| 620 | static unsigned int mmc_calculate_clock(struct mmc_host *host) | 950 | static unsigned int mmc_calculate_clock(struct mmc_host *host) |
| 621 | { | 951 | { |
| 622 | struct mmc_card *card; | 952 | struct mmc_card *card; |
| @@ -669,12 +999,24 @@ static void mmc_setup(struct mmc_host *host) | |||
| 669 | int err; | 999 | int err; |
| 670 | u32 ocr; | 1000 | u32 ocr; |
| 671 | 1001 | ||
| 1002 | host->mode = MMC_MODE_SD; | ||
| 1003 | |||
| 672 | mmc_power_up(host); | 1004 | mmc_power_up(host); |
| 673 | mmc_idle_cards(host); | 1005 | mmc_idle_cards(host); |
| 674 | 1006 | ||
| 675 | err = mmc_send_op_cond(host, 0, &ocr); | 1007 | err = mmc_send_app_op_cond(host, 0, &ocr); |
| 676 | if (err != MMC_ERR_NONE) | 1008 | |
| 677 | return; | 1009 | /* |
| 1010 | * If we fail to detect any SD cards then try | ||
| 1011 | * searching for MMC cards. | ||
| 1012 | */ | ||
| 1013 | if (err != MMC_ERR_NONE) { | ||
| 1014 | host->mode = MMC_MODE_MMC; | ||
| 1015 | |||
| 1016 | err = mmc_send_op_cond(host, 0, &ocr); | ||
| 1017 | if (err != MMC_ERR_NONE) | ||
| 1018 | return; | ||
| 1019 | } | ||
| 678 | 1020 | ||
| 679 | host->ocr = mmc_select_voltage(host, ocr); | 1021 | host->ocr = mmc_select_voltage(host, ocr); |
| 680 | 1022 | ||
| @@ -714,7 +1056,10 @@ static void mmc_setup(struct mmc_host *host) | |||
| 714 | * all get the idea that they should be ready for CMD2. | 1056 | * all get the idea that they should be ready for CMD2. |
| 715 | * (My SanDisk card seems to need this.) | 1057 | * (My SanDisk card seems to need this.) |
| 716 | */ | 1058 | */ |
| 717 | mmc_send_op_cond(host, host->ocr, NULL); | 1059 | if (host->mode == MMC_MODE_SD) |
| 1060 | mmc_send_app_op_cond(host, host->ocr, NULL); | ||
| 1061 | else | ||
| 1062 | mmc_send_op_cond(host, host->ocr, NULL); | ||
| 718 | 1063 | ||
| 719 | mmc_discover_cards(host); | 1064 | mmc_discover_cards(host); |
| 720 | 1065 | ||
| @@ -725,19 +1070,26 @@ static void mmc_setup(struct mmc_host *host) | |||
| 725 | host->ops->set_ios(host, &host->ios); | 1070 | host->ops->set_ios(host, &host->ios); |
| 726 | 1071 | ||
| 727 | mmc_read_csds(host); | 1072 | mmc_read_csds(host); |
| 1073 | |||
| 1074 | if (host->mode == MMC_MODE_SD) | ||
| 1075 | mmc_read_scrs(host); | ||
| 728 | } | 1076 | } |
| 729 | 1077 | ||
| 730 | 1078 | ||
| 731 | /** | 1079 | /** |
| 732 | * mmc_detect_change - process change of state on a MMC socket | 1080 | * mmc_detect_change - process change of state on a MMC socket |
| 733 | * @host: host which changed state. | 1081 | * @host: host which changed state. |
| 1082 | * @delay: optional delay to wait before detection (jiffies) | ||
| 734 | * | 1083 | * |
| 735 | * All we know is that card(s) have been inserted or removed | 1084 | * All we know is that card(s) have been inserted or removed |
| 736 | * from the socket(s). We don't know which socket or cards. | 1085 | * from the socket(s). We don't know which socket or cards. |
| 737 | */ | 1086 | */ |
| 738 | void mmc_detect_change(struct mmc_host *host) | 1087 | void mmc_detect_change(struct mmc_host *host, unsigned long delay) |
| 739 | { | 1088 | { |
| 740 | schedule_work(&host->detect); | 1089 | if (delay) |
| 1090 | schedule_delayed_work(&host->detect, delay); | ||
| 1091 | else | ||
| 1092 | schedule_work(&host->detect); | ||
| 741 | } | 1093 | } |
| 742 | 1094 | ||
| 743 | EXPORT_SYMBOL(mmc_detect_change); | 1095 | EXPORT_SYMBOL(mmc_detect_change); |
| @@ -841,7 +1193,7 @@ int mmc_add_host(struct mmc_host *host) | |||
| 841 | ret = mmc_add_host_sysfs(host); | 1193 | ret = mmc_add_host_sysfs(host); |
| 842 | if (ret == 0) { | 1194 | if (ret == 0) { |
| 843 | mmc_power_off(host); | 1195 | mmc_power_off(host); |
| 844 | mmc_detect_change(host); | 1196 | mmc_detect_change(host, 0); |
| 845 | } | 1197 | } |
| 846 | 1198 | ||
| 847 | return ret; | 1199 | return ret; |
| @@ -911,7 +1263,7 @@ EXPORT_SYMBOL(mmc_suspend_host); | |||
| 911 | */ | 1263 | */ |
| 912 | int mmc_resume_host(struct mmc_host *host) | 1264 | int mmc_resume_host(struct mmc_host *host) |
| 913 | { | 1265 | { |
| 914 | mmc_detect_change(host); | 1266 | mmc_detect_change(host, 0); |
| 915 | 1267 | ||
| 916 | return 0; | 1268 | return 0; |
| 917 | } | 1269 | } |
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c index d4eee99c2bf6..fa83f15fdf16 100644 --- a/drivers/mmc/mmc_block.c +++ b/drivers/mmc/mmc_block.c | |||
| @@ -95,6 +95,10 @@ static int mmc_blk_open(struct inode *inode, struct file *filp) | |||
| 95 | if (md->usage == 2) | 95 | if (md->usage == 2) |
| 96 | check_disk_change(inode->i_bdev); | 96 | check_disk_change(inode->i_bdev); |
| 97 | ret = 0; | 97 | ret = 0; |
| 98 | |||
| 99 | if ((filp->f_mode & FMODE_WRITE) && | ||
| 100 | mmc_card_readonly(md->queue.card)) | ||
| 101 | ret = -EROFS; | ||
| 98 | } | 102 | } |
| 99 | 103 | ||
| 100 | return ret; | 104 | return ret; |
| @@ -403,9 +407,10 @@ static int mmc_blk_probe(struct mmc_card *card) | |||
| 403 | if (err) | 407 | if (err) |
| 404 | goto out; | 408 | goto out; |
| 405 | 409 | ||
| 406 | printk(KERN_INFO "%s: %s %s %dKiB\n", | 410 | printk(KERN_INFO "%s: %s %s %dKiB %s\n", |
| 407 | md->disk->disk_name, mmc_card_id(card), mmc_card_name(card), | 411 | md->disk->disk_name, mmc_card_id(card), mmc_card_name(card), |
| 408 | (card->csd.capacity << card->csd.read_blkbits) / 1024); | 412 | (card->csd.capacity << card->csd.read_blkbits) / 1024, |
| 413 | mmc_card_readonly(card)?"(ro)":""); | ||
| 409 | 414 | ||
| 410 | mmc_set_drvdata(card, md); | 415 | mmc_set_drvdata(card, md); |
| 411 | add_disk(md->disk); | 416 | add_disk(md->disk); |
diff --git a/drivers/mmc/mmc_sysfs.c b/drivers/mmc/mmc_sysfs.c index ad8949810fc5..3f4a66ca9555 100644 --- a/drivers/mmc/mmc_sysfs.c +++ b/drivers/mmc/mmc_sysfs.c | |||
| @@ -34,6 +34,7 @@ MMC_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1], | |||
| 34 | card->raw_cid[2], card->raw_cid[3]); | 34 | card->raw_cid[2], card->raw_cid[3]); |
| 35 | MMC_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1], | 35 | MMC_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1], |
| 36 | card->raw_csd[2], card->raw_csd[3]); | 36 | card->raw_csd[2], card->raw_csd[3]); |
| 37 | MMC_ATTR(scr, "%08x%08x\n", card->raw_scr[0], card->raw_scr[1]); | ||
| 37 | MMC_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year); | 38 | MMC_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year); |
| 38 | MMC_ATTR(fwrev, "0x%x\n", card->cid.fwrev); | 39 | MMC_ATTR(fwrev, "0x%x\n", card->cid.fwrev); |
| 39 | MMC_ATTR(hwrev, "0x%x\n", card->cid.hwrev); | 40 | MMC_ATTR(hwrev, "0x%x\n", card->cid.hwrev); |
| @@ -57,6 +58,8 @@ static struct device_attribute mmc_dev_attrs[] = { | |||
| 57 | __ATTR_NULL | 58 | __ATTR_NULL |
| 58 | }; | 59 | }; |
| 59 | 60 | ||
| 61 | static struct device_attribute mmc_dev_attr_scr = MMC_ATTR_RO(scr); | ||
| 62 | |||
| 60 | 63 | ||
| 61 | static void mmc_release_card(struct device *dev) | 64 | static void mmc_release_card(struct device *dev) |
| 62 | { | 65 | { |
| @@ -207,10 +210,20 @@ void mmc_init_card(struct mmc_card *card, struct mmc_host *host) | |||
| 207 | */ | 210 | */ |
| 208 | int mmc_register_card(struct mmc_card *card) | 211 | int mmc_register_card(struct mmc_card *card) |
| 209 | { | 212 | { |
| 213 | int ret; | ||
| 214 | |||
| 210 | snprintf(card->dev.bus_id, sizeof(card->dev.bus_id), | 215 | snprintf(card->dev.bus_id, sizeof(card->dev.bus_id), |
| 211 | "%s:%04x", mmc_hostname(card->host), card->rca); | 216 | "%s:%04x", mmc_hostname(card->host), card->rca); |
| 212 | 217 | ||
| 213 | return device_add(&card->dev); | 218 | ret = device_add(&card->dev); |
| 219 | if (ret == 0) { | ||
| 220 | if (mmc_card_sd(card)) { | ||
| 221 | ret = device_create_file(&card->dev, &mmc_dev_attr_scr); | ||
| 222 | if (ret) | ||
| 223 | device_del(&card->dev); | ||
| 224 | } | ||
| 225 | } | ||
| 226 | return ret; | ||
| 214 | } | 227 | } |
| 215 | 228 | ||
| 216 | /* | 229 | /* |
| @@ -219,8 +232,12 @@ int mmc_register_card(struct mmc_card *card) | |||
| 219 | */ | 232 | */ |
| 220 | void mmc_remove_card(struct mmc_card *card) | 233 | void mmc_remove_card(struct mmc_card *card) |
| 221 | { | 234 | { |
| 222 | if (mmc_card_present(card)) | 235 | if (mmc_card_present(card)) { |
| 236 | if (mmc_card_sd(card)) | ||
| 237 | device_remove_file(&card->dev, &mmc_dev_attr_scr); | ||
| 238 | |||
| 223 | device_del(&card->dev); | 239 | device_del(&card->dev); |
| 240 | } | ||
| 224 | 241 | ||
| 225 | put_device(&card->dev); | 242 | put_device(&card->dev); |
| 226 | } | 243 | } |
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c index 716c4ef4faf6..91c74843dc0d 100644 --- a/drivers/mmc/mmci.c +++ b/drivers/mmc/mmci.c | |||
| @@ -442,7 +442,7 @@ static void mmci_check_status(unsigned long data) | |||
| 442 | 442 | ||
| 443 | status = host->plat->status(mmc_dev(host->mmc)); | 443 | status = host->plat->status(mmc_dev(host->mmc)); |
| 444 | if (status ^ host->oldstat) | 444 | if (status ^ host->oldstat) |
| 445 | mmc_detect_change(host->mmc); | 445 | mmc_detect_change(host->mmc, 0); |
| 446 | 446 | ||
| 447 | host->oldstat = status; | 447 | host->oldstat = status; |
| 448 | mod_timer(&host->timer, jiffies + HZ); | 448 | mod_timer(&host->timer, jiffies + HZ); |
diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c index b78beb1b0159..b53af57074e3 100644 --- a/drivers/mmc/pxamci.c +++ b/drivers/mmc/pxamci.c | |||
| @@ -362,6 +362,16 @@ static void pxamci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 362 | pxamci_start_cmd(host, mrq->cmd, cmdat); | 362 | pxamci_start_cmd(host, mrq->cmd, cmdat); |
| 363 | } | 363 | } |
| 364 | 364 | ||
| 365 | static int pxamci_get_ro(struct mmc_host *mmc) | ||
| 366 | { | ||
| 367 | struct pxamci_host *host = mmc_priv(mmc); | ||
| 368 | |||
| 369 | if (host->pdata && host->pdata->get_ro) | ||
| 370 | return host->pdata->get_ro(mmc->dev); | ||
| 371 | /* Host doesn't support read only detection so assume writeable */ | ||
| 372 | return 0; | ||
| 373 | } | ||
| 374 | |||
| 365 | static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 375 | static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
| 366 | { | 376 | { |
| 367 | struct pxamci_host *host = mmc_priv(mmc); | 377 | struct pxamci_host *host = mmc_priv(mmc); |
| @@ -401,6 +411,7 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 401 | 411 | ||
| 402 | static struct mmc_host_ops pxamci_ops = { | 412 | static struct mmc_host_ops pxamci_ops = { |
| 403 | .request = pxamci_request, | 413 | .request = pxamci_request, |
| 414 | .get_ro = pxamci_get_ro, | ||
| 404 | .set_ios = pxamci_set_ios, | 415 | .set_ios = pxamci_set_ios, |
| 405 | }; | 416 | }; |
| 406 | 417 | ||
| @@ -412,7 +423,9 @@ static void pxamci_dma_irq(int dma, void *devid, struct pt_regs *regs) | |||
| 412 | 423 | ||
| 413 | static irqreturn_t pxamci_detect_irq(int irq, void *devid, struct pt_regs *regs) | 424 | static irqreturn_t pxamci_detect_irq(int irq, void *devid, struct pt_regs *regs) |
| 414 | { | 425 | { |
| 415 | mmc_detect_change(devid); | 426 | struct pxamci_host *host = mmc_priv(devid); |
| 427 | |||
| 428 | mmc_detect_change(devid, host->pdata->detect_delay); | ||
| 416 | return IRQ_HANDLED; | 429 | return IRQ_HANDLED; |
| 417 | } | 430 | } |
| 418 | 431 | ||
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c index 08ae22aed9e8..e11e55dc8924 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/wbsd.c | |||
| @@ -720,11 +720,28 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data) | |||
| 720 | * calculate CRC. | 720 | * calculate CRC. |
| 721 | * | 721 | * |
| 722 | * Space for CRC must be included in the size. | 722 | * Space for CRC must be included in the size. |
| 723 | * Two bytes are needed for each data line. | ||
| 723 | */ | 724 | */ |
| 724 | blksize = (1 << data->blksz_bits) + 2; | 725 | if (host->bus_width == MMC_BUS_WIDTH_1) |
| 726 | { | ||
| 727 | blksize = (1 << data->blksz_bits) + 2; | ||
| 728 | |||
| 729 | wbsd_write_index(host, WBSD_IDX_PBSMSB, (blksize >> 4) & 0xF0); | ||
| 730 | wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF); | ||
| 731 | } | ||
| 732 | else if (host->bus_width == MMC_BUS_WIDTH_4) | ||
| 733 | { | ||
| 734 | blksize = (1 << data->blksz_bits) + 2 * 4; | ||
| 725 | 735 | ||
| 726 | wbsd_write_index(host, WBSD_IDX_PBSMSB, (blksize >> 4) & 0xF0); | 736 | wbsd_write_index(host, WBSD_IDX_PBSMSB, ((blksize >> 4) & 0xF0) |
| 727 | wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF); | 737 | | WBSD_DATA_WIDTH); |
| 738 | wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF); | ||
| 739 | } | ||
| 740 | else | ||
| 741 | { | ||
| 742 | data->error = MMC_ERR_INVALID; | ||
| 743 | return; | ||
| 744 | } | ||
| 728 | 745 | ||
| 729 | /* | 746 | /* |
| 730 | * Clear the FIFO. This is needed even for DMA | 747 | * Clear the FIFO. This is needed even for DMA |
| @@ -960,9 +977,9 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) | |||
| 960 | struct wbsd_host* host = mmc_priv(mmc); | 977 | struct wbsd_host* host = mmc_priv(mmc); |
| 961 | u8 clk, setup, pwr; | 978 | u8 clk, setup, pwr; |
| 962 | 979 | ||
| 963 | DBGF("clock %uHz busmode %u powermode %u cs %u Vdd %u\n", | 980 | DBGF("clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n", |
| 964 | ios->clock, ios->bus_mode, ios->power_mode, ios->chip_select, | 981 | ios->clock, ios->bus_mode, ios->power_mode, ios->chip_select, |
| 965 | ios->vdd); | 982 | ios->vdd, ios->bus_width); |
| 966 | 983 | ||
| 967 | spin_lock_bh(&host->lock); | 984 | spin_lock_bh(&host->lock); |
| 968 | 985 | ||
| @@ -1010,6 +1027,7 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) | |||
| 1010 | setup = wbsd_read_index(host, WBSD_IDX_SETUP); | 1027 | setup = wbsd_read_index(host, WBSD_IDX_SETUP); |
| 1011 | if (ios->chip_select == MMC_CS_HIGH) | 1028 | if (ios->chip_select == MMC_CS_HIGH) |
| 1012 | { | 1029 | { |
| 1030 | BUG_ON(ios->bus_width != MMC_BUS_WIDTH_1); | ||
| 1013 | setup |= WBSD_DAT3_H; | 1031 | setup |= WBSD_DAT3_H; |
| 1014 | host->flags |= WBSD_FIGNORE_DETECT; | 1032 | host->flags |= WBSD_FIGNORE_DETECT; |
| 1015 | } | 1033 | } |
| @@ -1025,12 +1043,41 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) | |||
| 1025 | } | 1043 | } |
| 1026 | wbsd_write_index(host, WBSD_IDX_SETUP, setup); | 1044 | wbsd_write_index(host, WBSD_IDX_SETUP, setup); |
| 1027 | 1045 | ||
| 1046 | /* | ||
| 1047 | * Store bus width for later. Will be used when | ||
| 1048 | * setting up the data transfer. | ||
| 1049 | */ | ||
| 1050 | host->bus_width = ios->bus_width; | ||
| 1051 | |||
| 1052 | spin_unlock_bh(&host->lock); | ||
| 1053 | } | ||
| 1054 | |||
| 1055 | static int wbsd_get_ro(struct mmc_host* mmc) | ||
| 1056 | { | ||
| 1057 | struct wbsd_host* host = mmc_priv(mmc); | ||
| 1058 | u8 csr; | ||
| 1059 | |||
| 1060 | spin_lock_bh(&host->lock); | ||
| 1061 | |||
| 1062 | csr = inb(host->base + WBSD_CSR); | ||
| 1063 | csr |= WBSD_MSLED; | ||
| 1064 | outb(csr, host->base + WBSD_CSR); | ||
| 1065 | |||
| 1066 | mdelay(1); | ||
| 1067 | |||
| 1068 | csr = inb(host->base + WBSD_CSR); | ||
| 1069 | csr &= ~WBSD_MSLED; | ||
| 1070 | outb(csr, host->base + WBSD_CSR); | ||
| 1071 | |||
| 1028 | spin_unlock_bh(&host->lock); | 1072 | spin_unlock_bh(&host->lock); |
| 1073 | |||
| 1074 | return csr & WBSD_WRPT; | ||
| 1029 | } | 1075 | } |
| 1030 | 1076 | ||
| 1031 | static struct mmc_host_ops wbsd_ops = { | 1077 | static struct mmc_host_ops wbsd_ops = { |
| 1032 | .request = wbsd_request, | 1078 | .request = wbsd_request, |
| 1033 | .set_ios = wbsd_set_ios, | 1079 | .set_ios = wbsd_set_ios, |
| 1080 | .get_ro = wbsd_get_ro, | ||
| 1034 | }; | 1081 | }; |
| 1035 | 1082 | ||
| 1036 | /*****************************************************************************\ | 1083 | /*****************************************************************************\ |
| @@ -1065,20 +1112,6 @@ static void wbsd_reset_ignore(unsigned long data) | |||
| 1065 | } | 1112 | } |
| 1066 | 1113 | ||
| 1067 | /* | 1114 | /* |
| 1068 | * Helper function for card detection | ||
| 1069 | */ | ||
| 1070 | static void wbsd_detect_card(unsigned long data) | ||
| 1071 | { | ||
| 1072 | struct wbsd_host *host = (struct wbsd_host*)data; | ||
| 1073 | |||
| 1074 | BUG_ON(host == NULL); | ||
| 1075 | |||
| 1076 | DBG("Executing card detection\n"); | ||
| 1077 | |||
| 1078 | mmc_detect_change(host->mmc); | ||
| 1079 | } | ||
| 1080 | |||
| 1081 | /* | ||
| 1082 | * Tasklets | 1115 | * Tasklets |
| 1083 | */ | 1116 | */ |
| 1084 | 1117 | ||
| @@ -1122,14 +1155,16 @@ static void wbsd_tasklet_card(unsigned long param) | |||
| 1122 | DBG("Card inserted\n"); | 1155 | DBG("Card inserted\n"); |
| 1123 | host->flags |= WBSD_FCARD_PRESENT; | 1156 | host->flags |= WBSD_FCARD_PRESENT; |
| 1124 | 1157 | ||
| 1158 | spin_unlock(&host->lock); | ||
| 1159 | |||
| 1125 | /* | 1160 | /* |
| 1126 | * Delay card detection to allow electrical connections | 1161 | * Delay card detection to allow electrical connections |
| 1127 | * to stabilise. | 1162 | * to stabilise. |
| 1128 | */ | 1163 | */ |
| 1129 | mod_timer(&host->detect_timer, jiffies + HZ/2); | 1164 | mmc_detect_change(host->mmc, msecs_to_jiffies(500)); |
| 1130 | } | 1165 | } |
| 1131 | 1166 | else | |
| 1132 | spin_unlock(&host->lock); | 1167 | spin_unlock(&host->lock); |
| 1133 | } | 1168 | } |
| 1134 | else if (host->flags & WBSD_FCARD_PRESENT) | 1169 | else if (host->flags & WBSD_FCARD_PRESENT) |
| 1135 | { | 1170 | { |
| @@ -1151,7 +1186,7 @@ static void wbsd_tasklet_card(unsigned long param) | |||
| 1151 | */ | 1186 | */ |
| 1152 | spin_unlock(&host->lock); | 1187 | spin_unlock(&host->lock); |
| 1153 | 1188 | ||
| 1154 | mmc_detect_change(host->mmc); | 1189 | mmc_detect_change(host->mmc, 0); |
| 1155 | } | 1190 | } |
| 1156 | else | 1191 | else |
| 1157 | spin_unlock(&host->lock); | 1192 | spin_unlock(&host->lock); |
| @@ -1355,16 +1390,13 @@ static int __devinit wbsd_alloc_mmc(struct device* dev) | |||
| 1355 | mmc->f_min = 375000; | 1390 | mmc->f_min = 375000; |
| 1356 | mmc->f_max = 24000000; | 1391 | mmc->f_max = 24000000; |
| 1357 | mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; | 1392 | mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; |
| 1393 | mmc->caps = MMC_CAP_4_BIT_DATA; | ||
| 1358 | 1394 | ||
| 1359 | spin_lock_init(&host->lock); | 1395 | spin_lock_init(&host->lock); |
| 1360 | 1396 | ||
| 1361 | /* | 1397 | /* |
| 1362 | * Set up timers | 1398 | * Set up timers |
| 1363 | */ | 1399 | */ |
| 1364 | init_timer(&host->detect_timer); | ||
| 1365 | host->detect_timer.data = (unsigned long)host; | ||
| 1366 | host->detect_timer.function = wbsd_detect_card; | ||
| 1367 | |||
| 1368 | init_timer(&host->ignore_timer); | 1400 | init_timer(&host->ignore_timer); |
| 1369 | host->ignore_timer.data = (unsigned long)host; | 1401 | host->ignore_timer.data = (unsigned long)host; |
| 1370 | host->ignore_timer.function = wbsd_reset_ignore; | 1402 | host->ignore_timer.function = wbsd_reset_ignore; |
| @@ -1406,7 +1438,6 @@ static void __devexit wbsd_free_mmc(struct device* dev) | |||
| 1406 | BUG_ON(host == NULL); | 1438 | BUG_ON(host == NULL); |
| 1407 | 1439 | ||
| 1408 | del_timer_sync(&host->ignore_timer); | 1440 | del_timer_sync(&host->ignore_timer); |
| 1409 | del_timer_sync(&host->detect_timer); | ||
| 1410 | 1441 | ||
| 1411 | mmc_free_host(mmc); | 1442 | mmc_free_host(mmc); |
| 1412 | 1443 | ||
diff --git a/drivers/mmc/wbsd.h b/drivers/mmc/wbsd.h index 8af43549f5d5..9005b5241b3c 100644 --- a/drivers/mmc/wbsd.h +++ b/drivers/mmc/wbsd.h | |||
| @@ -106,6 +106,8 @@ | |||
| 106 | #define WBSD_CLK_16M 0x02 | 106 | #define WBSD_CLK_16M 0x02 |
| 107 | #define WBSD_CLK_24M 0x03 | 107 | #define WBSD_CLK_24M 0x03 |
| 108 | 108 | ||
| 109 | #define WBSD_DATA_WIDTH 0x01 | ||
| 110 | |||
| 109 | #define WBSD_DAT3_H 0x08 | 111 | #define WBSD_DAT3_H 0x08 |
| 110 | #define WBSD_FIFO_RESET 0x04 | 112 | #define WBSD_FIFO_RESET 0x04 |
| 111 | #define WBSD_SOFT_RESET 0x02 | 113 | #define WBSD_SOFT_RESET 0x02 |
| @@ -164,6 +166,7 @@ struct wbsd_host | |||
| 164 | int firsterr; /* See fifo functions */ | 166 | int firsterr; /* See fifo functions */ |
| 165 | 167 | ||
| 166 | u8 clk; /* Current clock speed */ | 168 | u8 clk; /* Current clock speed */ |
| 169 | unsigned char bus_width; /* Current bus width */ | ||
| 167 | 170 | ||
| 168 | int config; /* Config port */ | 171 | int config; /* Config port */ |
| 169 | u8 unlock_code; /* Code to unlock config */ | 172 | u8 unlock_code; /* Code to unlock config */ |
