diff options
author | David S. Miller <davem@davemloft.net> | 2011-07-14 10:56:40 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-07-14 10:56:40 -0400 |
commit | 6a7ebdf2fd15417e87b4fd02ff411aeaca34da5f (patch) | |
tree | 86b15d8cd3e25c97b348b5a61bdb16c02726a480 /drivers/mmc | |
parent | f6b72b6217f8c24f2a54988e58af858b4e66024d (diff) | |
parent | 51414d41084496aaefd06d7f19eb8206e8bfac2d (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
net/bluetooth/l2cap_core.c
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/core/mmc.c | 77 | ||||
-rw-r--r-- | drivers/mmc/host/mmci.c | 2 | ||||
-rw-r--r-- | drivers/mmc/host/mmci.h | 5 |
3 files changed, 56 insertions, 28 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 2a7e43bc796d..aa7d1d79b8c5 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -247,12 +247,12 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
247 | return 0; | 247 | return 0; |
248 | 248 | ||
249 | /* Version is coded in the CSD_STRUCTURE byte in the EXT_CSD register */ | 249 | /* Version is coded in the CSD_STRUCTURE byte in the EXT_CSD register */ |
250 | card->ext_csd.raw_ext_csd_structure = ext_csd[EXT_CSD_STRUCTURE]; | ||
250 | if (card->csd.structure == 3) { | 251 | if (card->csd.structure == 3) { |
251 | int ext_csd_struct = ext_csd[EXT_CSD_STRUCTURE]; | 252 | if (card->ext_csd.raw_ext_csd_structure > 2) { |
252 | if (ext_csd_struct > 2) { | ||
253 | printk(KERN_ERR "%s: unrecognised EXT_CSD structure " | 253 | printk(KERN_ERR "%s: unrecognised EXT_CSD structure " |
254 | "version %d\n", mmc_hostname(card->host), | 254 | "version %d\n", mmc_hostname(card->host), |
255 | ext_csd_struct); | 255 | card->ext_csd.raw_ext_csd_structure); |
256 | err = -EINVAL; | 256 | err = -EINVAL; |
257 | goto out; | 257 | goto out; |
258 | } | 258 | } |
@@ -266,6 +266,10 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
266 | goto out; | 266 | goto out; |
267 | } | 267 | } |
268 | 268 | ||
269 | card->ext_csd.raw_sectors[0] = ext_csd[EXT_CSD_SEC_CNT + 0]; | ||
270 | card->ext_csd.raw_sectors[1] = ext_csd[EXT_CSD_SEC_CNT + 1]; | ||
271 | card->ext_csd.raw_sectors[2] = ext_csd[EXT_CSD_SEC_CNT + 2]; | ||
272 | card->ext_csd.raw_sectors[3] = ext_csd[EXT_CSD_SEC_CNT + 3]; | ||
269 | if (card->ext_csd.rev >= 2) { | 273 | if (card->ext_csd.rev >= 2) { |
270 | card->ext_csd.sectors = | 274 | card->ext_csd.sectors = |
271 | ext_csd[EXT_CSD_SEC_CNT + 0] << 0 | | 275 | ext_csd[EXT_CSD_SEC_CNT + 0] << 0 | |
@@ -277,7 +281,7 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
277 | if (card->ext_csd.sectors > (2u * 1024 * 1024 * 1024) / 512) | 281 | if (card->ext_csd.sectors > (2u * 1024 * 1024 * 1024) / 512) |
278 | mmc_card_set_blockaddr(card); | 282 | mmc_card_set_blockaddr(card); |
279 | } | 283 | } |
280 | 284 | card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE]; | |
281 | switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) { | 285 | switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) { |
282 | case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 | | 286 | case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 | |
283 | EXT_CSD_CARD_TYPE_26: | 287 | EXT_CSD_CARD_TYPE_26: |
@@ -307,6 +311,11 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
307 | mmc_hostname(card->host)); | 311 | mmc_hostname(card->host)); |
308 | } | 312 | } |
309 | 313 | ||
314 | card->ext_csd.raw_s_a_timeout = ext_csd[EXT_CSD_S_A_TIMEOUT]; | ||
315 | card->ext_csd.raw_erase_timeout_mult = | ||
316 | ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]; | ||
317 | card->ext_csd.raw_hc_erase_grp_size = | ||
318 | ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; | ||
310 | if (card->ext_csd.rev >= 3) { | 319 | if (card->ext_csd.rev >= 3) { |
311 | u8 sa_shift = ext_csd[EXT_CSD_S_A_TIMEOUT]; | 320 | u8 sa_shift = ext_csd[EXT_CSD_S_A_TIMEOUT]; |
312 | card->ext_csd.part_config = ext_csd[EXT_CSD_PART_CONFIG]; | 321 | card->ext_csd.part_config = ext_csd[EXT_CSD_PART_CONFIG]; |
@@ -334,6 +343,16 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
334 | card->ext_csd.boot_size = ext_csd[EXT_CSD_BOOT_MULT] << 17; | 343 | card->ext_csd.boot_size = ext_csd[EXT_CSD_BOOT_MULT] << 17; |
335 | } | 344 | } |
336 | 345 | ||
346 | card->ext_csd.raw_hc_erase_gap_size = | ||
347 | ext_csd[EXT_CSD_PARTITION_ATTRIBUTE]; | ||
348 | card->ext_csd.raw_sec_trim_mult = | ||
349 | ext_csd[EXT_CSD_SEC_TRIM_MULT]; | ||
350 | card->ext_csd.raw_sec_erase_mult = | ||
351 | ext_csd[EXT_CSD_SEC_ERASE_MULT]; | ||
352 | card->ext_csd.raw_sec_feature_support = | ||
353 | ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]; | ||
354 | card->ext_csd.raw_trim_mult = | ||
355 | ext_csd[EXT_CSD_TRIM_MULT]; | ||
337 | if (card->ext_csd.rev >= 4) { | 356 | if (card->ext_csd.rev >= 4) { |
338 | /* | 357 | /* |
339 | * Enhanced area feature support -- check whether the eMMC | 358 | * Enhanced area feature support -- check whether the eMMC |
@@ -341,7 +360,7 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
341 | * area offset and size to user by adding sysfs interface. | 360 | * area offset and size to user by adding sysfs interface. |
342 | */ | 361 | */ |
343 | if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) && | 362 | if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) && |
344 | (ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) { | 363 | (ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) { |
345 | u8 hc_erase_grp_sz = | 364 | u8 hc_erase_grp_sz = |
346 | ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; | 365 | ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; |
347 | u8 hc_wp_grp_sz = | 366 | u8 hc_wp_grp_sz = |
@@ -401,17 +420,17 @@ static inline void mmc_free_ext_csd(u8 *ext_csd) | |||
401 | } | 420 | } |
402 | 421 | ||
403 | 422 | ||
404 | static int mmc_compare_ext_csds(struct mmc_card *card, u8 *ext_csd, | 423 | static int mmc_compare_ext_csds(struct mmc_card *card, unsigned bus_width) |
405 | unsigned bus_width) | ||
406 | { | 424 | { |
407 | u8 *bw_ext_csd; | 425 | u8 *bw_ext_csd; |
408 | int err; | 426 | int err; |
409 | 427 | ||
428 | if (bus_width == MMC_BUS_WIDTH_1) | ||
429 | return 0; | ||
430 | |||
410 | err = mmc_get_ext_csd(card, &bw_ext_csd); | 431 | err = mmc_get_ext_csd(card, &bw_ext_csd); |
411 | if (err) | ||
412 | return err; | ||
413 | 432 | ||
414 | if ((ext_csd == NULL || bw_ext_csd == NULL)) { | 433 | if (err || bw_ext_csd == NULL) { |
415 | if (bus_width != MMC_BUS_WIDTH_1) | 434 | if (bus_width != MMC_BUS_WIDTH_1) |
416 | err = -EINVAL; | 435 | err = -EINVAL; |
417 | goto out; | 436 | goto out; |
@@ -421,35 +440,40 @@ static int mmc_compare_ext_csds(struct mmc_card *card, u8 *ext_csd, | |||
421 | goto out; | 440 | goto out; |
422 | 441 | ||
423 | /* only compare read only fields */ | 442 | /* only compare read only fields */ |
424 | err = (!(ext_csd[EXT_CSD_PARTITION_SUPPORT] == | 443 | err = (!(card->ext_csd.raw_partition_support == |
425 | bw_ext_csd[EXT_CSD_PARTITION_SUPPORT]) && | 444 | bw_ext_csd[EXT_CSD_PARTITION_SUPPORT]) && |
426 | (ext_csd[EXT_CSD_ERASED_MEM_CONT] == | 445 | (card->ext_csd.raw_erased_mem_count == |
427 | bw_ext_csd[EXT_CSD_ERASED_MEM_CONT]) && | 446 | bw_ext_csd[EXT_CSD_ERASED_MEM_CONT]) && |
428 | (ext_csd[EXT_CSD_REV] == | 447 | (card->ext_csd.rev == |
429 | bw_ext_csd[EXT_CSD_REV]) && | 448 | bw_ext_csd[EXT_CSD_REV]) && |
430 | (ext_csd[EXT_CSD_STRUCTURE] == | 449 | (card->ext_csd.raw_ext_csd_structure == |
431 | bw_ext_csd[EXT_CSD_STRUCTURE]) && | 450 | bw_ext_csd[EXT_CSD_STRUCTURE]) && |
432 | (ext_csd[EXT_CSD_CARD_TYPE] == | 451 | (card->ext_csd.raw_card_type == |
433 | bw_ext_csd[EXT_CSD_CARD_TYPE]) && | 452 | bw_ext_csd[EXT_CSD_CARD_TYPE]) && |
434 | (ext_csd[EXT_CSD_S_A_TIMEOUT] == | 453 | (card->ext_csd.raw_s_a_timeout == |
435 | bw_ext_csd[EXT_CSD_S_A_TIMEOUT]) && | 454 | bw_ext_csd[EXT_CSD_S_A_TIMEOUT]) && |
436 | (ext_csd[EXT_CSD_HC_WP_GRP_SIZE] == | 455 | (card->ext_csd.raw_hc_erase_gap_size == |
437 | bw_ext_csd[EXT_CSD_HC_WP_GRP_SIZE]) && | 456 | bw_ext_csd[EXT_CSD_HC_WP_GRP_SIZE]) && |
438 | (ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT] == | 457 | (card->ext_csd.raw_erase_timeout_mult == |
439 | bw_ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]) && | 458 | bw_ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]) && |
440 | (ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] == | 459 | (card->ext_csd.raw_hc_erase_grp_size == |
441 | bw_ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]) && | 460 | bw_ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]) && |
442 | (ext_csd[EXT_CSD_SEC_TRIM_MULT] == | 461 | (card->ext_csd.raw_sec_trim_mult == |
443 | bw_ext_csd[EXT_CSD_SEC_TRIM_MULT]) && | 462 | bw_ext_csd[EXT_CSD_SEC_TRIM_MULT]) && |
444 | (ext_csd[EXT_CSD_SEC_ERASE_MULT] == | 463 | (card->ext_csd.raw_sec_erase_mult == |
445 | bw_ext_csd[EXT_CSD_SEC_ERASE_MULT]) && | 464 | bw_ext_csd[EXT_CSD_SEC_ERASE_MULT]) && |
446 | (ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT] == | 465 | (card->ext_csd.raw_sec_feature_support == |
447 | bw_ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]) && | 466 | bw_ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]) && |
448 | (ext_csd[EXT_CSD_TRIM_MULT] == | 467 | (card->ext_csd.raw_trim_mult == |
449 | bw_ext_csd[EXT_CSD_TRIM_MULT]) && | 468 | bw_ext_csd[EXT_CSD_TRIM_MULT]) && |
450 | memcmp(&ext_csd[EXT_CSD_SEC_CNT], | 469 | (card->ext_csd.raw_sectors[0] == |
451 | &bw_ext_csd[EXT_CSD_SEC_CNT], | 470 | bw_ext_csd[EXT_CSD_SEC_CNT + 0]) && |
452 | 4) != 0); | 471 | (card->ext_csd.raw_sectors[1] == |
472 | bw_ext_csd[EXT_CSD_SEC_CNT + 1]) && | ||
473 | (card->ext_csd.raw_sectors[2] == | ||
474 | bw_ext_csd[EXT_CSD_SEC_CNT + 2]) && | ||
475 | (card->ext_csd.raw_sectors[3] == | ||
476 | bw_ext_csd[EXT_CSD_SEC_CNT + 3])); | ||
453 | if (err) | 477 | if (err) |
454 | err = -EINVAL; | 478 | err = -EINVAL; |
455 | 479 | ||
@@ -770,7 +794,6 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
770 | */ | 794 | */ |
771 | if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST)) | 795 | if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST)) |
772 | err = mmc_compare_ext_csds(card, | 796 | err = mmc_compare_ext_csds(card, |
773 | ext_csd, | ||
774 | bus_width); | 797 | bus_width); |
775 | else | 798 | else |
776 | err = mmc_bus_test(card, bus_width); | 799 | err = mmc_bus_test(card, bus_width); |
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 7721de942c69..fe140724a02e 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -582,6 +582,8 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data, | |||
582 | data->error = -EILSEQ; | 582 | data->error = -EILSEQ; |
583 | } else if (status & MCI_DATATIMEOUT) { | 583 | } else if (status & MCI_DATATIMEOUT) { |
584 | data->error = -ETIMEDOUT; | 584 | data->error = -ETIMEDOUT; |
585 | } else if (status & MCI_STARTBITERR) { | ||
586 | data->error = -ECOMM; | ||
585 | } else if (status & MCI_TXUNDERRUN) { | 587 | } else if (status & MCI_TXUNDERRUN) { |
586 | data->error = -EIO; | 588 | data->error = -EIO; |
587 | } else if (status & MCI_RXOVERRUN) { | 589 | } else if (status & MCI_RXOVERRUN) { |
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index bb32e21c09db..2164e8c6476c 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h | |||
@@ -86,6 +86,7 @@ | |||
86 | #define MCI_CMDRESPEND (1 << 6) | 86 | #define MCI_CMDRESPEND (1 << 6) |
87 | #define MCI_CMDSENT (1 << 7) | 87 | #define MCI_CMDSENT (1 << 7) |
88 | #define MCI_DATAEND (1 << 8) | 88 | #define MCI_DATAEND (1 << 8) |
89 | #define MCI_STARTBITERR (1 << 9) | ||
89 | #define MCI_DATABLOCKEND (1 << 10) | 90 | #define MCI_DATABLOCKEND (1 << 10) |
90 | #define MCI_CMDACTIVE (1 << 11) | 91 | #define MCI_CMDACTIVE (1 << 11) |
91 | #define MCI_TXACTIVE (1 << 12) | 92 | #define MCI_TXACTIVE (1 << 12) |
@@ -112,6 +113,7 @@ | |||
112 | #define MCI_CMDRESPENDCLR (1 << 6) | 113 | #define MCI_CMDRESPENDCLR (1 << 6) |
113 | #define MCI_CMDSENTCLR (1 << 7) | 114 | #define MCI_CMDSENTCLR (1 << 7) |
114 | #define MCI_DATAENDCLR (1 << 8) | 115 | #define MCI_DATAENDCLR (1 << 8) |
116 | #define MCI_STARTBITERRCLR (1 << 9) | ||
115 | #define MCI_DATABLOCKENDCLR (1 << 10) | 117 | #define MCI_DATABLOCKENDCLR (1 << 10) |
116 | /* Extended status bits for the ST Micro variants */ | 118 | /* Extended status bits for the ST Micro variants */ |
117 | #define MCI_ST_SDIOITC (1 << 22) | 119 | #define MCI_ST_SDIOITC (1 << 22) |
@@ -127,6 +129,7 @@ | |||
127 | #define MCI_CMDRESPENDMASK (1 << 6) | 129 | #define MCI_CMDRESPENDMASK (1 << 6) |
128 | #define MCI_CMDSENTMASK (1 << 7) | 130 | #define MCI_CMDSENTMASK (1 << 7) |
129 | #define MCI_DATAENDMASK (1 << 8) | 131 | #define MCI_DATAENDMASK (1 << 8) |
132 | #define MCI_STARTBITERRMASK (1 << 9) | ||
130 | #define MCI_DATABLOCKENDMASK (1 << 10) | 133 | #define MCI_DATABLOCKENDMASK (1 << 10) |
131 | #define MCI_CMDACTIVEMASK (1 << 11) | 134 | #define MCI_CMDACTIVEMASK (1 << 11) |
132 | #define MCI_TXACTIVEMASK (1 << 12) | 135 | #define MCI_TXACTIVEMASK (1 << 12) |
@@ -150,7 +153,7 @@ | |||
150 | #define MCI_IRQENABLE \ | 153 | #define MCI_IRQENABLE \ |
151 | (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \ | 154 | (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \ |
152 | MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \ | 155 | MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \ |
153 | MCI_CMDRESPENDMASK|MCI_CMDSENTMASK) | 156 | MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_STARTBITERRMASK) |
154 | 157 | ||
155 | /* These interrupts are directed to IRQ1 when two IRQ lines are available */ | 158 | /* These interrupts are directed to IRQ1 when two IRQ lines are available */ |
156 | #define MCI_IRQ1MASK \ | 159 | #define MCI_IRQ1MASK \ |