diff options
Diffstat (limited to 'drivers/mmc')
| -rw-r--r-- | drivers/mmc/mmc.c | 518 | ||||
| -rw-r--r-- | drivers/mmc/mmc_block.c | 9 | ||||
| -rw-r--r-- | drivers/mmc/mmc_sysfs.c | 21 | ||||
| -rw-r--r-- | drivers/mmc/pxamci.c | 11 | ||||
| -rw-r--r-- | drivers/mmc/wbsd.c | 60 | ||||
| -rw-r--r-- | drivers/mmc/wbsd.h | 3 |
6 files changed, 527 insertions, 95 deletions
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 0a8165974ba7..0a117c61cd18 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,6 +1070,9 @@ 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 | ||
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/pxamci.c b/drivers/mmc/pxamci.c index b78beb1b0159..e99a53b09e32 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 | ||
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c index 08ae22aed9e8..dec01d38c782 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 | |||
| 1028 | spin_unlock_bh(&host->lock); | 1052 | spin_unlock_bh(&host->lock); |
| 1029 | } | 1053 | } |
| 1030 | 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 | |||
| 1072 | spin_unlock_bh(&host->lock); | ||
| 1073 | |||
| 1074 | return csr & WBSD_WRPT; | ||
| 1075 | } | ||
| 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 | /*****************************************************************************\ |
| @@ -1355,6 +1402,7 @@ static int __devinit wbsd_alloc_mmc(struct device* dev) | |||
| 1355 | mmc->f_min = 375000; | 1402 | mmc->f_min = 375000; |
| 1356 | mmc->f_max = 24000000; | 1403 | mmc->f_max = 24000000; |
| 1357 | mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; | 1404 | mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; |
| 1405 | mmc->caps = MMC_CAP_4_BIT_DATA; | ||
| 1358 | 1406 | ||
| 1359 | spin_lock_init(&host->lock); | 1407 | spin_lock_init(&host->lock); |
| 1360 | 1408 | ||
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 */ |
