diff options
author | David Howells <dhowells@redhat.com> | 2006-12-05 09:37:56 -0500 |
---|---|---|
committer | David Howells <dhowells@warthog.cambridge.redhat.com> | 2006-12-05 09:37:56 -0500 |
commit | 4c1ac1b49122b805adfa4efc620592f68dccf5db (patch) | |
tree | 87557f4bc2fd4fe65b7570489c2f610c45c0adcd /drivers/mmc/mmc.c | |
parent | c4028958b6ecad064b1a6303a6a5906d4fe48d73 (diff) | |
parent | d916faace3efc0bf19fe9a615a1ab8fa1a24cd93 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
drivers/infiniband/core/iwcm.c
drivers/net/chelsio/cxgb2.c
drivers/net/wireless/bcm43xx/bcm43xx_main.c
drivers/net/wireless/prism54/islpci_eth.c
drivers/usb/core/hub.h
drivers/usb/input/hid-core.c
net/core/netpoll.c
Fix up merge failures with Linus's head and fix new compilation failures.
Signed-Off-By: David Howells <dhowells@redhat.com>
Diffstat (limited to 'drivers/mmc/mmc.c')
-rw-r--r-- | drivers/mmc/mmc.c | 294 |
1 files changed, 274 insertions, 20 deletions
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 21fd39e4a20f..6f2a282e2b97 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c | |||
@@ -4,6 +4,7 @@ | |||
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. | 5 | * SD support Copyright (C) 2004 Ian Molton, All Rights Reserved. |
6 | * SD support Copyright (C) 2005 Pierre Ossman, All Rights Reserved. | 6 | * SD support Copyright (C) 2005 Pierre Ossman, All Rights Reserved. |
7 | * MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved. | ||
7 | * | 8 | * |
8 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
@@ -396,23 +397,23 @@ static int mmc_select_card(struct mmc_host *host, struct mmc_card *card) | |||
396 | return err; | 397 | return err; |
397 | 398 | ||
398 | /* | 399 | /* |
399 | * Default bus width is 1 bit. | 400 | * We can only change the bus width of SD cards when |
400 | */ | 401 | * they are selected so we have to put the handling |
401 | host->ios.bus_width = MMC_BUS_WIDTH_1; | ||
402 | |||
403 | /* | ||
404 | * We can only change the bus width of the selected | ||
405 | * card so therefore we have to put the handling | ||
406 | * here. | 402 | * here. |
403 | * | ||
404 | * The card is in 1 bit mode by default so | ||
405 | * we only need to change if it supports the | ||
406 | * wider version. | ||
407 | */ | 407 | */ |
408 | if (host->caps & MMC_CAP_4_BIT_DATA) { | 408 | if (mmc_card_sd(card) && |
409 | (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { | ||
410 | |||
409 | /* | 411 | /* |
410 | * The card is in 1 bit mode by default so | 412 | * Default bus width is 1 bit. |
411 | * we only need to change if it supports the | 413 | */ |
412 | * wider version. | 414 | host->ios.bus_width = MMC_BUS_WIDTH_1; |
413 | */ | 415 | |
414 | if (mmc_card_sd(card) && | 416 | if (host->caps & MMC_CAP_4_BIT_DATA) { |
415 | (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { | ||
416 | struct mmc_command cmd; | 417 | struct mmc_command cmd; |
417 | cmd.opcode = SD_APP_SET_BUS_WIDTH; | 418 | cmd.opcode = SD_APP_SET_BUS_WIDTH; |
418 | cmd.arg = SD_BUS_WIDTH_4; | 419 | cmd.arg = SD_BUS_WIDTH_4; |
@@ -453,11 +454,11 @@ static void mmc_deselect_cards(struct mmc_host *host) | |||
453 | 454 | ||
454 | static inline void mmc_delay(unsigned int ms) | 455 | static inline void mmc_delay(unsigned int ms) |
455 | { | 456 | { |
456 | if (ms < HZ / 1000) { | 457 | if (ms < 1000 / HZ) { |
457 | yield(); | 458 | cond_resched(); |
458 | mdelay(ms); | 459 | mdelay(ms); |
459 | } else { | 460 | } else { |
460 | msleep_interruptible (ms); | 461 | msleep(ms); |
461 | } | 462 | } |
462 | } | 463 | } |
463 | 464 | ||
@@ -953,6 +954,137 @@ static void mmc_read_csds(struct mmc_host *host) | |||
953 | } | 954 | } |
954 | } | 955 | } |
955 | 956 | ||
957 | static void mmc_process_ext_csds(struct mmc_host *host) | ||
958 | { | ||
959 | int err; | ||
960 | struct mmc_card *card; | ||
961 | |||
962 | struct mmc_request mrq; | ||
963 | struct mmc_command cmd; | ||
964 | struct mmc_data data; | ||
965 | |||
966 | struct scatterlist sg; | ||
967 | |||
968 | /* | ||
969 | * As the ext_csd is so large and mostly unused, we don't store the | ||
970 | * raw block in mmc_card. | ||
971 | */ | ||
972 | u8 *ext_csd; | ||
973 | ext_csd = kmalloc(512, GFP_KERNEL); | ||
974 | if (!ext_csd) { | ||
975 | printk("%s: could not allocate a buffer to receive the ext_csd." | ||
976 | "mmc v4 cards will be treated as v3.\n", | ||
977 | mmc_hostname(host)); | ||
978 | return; | ||
979 | } | ||
980 | |||
981 | list_for_each_entry(card, &host->cards, node) { | ||
982 | if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT)) | ||
983 | continue; | ||
984 | if (mmc_card_sd(card)) | ||
985 | continue; | ||
986 | if (card->csd.mmca_vsn < CSD_SPEC_VER_4) | ||
987 | continue; | ||
988 | |||
989 | err = mmc_select_card(host, card); | ||
990 | if (err != MMC_ERR_NONE) { | ||
991 | mmc_card_set_dead(card); | ||
992 | continue; | ||
993 | } | ||
994 | |||
995 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
996 | |||
997 | cmd.opcode = MMC_SEND_EXT_CSD; | ||
998 | cmd.arg = 0; | ||
999 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
1000 | |||
1001 | memset(&data, 0, sizeof(struct mmc_data)); | ||
1002 | |||
1003 | mmc_set_data_timeout(&data, card, 0); | ||
1004 | |||
1005 | data.blksz = 512; | ||
1006 | data.blocks = 1; | ||
1007 | data.flags = MMC_DATA_READ; | ||
1008 | data.sg = &sg; | ||
1009 | data.sg_len = 1; | ||
1010 | |||
1011 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
1012 | |||
1013 | mrq.cmd = &cmd; | ||
1014 | mrq.data = &data; | ||
1015 | |||
1016 | sg_init_one(&sg, ext_csd, 512); | ||
1017 | |||
1018 | mmc_wait_for_req(host, &mrq); | ||
1019 | |||
1020 | if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) { | ||
1021 | mmc_card_set_dead(card); | ||
1022 | continue; | ||
1023 | } | ||
1024 | |||
1025 | switch (ext_csd[EXT_CSD_CARD_TYPE]) { | ||
1026 | case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: | ||
1027 | card->ext_csd.hs_max_dtr = 52000000; | ||
1028 | break; | ||
1029 | case EXT_CSD_CARD_TYPE_26: | ||
1030 | card->ext_csd.hs_max_dtr = 26000000; | ||
1031 | break; | ||
1032 | default: | ||
1033 | /* MMC v4 spec says this cannot happen */ | ||
1034 | printk("%s: card is mmc v4 but doesn't support " | ||
1035 | "any high-speed modes.\n", | ||
1036 | mmc_hostname(card->host)); | ||
1037 | mmc_card_set_bad(card); | ||
1038 | continue; | ||
1039 | } | ||
1040 | |||
1041 | /* Activate highspeed support. */ | ||
1042 | cmd.opcode = MMC_SWITCH; | ||
1043 | cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | | ||
1044 | (EXT_CSD_HS_TIMING << 16) | | ||
1045 | (1 << 8) | | ||
1046 | EXT_CSD_CMD_SET_NORMAL; | ||
1047 | cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; | ||
1048 | |||
1049 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | ||
1050 | if (err != MMC_ERR_NONE) { | ||
1051 | printk("%s: failed to switch card to mmc v4 " | ||
1052 | "high-speed mode.\n", | ||
1053 | mmc_hostname(card->host)); | ||
1054 | continue; | ||
1055 | } | ||
1056 | |||
1057 | mmc_card_set_highspeed(card); | ||
1058 | |||
1059 | /* Check for host support for wide-bus modes. */ | ||
1060 | if (!(host->caps & MMC_CAP_4_BIT_DATA)) { | ||
1061 | continue; | ||
1062 | } | ||
1063 | |||
1064 | /* Activate 4-bit support. */ | ||
1065 | cmd.opcode = MMC_SWITCH; | ||
1066 | cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | | ||
1067 | (EXT_CSD_BUS_WIDTH << 16) | | ||
1068 | (EXT_CSD_BUS_WIDTH_4 << 8) | | ||
1069 | EXT_CSD_CMD_SET_NORMAL; | ||
1070 | cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; | ||
1071 | |||
1072 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | ||
1073 | if (err != MMC_ERR_NONE) { | ||
1074 | printk("%s: failed to switch card to " | ||
1075 | "mmc v4 4-bit bus mode.\n", | ||
1076 | mmc_hostname(card->host)); | ||
1077 | continue; | ||
1078 | } | ||
1079 | |||
1080 | host->ios.bus_width = MMC_BUS_WIDTH_4; | ||
1081 | } | ||
1082 | |||
1083 | kfree(ext_csd); | ||
1084 | |||
1085 | mmc_deselect_cards(host); | ||
1086 | } | ||
1087 | |||
956 | static void mmc_read_scrs(struct mmc_host *host) | 1088 | static void mmc_read_scrs(struct mmc_host *host) |
957 | { | 1089 | { |
958 | int err; | 1090 | int err; |
@@ -1025,14 +1157,133 @@ static void mmc_read_scrs(struct mmc_host *host) | |||
1025 | mmc_deselect_cards(host); | 1157 | mmc_deselect_cards(host); |
1026 | } | 1158 | } |
1027 | 1159 | ||
1160 | static void mmc_read_switch_caps(struct mmc_host *host) | ||
1161 | { | ||
1162 | int err; | ||
1163 | struct mmc_card *card; | ||
1164 | struct mmc_request mrq; | ||
1165 | struct mmc_command cmd; | ||
1166 | struct mmc_data data; | ||
1167 | unsigned char *status; | ||
1168 | struct scatterlist sg; | ||
1169 | |||
1170 | status = kmalloc(64, GFP_KERNEL); | ||
1171 | if (!status) { | ||
1172 | printk(KERN_WARNING "%s: Unable to allocate buffer for " | ||
1173 | "reading switch capabilities.\n", | ||
1174 | mmc_hostname(host)); | ||
1175 | return; | ||
1176 | } | ||
1177 | |||
1178 | list_for_each_entry(card, &host->cards, node) { | ||
1179 | if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT)) | ||
1180 | continue; | ||
1181 | if (!mmc_card_sd(card)) | ||
1182 | continue; | ||
1183 | if (card->scr.sda_vsn < SCR_SPEC_VER_1) | ||
1184 | continue; | ||
1185 | |||
1186 | err = mmc_select_card(host, card); | ||
1187 | if (err != MMC_ERR_NONE) { | ||
1188 | mmc_card_set_dead(card); | ||
1189 | continue; | ||
1190 | } | ||
1191 | |||
1192 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
1193 | |||
1194 | cmd.opcode = SD_SWITCH; | ||
1195 | cmd.arg = 0x00FFFFF1; | ||
1196 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
1197 | |||
1198 | memset(&data, 0, sizeof(struct mmc_data)); | ||
1199 | |||
1200 | mmc_set_data_timeout(&data, card, 0); | ||
1201 | |||
1202 | data.blksz = 64; | ||
1203 | data.blocks = 1; | ||
1204 | data.flags = MMC_DATA_READ; | ||
1205 | data.sg = &sg; | ||
1206 | data.sg_len = 1; | ||
1207 | |||
1208 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
1209 | |||
1210 | mrq.cmd = &cmd; | ||
1211 | mrq.data = &data; | ||
1212 | |||
1213 | sg_init_one(&sg, status, 64); | ||
1214 | |||
1215 | mmc_wait_for_req(host, &mrq); | ||
1216 | |||
1217 | if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) { | ||
1218 | mmc_card_set_dead(card); | ||
1219 | continue; | ||
1220 | } | ||
1221 | |||
1222 | if (status[13] & 0x02) | ||
1223 | card->sw_caps.hs_max_dtr = 50000000; | ||
1224 | |||
1225 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
1226 | |||
1227 | cmd.opcode = SD_SWITCH; | ||
1228 | cmd.arg = 0x80FFFFF1; | ||
1229 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
1230 | |||
1231 | memset(&data, 0, sizeof(struct mmc_data)); | ||
1232 | |||
1233 | mmc_set_data_timeout(&data, card, 0); | ||
1234 | |||
1235 | data.blksz = 64; | ||
1236 | data.blocks = 1; | ||
1237 | data.flags = MMC_DATA_READ; | ||
1238 | data.sg = &sg; | ||
1239 | data.sg_len = 1; | ||
1240 | |||
1241 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
1242 | |||
1243 | mrq.cmd = &cmd; | ||
1244 | mrq.data = &data; | ||
1245 | |||
1246 | sg_init_one(&sg, status, 64); | ||
1247 | |||
1248 | mmc_wait_for_req(host, &mrq); | ||
1249 | |||
1250 | if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) { | ||
1251 | mmc_card_set_dead(card); | ||
1252 | continue; | ||
1253 | } | ||
1254 | |||
1255 | if ((status[16] & 0xF) != 1) { | ||
1256 | printk(KERN_WARNING "%s: Problem switching card " | ||
1257 | "into high-speed mode!\n", | ||
1258 | mmc_hostname(host)); | ||
1259 | continue; | ||
1260 | } | ||
1261 | |||
1262 | mmc_card_set_highspeed(card); | ||
1263 | } | ||
1264 | |||
1265 | kfree(status); | ||
1266 | |||
1267 | mmc_deselect_cards(host); | ||
1268 | } | ||
1269 | |||
1028 | static unsigned int mmc_calculate_clock(struct mmc_host *host) | 1270 | static unsigned int mmc_calculate_clock(struct mmc_host *host) |
1029 | { | 1271 | { |
1030 | struct mmc_card *card; | 1272 | struct mmc_card *card; |
1031 | unsigned int max_dtr = host->f_max; | 1273 | unsigned int max_dtr = host->f_max; |
1032 | 1274 | ||
1033 | list_for_each_entry(card, &host->cards, node) | 1275 | list_for_each_entry(card, &host->cards, node) |
1034 | if (!mmc_card_dead(card) && max_dtr > card->csd.max_dtr) | 1276 | if (!mmc_card_dead(card)) { |
1035 | max_dtr = card->csd.max_dtr; | 1277 | if (mmc_card_highspeed(card) && mmc_card_sd(card)) { |
1278 | if (max_dtr > card->sw_caps.hs_max_dtr) | ||
1279 | max_dtr = card->sw_caps.hs_max_dtr; | ||
1280 | } else if (mmc_card_highspeed(card) && !mmc_card_sd(card)) { | ||
1281 | if (max_dtr > card->ext_csd.hs_max_dtr) | ||
1282 | max_dtr = card->ext_csd.hs_max_dtr; | ||
1283 | } else if (max_dtr > card->csd.max_dtr) { | ||
1284 | max_dtr = card->csd.max_dtr; | ||
1285 | } | ||
1286 | } | ||
1036 | 1287 | ||
1037 | pr_debug("%s: selected %d.%03dMHz transfer rate\n", | 1288 | pr_debug("%s: selected %d.%03dMHz transfer rate\n", |
1038 | mmc_hostname(host), | 1289 | mmc_hostname(host), |
@@ -1150,8 +1401,11 @@ static void mmc_setup(struct mmc_host *host) | |||
1150 | 1401 | ||
1151 | mmc_read_csds(host); | 1402 | mmc_read_csds(host); |
1152 | 1403 | ||
1153 | if (host->mode == MMC_MODE_SD) | 1404 | if (host->mode == MMC_MODE_SD) { |
1154 | mmc_read_scrs(host); | 1405 | mmc_read_scrs(host); |
1406 | mmc_read_switch_caps(host); | ||
1407 | } else | ||
1408 | mmc_process_ext_csds(host); | ||
1155 | } | 1409 | } |
1156 | 1410 | ||
1157 | 1411 | ||