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 */ |