diff options
author | Kyungmin Park <kmpark@infradead.org> | 2010-08-11 01:01:36 (GMT) |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-11 15:59:02 (GMT) |
commit | 6da24b786ed1963a7f872c1899627968c76d17d7 (patch) | |
tree | 992e2800e6aa88218f521ddd2f1cad879dcae380 /drivers/mmc | |
parent | a892e2d7dcdfa6c76e60c50a8c7385c65587a2a6 (diff) | |
download | linux-6da24b786ed1963a7f872c1899627968c76d17d7.tar.xz |
mmc: recognize CSD structure
The eMMC spec 4.4 and 4.3 + additional feature chips has CSD structure
version 3 and version 3 have to check the CSD_STRUCTURE byte in the
EXT_CSD register.
Also fix EXT_CSD revision message.
[akpm@linux-foundation.org: fix comment, per Chris Ball]
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Adrian Hunter <adrian.hunter@nokia.com>
Cc: Chris Ball <cjb@laptop.org>
Cc: <linux-mmc@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/core/mmc.c | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 89f7a25..cd8d3d2 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -114,17 +114,18 @@ static int mmc_decode_cid(struct mmc_card *card) static int mmc_decode_csd(struct mmc_card *card) { struct mmc_csd *csd = &card->csd; - unsigned int e, m, csd_struct; + unsigned int e, m; u32 *resp = card->raw_csd; /* * We only understand CSD structure v1.1 and v1.2. * v1.2 has extra information in bits 15, 11 and 10. + * We also support eMMC v4.4 & v4.41. */ - csd_struct = UNSTUFF_BITS(resp, 126, 2); - if (csd_struct != 1 && csd_struct != 2) { + csd->structure = UNSTUFF_BITS(resp, 126, 2); + if (csd->structure == 0) { printk(KERN_ERR "%s: unrecognised CSD structure version %d\n", - mmc_hostname(card->host), csd_struct); + mmc_hostname(card->host), csd->structure); return -EINVAL; } @@ -207,11 +208,22 @@ static int mmc_read_ext_csd(struct mmc_card *card) goto out; } + /* Version is coded in the CSD_STRUCTURE byte in the EXT_CSD register */ + if (card->csd.structure == 3) { + int ext_csd_struct = ext_csd[EXT_CSD_STRUCTURE]; + if (ext_csd_struct > 2) { + printk(KERN_ERR "%s: unrecognised EXT_CSD structure " + "version %d\n", mmc_hostname(card->host), + ext_csd_struct); + err = -EINVAL; + goto out; + } + } + card->ext_csd.rev = ext_csd[EXT_CSD_REV]; if (card->ext_csd.rev > 5) { - printk(KERN_ERR "%s: unrecognised EXT_CSD structure " - "version %d\n", mmc_hostname(card->host), - card->ext_csd.rev); + printk(KERN_ERR "%s: unrecognised EXT_CSD revision %d\n", + mmc_hostname(card->host), card->ext_csd.rev); err = -EINVAL; goto out; } |