diff options
Diffstat (limited to 'drivers/mmc/core/mmc_ops.c')
-rw-r--r-- | drivers/mmc/core/mmc_ops.c | 80 |
1 files changed, 32 insertions, 48 deletions
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index f3b22bf89cc9..845ce7c533b9 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c | |||
@@ -23,12 +23,10 @@ | |||
23 | static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card) | 23 | static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card) |
24 | { | 24 | { |
25 | int err; | 25 | int err; |
26 | struct mmc_command cmd; | 26 | struct mmc_command cmd = {0}; |
27 | 27 | ||
28 | BUG_ON(!host); | 28 | BUG_ON(!host); |
29 | 29 | ||
30 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
31 | |||
32 | cmd.opcode = MMC_SELECT_CARD; | 30 | cmd.opcode = MMC_SELECT_CARD; |
33 | 31 | ||
34 | if (card) { | 32 | if (card) { |
@@ -60,15 +58,13 @@ int mmc_deselect_cards(struct mmc_host *host) | |||
60 | 58 | ||
61 | int mmc_card_sleepawake(struct mmc_host *host, int sleep) | 59 | int mmc_card_sleepawake(struct mmc_host *host, int sleep) |
62 | { | 60 | { |
63 | struct mmc_command cmd; | 61 | struct mmc_command cmd = {0}; |
64 | struct mmc_card *card = host->card; | 62 | struct mmc_card *card = host->card; |
65 | int err; | 63 | int err; |
66 | 64 | ||
67 | if (sleep) | 65 | if (sleep) |
68 | mmc_deselect_cards(host); | 66 | mmc_deselect_cards(host); |
69 | 67 | ||
70 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
71 | |||
72 | cmd.opcode = MMC_SLEEP_AWAKE; | 68 | cmd.opcode = MMC_SLEEP_AWAKE; |
73 | cmd.arg = card->rca << 16; | 69 | cmd.arg = card->rca << 16; |
74 | if (sleep) | 70 | if (sleep) |
@@ -97,7 +93,7 @@ int mmc_card_sleepawake(struct mmc_host *host, int sleep) | |||
97 | int mmc_go_idle(struct mmc_host *host) | 93 | int mmc_go_idle(struct mmc_host *host) |
98 | { | 94 | { |
99 | int err; | 95 | int err; |
100 | struct mmc_command cmd; | 96 | struct mmc_command cmd = {0}; |
101 | 97 | ||
102 | /* | 98 | /* |
103 | * Non-SPI hosts need to prevent chipselect going active during | 99 | * Non-SPI hosts need to prevent chipselect going active during |
@@ -113,8 +109,6 @@ int mmc_go_idle(struct mmc_host *host) | |||
113 | mmc_delay(1); | 109 | mmc_delay(1); |
114 | } | 110 | } |
115 | 111 | ||
116 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
117 | |||
118 | cmd.opcode = MMC_GO_IDLE_STATE; | 112 | cmd.opcode = MMC_GO_IDLE_STATE; |
119 | cmd.arg = 0; | 113 | cmd.arg = 0; |
120 | cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_NONE | MMC_CMD_BC; | 114 | cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_NONE | MMC_CMD_BC; |
@@ -135,13 +129,11 @@ int mmc_go_idle(struct mmc_host *host) | |||
135 | 129 | ||
136 | int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | 130 | int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) |
137 | { | 131 | { |
138 | struct mmc_command cmd; | 132 | struct mmc_command cmd = {0}; |
139 | int i, err = 0; | 133 | int i, err = 0; |
140 | 134 | ||
141 | BUG_ON(!host); | 135 | BUG_ON(!host); |
142 | 136 | ||
143 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
144 | |||
145 | cmd.opcode = MMC_SEND_OP_COND; | 137 | cmd.opcode = MMC_SEND_OP_COND; |
146 | cmd.arg = mmc_host_is_spi(host) ? 0 : ocr; | 138 | cmd.arg = mmc_host_is_spi(host) ? 0 : ocr; |
147 | cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR; | 139 | cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR; |
@@ -178,13 +170,11 @@ int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | |||
178 | int mmc_all_send_cid(struct mmc_host *host, u32 *cid) | 170 | int mmc_all_send_cid(struct mmc_host *host, u32 *cid) |
179 | { | 171 | { |
180 | int err; | 172 | int err; |
181 | struct mmc_command cmd; | 173 | struct mmc_command cmd = {0}; |
182 | 174 | ||
183 | BUG_ON(!host); | 175 | BUG_ON(!host); |
184 | BUG_ON(!cid); | 176 | BUG_ON(!cid); |
185 | 177 | ||
186 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
187 | |||
188 | cmd.opcode = MMC_ALL_SEND_CID; | 178 | cmd.opcode = MMC_ALL_SEND_CID; |
189 | cmd.arg = 0; | 179 | cmd.arg = 0; |
190 | cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; | 180 | cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; |
@@ -201,13 +191,11 @@ int mmc_all_send_cid(struct mmc_host *host, u32 *cid) | |||
201 | int mmc_set_relative_addr(struct mmc_card *card) | 191 | int mmc_set_relative_addr(struct mmc_card *card) |
202 | { | 192 | { |
203 | int err; | 193 | int err; |
204 | struct mmc_command cmd; | 194 | struct mmc_command cmd = {0}; |
205 | 195 | ||
206 | BUG_ON(!card); | 196 | BUG_ON(!card); |
207 | BUG_ON(!card->host); | 197 | BUG_ON(!card->host); |
208 | 198 | ||
209 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
210 | |||
211 | cmd.opcode = MMC_SET_RELATIVE_ADDR; | 199 | cmd.opcode = MMC_SET_RELATIVE_ADDR; |
212 | cmd.arg = card->rca << 16; | 200 | cmd.arg = card->rca << 16; |
213 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | 201 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; |
@@ -223,13 +211,11 @@ static int | |||
223 | mmc_send_cxd_native(struct mmc_host *host, u32 arg, u32 *cxd, int opcode) | 211 | mmc_send_cxd_native(struct mmc_host *host, u32 arg, u32 *cxd, int opcode) |
224 | { | 212 | { |
225 | int err; | 213 | int err; |
226 | struct mmc_command cmd; | 214 | struct mmc_command cmd = {0}; |
227 | 215 | ||
228 | BUG_ON(!host); | 216 | BUG_ON(!host); |
229 | BUG_ON(!cxd); | 217 | BUG_ON(!cxd); |
230 | 218 | ||
231 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
232 | |||
233 | cmd.opcode = opcode; | 219 | cmd.opcode = opcode; |
234 | cmd.arg = arg; | 220 | cmd.arg = arg; |
235 | cmd.flags = MMC_RSP_R2 | MMC_CMD_AC; | 221 | cmd.flags = MMC_RSP_R2 | MMC_CMD_AC; |
@@ -247,9 +233,9 @@ static int | |||
247 | mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host, | 233 | mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host, |
248 | u32 opcode, void *buf, unsigned len) | 234 | u32 opcode, void *buf, unsigned len) |
249 | { | 235 | { |
250 | struct mmc_request mrq; | 236 | struct mmc_request mrq = {0}; |
251 | struct mmc_command cmd; | 237 | struct mmc_command cmd = {0}; |
252 | struct mmc_data data; | 238 | struct mmc_data data = {0}; |
253 | struct scatterlist sg; | 239 | struct scatterlist sg; |
254 | void *data_buf; | 240 | void *data_buf; |
255 | 241 | ||
@@ -260,10 +246,6 @@ mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host, | |||
260 | if (data_buf == NULL) | 246 | if (data_buf == NULL) |
261 | return -ENOMEM; | 247 | return -ENOMEM; |
262 | 248 | ||
263 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
264 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
265 | memset(&data, 0, sizeof(struct mmc_data)); | ||
266 | |||
267 | mrq.cmd = &cmd; | 249 | mrq.cmd = &cmd; |
268 | mrq.data = &data; | 250 | mrq.data = &data; |
269 | 251 | ||
@@ -355,11 +337,9 @@ int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
355 | 337 | ||
356 | int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp) | 338 | int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp) |
357 | { | 339 | { |
358 | struct mmc_command cmd; | 340 | struct mmc_command cmd = {0}; |
359 | int err; | 341 | int err; |
360 | 342 | ||
361 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
362 | |||
363 | cmd.opcode = MMC_SPI_READ_OCR; | 343 | cmd.opcode = MMC_SPI_READ_OCR; |
364 | cmd.arg = highcap ? (1 << 30) : 0; | 344 | cmd.arg = highcap ? (1 << 30) : 0; |
365 | cmd.flags = MMC_RSP_SPI_R3; | 345 | cmd.flags = MMC_RSP_SPI_R3; |
@@ -372,11 +352,9 @@ int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp) | |||
372 | 352 | ||
373 | int mmc_spi_set_crc(struct mmc_host *host, int use_crc) | 353 | int mmc_spi_set_crc(struct mmc_host *host, int use_crc) |
374 | { | 354 | { |
375 | struct mmc_command cmd; | 355 | struct mmc_command cmd = {0}; |
376 | int err; | 356 | int err; |
377 | 357 | ||
378 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
379 | |||
380 | cmd.opcode = MMC_SPI_CRC_ON_OFF; | 358 | cmd.opcode = MMC_SPI_CRC_ON_OFF; |
381 | cmd.flags = MMC_RSP_SPI_R1; | 359 | cmd.flags = MMC_RSP_SPI_R1; |
382 | cmd.arg = use_crc; | 360 | cmd.arg = use_crc; |
@@ -387,23 +365,34 @@ int mmc_spi_set_crc(struct mmc_host *host, int use_crc) | |||
387 | return err; | 365 | return err; |
388 | } | 366 | } |
389 | 367 | ||
390 | int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value) | 368 | /** |
369 | * mmc_switch - modify EXT_CSD register | ||
370 | * @card: the MMC card associated with the data transfer | ||
371 | * @set: cmd set values | ||
372 | * @index: EXT_CSD register index | ||
373 | * @value: value to program into EXT_CSD register | ||
374 | * @timeout_ms: timeout (ms) for operation performed by register write, | ||
375 | * timeout of zero implies maximum possible timeout | ||
376 | * | ||
377 | * Modifies the EXT_CSD register for selected card. | ||
378 | */ | ||
379 | int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, | ||
380 | unsigned int timeout_ms) | ||
391 | { | 381 | { |
392 | int err; | 382 | int err; |
393 | struct mmc_command cmd; | 383 | struct mmc_command cmd = {0}; |
394 | u32 status; | 384 | u32 status; |
395 | 385 | ||
396 | BUG_ON(!card); | 386 | BUG_ON(!card); |
397 | BUG_ON(!card->host); | 387 | BUG_ON(!card->host); |
398 | 388 | ||
399 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
400 | |||
401 | cmd.opcode = MMC_SWITCH; | 389 | cmd.opcode = MMC_SWITCH; |
402 | cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | | 390 | cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | |
403 | (index << 16) | | 391 | (index << 16) | |
404 | (value << 8) | | 392 | (value << 8) | |
405 | set; | 393 | set; |
406 | cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; | 394 | cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; |
395 | cmd.cmd_timeout_ms = timeout_ms; | ||
407 | 396 | ||
408 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); | 397 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); |
409 | if (err) | 398 | if (err) |
@@ -433,17 +422,16 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value) | |||
433 | 422 | ||
434 | return 0; | 423 | return 0; |
435 | } | 424 | } |
425 | EXPORT_SYMBOL_GPL(mmc_switch); | ||
436 | 426 | ||
437 | int mmc_send_status(struct mmc_card *card, u32 *status) | 427 | int mmc_send_status(struct mmc_card *card, u32 *status) |
438 | { | 428 | { |
439 | int err; | 429 | int err; |
440 | struct mmc_command cmd; | 430 | struct mmc_command cmd = {0}; |
441 | 431 | ||
442 | BUG_ON(!card); | 432 | BUG_ON(!card); |
443 | BUG_ON(!card->host); | 433 | BUG_ON(!card->host); |
444 | 434 | ||
445 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
446 | |||
447 | cmd.opcode = MMC_SEND_STATUS; | 435 | cmd.opcode = MMC_SEND_STATUS; |
448 | if (!mmc_host_is_spi(card->host)) | 436 | if (!mmc_host_is_spi(card->host)) |
449 | cmd.arg = card->rca << 16; | 437 | cmd.arg = card->rca << 16; |
@@ -466,9 +454,9 @@ static int | |||
466 | mmc_send_bus_test(struct mmc_card *card, struct mmc_host *host, u8 opcode, | 454 | mmc_send_bus_test(struct mmc_card *card, struct mmc_host *host, u8 opcode, |
467 | u8 len) | 455 | u8 len) |
468 | { | 456 | { |
469 | struct mmc_request mrq; | 457 | struct mmc_request mrq = {0}; |
470 | struct mmc_command cmd; | 458 | struct mmc_command cmd = {0}; |
471 | struct mmc_data data; | 459 | struct mmc_data data = {0}; |
472 | struct scatterlist sg; | 460 | struct scatterlist sg; |
473 | u8 *data_buf; | 461 | u8 *data_buf; |
474 | u8 *test_buf; | 462 | u8 *test_buf; |
@@ -497,10 +485,6 @@ mmc_send_bus_test(struct mmc_card *card, struct mmc_host *host, u8 opcode, | |||
497 | if (opcode == MMC_BUS_TEST_W) | 485 | if (opcode == MMC_BUS_TEST_W) |
498 | memcpy(data_buf, test_buf, len); | 486 | memcpy(data_buf, test_buf, len); |
499 | 487 | ||
500 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
501 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
502 | memset(&data, 0, sizeof(struct mmc_data)); | ||
503 | |||
504 | mrq.cmd = &cmd; | 488 | mrq.cmd = &cmd; |
505 | mrq.data = &data; | 489 | mrq.data = &data; |
506 | cmd.opcode = opcode; | 490 | cmd.opcode = opcode; |