diff options
Diffstat (limited to 'drivers/mmc/host/mmc_spi.c')
| -rw-r--r-- | drivers/mmc/host/mmc_spi.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 62a35822003e..7c1e16aaf17f 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c | |||
| @@ -99,7 +99,7 @@ | |||
| 99 | #define r1b_timeout (HZ * 3) | 99 | #define r1b_timeout (HZ * 3) |
| 100 | 100 | ||
| 101 | /* One of the critical speed parameters is the amount of data which may | 101 | /* One of the critical speed parameters is the amount of data which may |
| 102 | * be transfered in one command. If this value is too low, the SD card | 102 | * be transferred in one command. If this value is too low, the SD card |
| 103 | * controller has to do multiple partial block writes (argggh!). With | 103 | * controller has to do multiple partial block writes (argggh!). With |
| 104 | * today (2008) SD cards there is little speed gain if we transfer more | 104 | * today (2008) SD cards there is little speed gain if we transfer more |
| 105 | * than 64 KBytes at a time. So use this value until there is any indication | 105 | * than 64 KBytes at a time. So use this value until there is any indication |
| @@ -1055,6 +1055,8 @@ static void mmc_spi_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 1055 | { | 1055 | { |
| 1056 | struct mmc_spi_host *host = mmc_priv(mmc); | 1056 | struct mmc_spi_host *host = mmc_priv(mmc); |
| 1057 | int status = -EINVAL; | 1057 | int status = -EINVAL; |
| 1058 | int crc_retry = 5; | ||
| 1059 | struct mmc_command stop; | ||
| 1058 | 1060 | ||
| 1059 | #ifdef DEBUG | 1061 | #ifdef DEBUG |
| 1060 | /* MMC core and layered drivers *MUST* issue SPI-aware commands */ | 1062 | /* MMC core and layered drivers *MUST* issue SPI-aware commands */ |
| @@ -1087,10 +1089,29 @@ static void mmc_spi_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 1087 | /* request exclusive bus access */ | 1089 | /* request exclusive bus access */ |
| 1088 | spi_bus_lock(host->spi->master); | 1090 | spi_bus_lock(host->spi->master); |
| 1089 | 1091 | ||
| 1092 | crc_recover: | ||
| 1090 | /* issue command; then optionally data and stop */ | 1093 | /* issue command; then optionally data and stop */ |
| 1091 | status = mmc_spi_command_send(host, mrq, mrq->cmd, mrq->data != NULL); | 1094 | status = mmc_spi_command_send(host, mrq, mrq->cmd, mrq->data != NULL); |
| 1092 | if (status == 0 && mrq->data) { | 1095 | if (status == 0 && mrq->data) { |
| 1093 | mmc_spi_data_do(host, mrq->cmd, mrq->data, mrq->data->blksz); | 1096 | mmc_spi_data_do(host, mrq->cmd, mrq->data, mrq->data->blksz); |
| 1097 | |||
| 1098 | /* | ||
| 1099 | * The SPI bus is not always reliable for large data transfers. | ||
| 1100 | * If an occasional crc error is reported by the SD device with | ||
| 1101 | * data read/write over SPI, it may be recovered by repeating | ||
| 1102 | * the last SD command again. The retry count is set to 5 to | ||
| 1103 | * ensure the driver passes stress tests. | ||
| 1104 | */ | ||
| 1105 | if (mrq->data->error == -EILSEQ && crc_retry) { | ||
| 1106 | stop.opcode = MMC_STOP_TRANSMISSION; | ||
| 1107 | stop.arg = 0; | ||
| 1108 | stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; | ||
| 1109 | status = mmc_spi_command_send(host, mrq, &stop, 0); | ||
| 1110 | crc_retry--; | ||
| 1111 | mrq->data->error = 0; | ||
| 1112 | goto crc_recover; | ||
| 1113 | } | ||
| 1114 | |||
| 1094 | if (mrq->stop) | 1115 | if (mrq->stop) |
| 1095 | status = mmc_spi_command_send(host, mrq, mrq->stop, 0); | 1116 | status = mmc_spi_command_send(host, mrq, mrq->stop, 0); |
| 1096 | else | 1117 | else |
| @@ -1345,8 +1366,7 @@ static int mmc_spi_probe(struct spi_device *spi) | |||
| 1345 | 1366 | ||
| 1346 | mmc->ops = &mmc_spi_ops; | 1367 | mmc->ops = &mmc_spi_ops; |
| 1347 | mmc->max_blk_size = MMC_SPI_BLOCKSIZE; | 1368 | mmc->max_blk_size = MMC_SPI_BLOCKSIZE; |
| 1348 | mmc->max_hw_segs = MMC_SPI_BLOCKSATONCE; | 1369 | mmc->max_segs = MMC_SPI_BLOCKSATONCE; |
| 1349 | mmc->max_phys_segs = MMC_SPI_BLOCKSATONCE; | ||
| 1350 | mmc->max_req_size = MMC_SPI_BLOCKSATONCE * MMC_SPI_BLOCKSIZE; | 1370 | mmc->max_req_size = MMC_SPI_BLOCKSATONCE * MMC_SPI_BLOCKSIZE; |
| 1351 | mmc->max_blk_count = MMC_SPI_BLOCKSATONCE; | 1371 | mmc->max_blk_count = MMC_SPI_BLOCKSATONCE; |
| 1352 | 1372 | ||
| @@ -1496,21 +1516,17 @@ static int __devexit mmc_spi_remove(struct spi_device *spi) | |||
| 1496 | return 0; | 1516 | return 0; |
| 1497 | } | 1517 | } |
| 1498 | 1518 | ||
| 1499 | #if defined(CONFIG_OF) | ||
| 1500 | static struct of_device_id mmc_spi_of_match_table[] __devinitdata = { | 1519 | static struct of_device_id mmc_spi_of_match_table[] __devinitdata = { |
| 1501 | { .compatible = "mmc-spi-slot", }, | 1520 | { .compatible = "mmc-spi-slot", }, |
| 1502 | {}, | 1521 | {}, |
| 1503 | }; | 1522 | }; |
| 1504 | #endif | ||
| 1505 | 1523 | ||
| 1506 | static struct spi_driver mmc_spi_driver = { | 1524 | static struct spi_driver mmc_spi_driver = { |
| 1507 | .driver = { | 1525 | .driver = { |
| 1508 | .name = "mmc_spi", | 1526 | .name = "mmc_spi", |
| 1509 | .bus = &spi_bus_type, | 1527 | .bus = &spi_bus_type, |
| 1510 | .owner = THIS_MODULE, | 1528 | .owner = THIS_MODULE, |
| 1511 | #if defined(CONFIG_OF) | ||
| 1512 | .of_match_table = mmc_spi_of_match_table, | 1529 | .of_match_table = mmc_spi_of_match_table, |
| 1513 | #endif | ||
| 1514 | }, | 1530 | }, |
| 1515 | .probe = mmc_spi_probe, | 1531 | .probe = mmc_spi_probe, |
| 1516 | .remove = __devexit_p(mmc_spi_remove), | 1532 | .remove = __devexit_p(mmc_spi_remove), |
