diff options
author | Kyungmin Park <kmpark@infradead.org> | 2010-08-10 21:01:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-11 11:59:02 -0400 |
commit | 6da24b786ed1963a7f872c1899627968c76d17d7 (patch) | |
tree | 992e2800e6aa88218f521ddd2f1cad879dcae380 /drivers/mmc | |
parent | a892e2d7dcdfa6c76e60c50a8c7385c65587a2a6 (diff) |
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 89f7a25b7ac1..cd8d3d2ea901 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) | |||
114 | static int mmc_decode_csd(struct mmc_card *card) | 114 | static int mmc_decode_csd(struct mmc_card *card) |
115 | { | 115 | { |
116 | struct mmc_csd *csd = &card->csd; | 116 | struct mmc_csd *csd = &card->csd; |
117 | unsigned int e, m, csd_struct; | 117 | unsigned int e, m; |
118 | u32 *resp = card->raw_csd; | 118 | u32 *resp = card->raw_csd; |
119 | 119 | ||
120 | /* | 120 | /* |
121 | * We only understand CSD structure v1.1 and v1.2. | 121 | * We only understand CSD structure v1.1 and v1.2. |
122 | * v1.2 has extra information in bits 15, 11 and 10. | 122 | * v1.2 has extra information in bits 15, 11 and 10. |
123 | * We also support eMMC v4.4 & v4.41. | ||
123 | */ | 124 | */ |
124 | csd_struct = UNSTUFF_BITS(resp, 126, 2); | 125 | csd->structure = UNSTUFF_BITS(resp, 126, 2); |
125 | if (csd_struct != 1 && csd_struct != 2) { | 126 | if (csd->structure == 0) { |
126 | printk(KERN_ERR "%s: unrecognised CSD structure version %d\n", | 127 | printk(KERN_ERR "%s: unrecognised CSD structure version %d\n", |
127 | mmc_hostname(card->host), csd_struct); | 128 | mmc_hostname(card->host), csd->structure); |
128 | return -EINVAL; | 129 | return -EINVAL; |
129 | } | 130 | } |
130 | 131 | ||
@@ -207,11 +208,22 @@ static int mmc_read_ext_csd(struct mmc_card *card) | |||
207 | goto out; | 208 | goto out; |
208 | } | 209 | } |
209 | 210 | ||
211 | /* Version is coded in the CSD_STRUCTURE byte in the EXT_CSD register */ | ||
212 | if (card->csd.structure == 3) { | ||
213 | int ext_csd_struct = ext_csd[EXT_CSD_STRUCTURE]; | ||
214 | if (ext_csd_struct > 2) { | ||
215 | printk(KERN_ERR "%s: unrecognised EXT_CSD structure " | ||
216 | "version %d\n", mmc_hostname(card->host), | ||
217 | ext_csd_struct); | ||
218 | err = -EINVAL; | ||
219 | goto out; | ||
220 | } | ||
221 | } | ||
222 | |||
210 | card->ext_csd.rev = ext_csd[EXT_CSD_REV]; | 223 | card->ext_csd.rev = ext_csd[EXT_CSD_REV]; |
211 | if (card->ext_csd.rev > 5) { | 224 | if (card->ext_csd.rev > 5) { |
212 | printk(KERN_ERR "%s: unrecognised EXT_CSD structure " | 225 | printk(KERN_ERR "%s: unrecognised EXT_CSD revision %d\n", |
213 | "version %d\n", mmc_hostname(card->host), | 226 | mmc_hostname(card->host), card->ext_csd.rev); |
214 | card->ext_csd.rev); | ||
215 | err = -EINVAL; | 227 | err = -EINVAL; |
216 | goto out; | 228 | goto out; |
217 | } | 229 | } |