diff options
Diffstat (limited to 'drivers/mmc/host')
-rw-r--r-- | drivers/mmc/host/au1xmmc.c | 35 | ||||
-rw-r--r-- | drivers/mmc/host/pxamci.c | 18 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.c | 9 |
3 files changed, 29 insertions, 33 deletions
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index b7156a4555b5..f967226d7505 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c | |||
@@ -187,9 +187,8 @@ static void au1xmmc_tasklet_finish(unsigned long param) | |||
187 | } | 187 | } |
188 | 188 | ||
189 | static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, | 189 | static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, |
190 | struct mmc_command *cmd) | 190 | struct mmc_command *cmd, unsigned int flags) |
191 | { | 191 | { |
192 | |||
193 | u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT); | 192 | u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT); |
194 | 193 | ||
195 | switch (mmc_resp_type(cmd)) { | 194 | switch (mmc_resp_type(cmd)) { |
@@ -213,24 +212,16 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, | |||
213 | return MMC_ERR_INVALID; | 212 | return MMC_ERR_INVALID; |
214 | } | 213 | } |
215 | 214 | ||
216 | switch(cmd->opcode) { | 215 | if (flags & MMC_DATA_READ) { |
217 | case MMC_READ_SINGLE_BLOCK: | 216 | if (flags & MMC_DATA_MULTI) |
218 | case SD_APP_SEND_SCR: | 217 | mmccmd |= SD_CMD_CT_4; |
219 | mmccmd |= SD_CMD_CT_2; | 218 | else |
220 | break; | 219 | mmccmd |= SD_CMD_CT_2; |
221 | case MMC_READ_MULTIPLE_BLOCK: | 220 | } else if (flags & MMC_DATA_WRITE) { |
222 | mmccmd |= SD_CMD_CT_4; | 221 | if (flags & MMC_DATA_MULTI) |
223 | break; | 222 | mmccmd |= SD_CMD_CT_3; |
224 | case MMC_WRITE_BLOCK: | 223 | else |
225 | mmccmd |= SD_CMD_CT_1; | 224 | mmccmd |= SD_CMD_CT_1; |
226 | break; | ||
227 | |||
228 | case MMC_WRITE_MULTIPLE_BLOCK: | ||
229 | mmccmd |= SD_CMD_CT_3; | ||
230 | break; | ||
231 | case MMC_STOP_TRANSMISSION: | ||
232 | mmccmd |= SD_CMD_CT_7; | ||
233 | break; | ||
234 | } | 225 | } |
235 | 226 | ||
236 | au_writel(cmd->arg, HOST_CMDARG(host)); | 227 | au_writel(cmd->arg, HOST_CMDARG(host)); |
@@ -665,6 +656,7 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq) | |||
665 | { | 656 | { |
666 | 657 | ||
667 | struct au1xmmc_host *host = mmc_priv(mmc); | 658 | struct au1xmmc_host *host = mmc_priv(mmc); |
659 | unsigned int flags = 0; | ||
668 | int ret = MMC_ERR_NONE; | 660 | int ret = MMC_ERR_NONE; |
669 | 661 | ||
670 | WARN_ON(irqs_disabled()); | 662 | WARN_ON(irqs_disabled()); |
@@ -677,11 +669,12 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq) | |||
677 | 669 | ||
678 | if (mrq->data) { | 670 | if (mrq->data) { |
679 | FLUSH_FIFO(host); | 671 | FLUSH_FIFO(host); |
672 | flags = mrq->data->flags; | ||
680 | ret = au1xmmc_prepare_data(host, mrq->data); | 673 | ret = au1xmmc_prepare_data(host, mrq->data); |
681 | } | 674 | } |
682 | 675 | ||
683 | if (ret == MMC_ERR_NONE) | 676 | if (ret == MMC_ERR_NONE) |
684 | ret = au1xmmc_send_command(host, 0, mrq->cmd); | 677 | ret = au1xmmc_send_command(host, 0, mrq->cmd, flags); |
685 | 678 | ||
686 | if (ret != MMC_ERR_NONE) { | 679 | if (ret != MMC_ERR_NONE) { |
687 | mrq->cmd->error = ret; | 680 | mrq->cmd->error = ret; |
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index d97d3864b57f..f8985c508bb9 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c | |||
@@ -232,20 +232,14 @@ static int pxamci_cmd_done(struct pxamci_host *host, unsigned int stat) | |||
232 | /* | 232 | /* |
233 | * workaround for erratum #42: | 233 | * workaround for erratum #42: |
234 | * Intel PXA27x Family Processor Specification Update Rev 001 | 234 | * Intel PXA27x Family Processor Specification Update Rev 001 |
235 | * A bogus CRC error can appear if the msb of a 136 bit | ||
236 | * response is a one. | ||
235 | */ | 237 | */ |
236 | if (cmd->opcode == MMC_ALL_SEND_CID || | 238 | if (cmd->flags & MMC_RSP_136 && cmd->resp[0] & 0x80000000) { |
237 | cmd->opcode == MMC_SEND_CSD || | 239 | pr_debug("ignoring CRC from command %d - *risky*\n", cmd->opcode); |
238 | cmd->opcode == MMC_SEND_CID) { | 240 | } else |
239 | /* a bogus CRC error can appear if the msb of | ||
240 | the 15 byte response is a one */ | ||
241 | if ((cmd->resp[0] & 0x80000000) == 0) | ||
242 | cmd->error = MMC_ERR_BADCRC; | ||
243 | } else { | ||
244 | pr_debug("ignoring CRC from command %d - *risky*\n",cmd->opcode); | ||
245 | } | ||
246 | #else | ||
247 | cmd->error = MMC_ERR_BADCRC; | ||
248 | #endif | 241 | #endif |
242 | cmd->error = MMC_ERR_BADCRC; | ||
249 | } | 243 | } |
250 | 244 | ||
251 | pxamci_disable_irq(host, END_CMD_RES); | 245 | pxamci_disable_irq(host, END_CMD_RES); |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index ff5bf73cdd25..a359efdd77eb 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -963,6 +963,15 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) | |||
963 | if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL)) | 963 | if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL)) |
964 | sdhci_transfer_pio(host); | 964 | sdhci_transfer_pio(host); |
965 | 965 | ||
966 | /* | ||
967 | * We currently don't do anything fancy with DMA | ||
968 | * boundaries, but as we can't disable the feature | ||
969 | * we need to at least restart the transfer. | ||
970 | */ | ||
971 | if (intmask & SDHCI_INT_DMA_END) | ||
972 | writel(readl(host->ioaddr + SDHCI_DMA_ADDRESS), | ||
973 | host->ioaddr + SDHCI_DMA_ADDRESS); | ||
974 | |||
966 | if (intmask & SDHCI_INT_DATA_END) | 975 | if (intmask & SDHCI_INT_DATA_END) |
967 | sdhci_finish_data(host); | 976 | sdhci_finish_data(host); |
968 | } | 977 | } |