diff options
Diffstat (limited to 'drivers/mmc/host/au1xmmc.c')
-rw-r--r-- | drivers/mmc/host/au1xmmc.c | 58 |
1 files changed, 30 insertions, 28 deletions
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index 34c99d4ea041..92c4d0dfee43 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c | |||
@@ -186,7 +186,7 @@ static void au1xmmc_tasklet_finish(unsigned long param) | |||
186 | } | 186 | } |
187 | 187 | ||
188 | static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, | 188 | static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, |
189 | struct mmc_command *cmd, unsigned int flags) | 189 | struct mmc_command *cmd, struct mmc_data *data) |
190 | { | 190 | { |
191 | u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT); | 191 | u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT); |
192 | 192 | ||
@@ -208,19 +208,21 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, | |||
208 | default: | 208 | default: |
209 | printk(KERN_INFO "au1xmmc: unhandled response type %02x\n", | 209 | printk(KERN_INFO "au1xmmc: unhandled response type %02x\n", |
210 | mmc_resp_type(cmd)); | 210 | mmc_resp_type(cmd)); |
211 | return MMC_ERR_INVALID; | 211 | return -EINVAL; |
212 | } | 212 | } |
213 | 213 | ||
214 | if (flags & MMC_DATA_READ) { | 214 | if (data) { |
215 | if (flags & MMC_DATA_MULTI) | 215 | if (flags & MMC_DATA_READ) { |
216 | mmccmd |= SD_CMD_CT_4; | 216 | if (data->blocks > 1) |
217 | else | 217 | mmccmd |= SD_CMD_CT_4; |
218 | mmccmd |= SD_CMD_CT_2; | 218 | else |
219 | } else if (flags & MMC_DATA_WRITE) { | 219 | mmccmd |= SD_CMD_CT_2; |
220 | if (flags & MMC_DATA_MULTI) | 220 | } else if (flags & MMC_DATA_WRITE) { |
221 | mmccmd |= SD_CMD_CT_3; | 221 | if (data->blocks > 1) |
222 | else | 222 | mmccmd |= SD_CMD_CT_3; |
223 | mmccmd |= SD_CMD_CT_1; | 223 | else |
224 | mmccmd |= SD_CMD_CT_1; | ||
225 | } | ||
224 | } | 226 | } |
225 | 227 | ||
226 | au_writel(cmd->arg, HOST_CMDARG(host)); | 228 | au_writel(cmd->arg, HOST_CMDARG(host)); |
@@ -253,7 +255,7 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, | |||
253 | IRQ_ON(host, SD_CONFIG_CR); | 255 | IRQ_ON(host, SD_CONFIG_CR); |
254 | } | 256 | } |
255 | 257 | ||
256 | return MMC_ERR_NONE; | 258 | return 0; |
257 | } | 259 | } |
258 | 260 | ||
259 | static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status) | 261 | static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status) |
@@ -278,7 +280,7 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status) | |||
278 | while((host->flags & HOST_F_XMIT) && (status & SD_STATUS_DB)) | 280 | while((host->flags & HOST_F_XMIT) && (status & SD_STATUS_DB)) |
279 | status = au_readl(HOST_STATUS(host)); | 281 | status = au_readl(HOST_STATUS(host)); |
280 | 282 | ||
281 | data->error = MMC_ERR_NONE; | 283 | data->error = 0; |
282 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma.dir); | 284 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma.dir); |
283 | 285 | ||
284 | /* Process any errors */ | 286 | /* Process any errors */ |
@@ -288,14 +290,14 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status) | |||
288 | crc |= ((status & 0x07) == 0x02) ? 0 : 1; | 290 | crc |= ((status & 0x07) == 0x02) ? 0 : 1; |
289 | 291 | ||
290 | if (crc) | 292 | if (crc) |
291 | data->error = MMC_ERR_BADCRC; | 293 | data->error = -EILSEQ; |
292 | 294 | ||
293 | /* Clear the CRC bits */ | 295 | /* Clear the CRC bits */ |
294 | au_writel(SD_STATUS_WC | SD_STATUS_RC, HOST_STATUS(host)); | 296 | au_writel(SD_STATUS_WC | SD_STATUS_RC, HOST_STATUS(host)); |
295 | 297 | ||
296 | data->bytes_xfered = 0; | 298 | data->bytes_xfered = 0; |
297 | 299 | ||
298 | if (data->error == MMC_ERR_NONE) { | 300 | if (!data->error) { |
299 | if (host->flags & HOST_F_DMA) { | 301 | if (host->flags & HOST_F_DMA) { |
300 | u32 chan = DMA_CHANNEL(host); | 302 | u32 chan = DMA_CHANNEL(host); |
301 | 303 | ||
@@ -475,7 +477,7 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status) | |||
475 | return; | 477 | return; |
476 | 478 | ||
477 | cmd = mrq->cmd; | 479 | cmd = mrq->cmd; |
478 | cmd->error = MMC_ERR_NONE; | 480 | cmd->error = 0; |
479 | 481 | ||
480 | if (cmd->flags & MMC_RSP_PRESENT) { | 482 | if (cmd->flags & MMC_RSP_PRESENT) { |
481 | if (cmd->flags & MMC_RSP_136) { | 483 | if (cmd->flags & MMC_RSP_136) { |
@@ -512,11 +514,11 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status) | |||
512 | /* Figure out errors */ | 514 | /* Figure out errors */ |
513 | 515 | ||
514 | if (status & (SD_STATUS_SC | SD_STATUS_WC | SD_STATUS_RC)) | 516 | if (status & (SD_STATUS_SC | SD_STATUS_WC | SD_STATUS_RC)) |
515 | cmd->error = MMC_ERR_BADCRC; | 517 | cmd->error = -EILSEQ; |
516 | 518 | ||
517 | trans = host->flags & (HOST_F_XMIT | HOST_F_RECV); | 519 | trans = host->flags & (HOST_F_XMIT | HOST_F_RECV); |
518 | 520 | ||
519 | if (!trans || cmd->error != MMC_ERR_NONE) { | 521 | if (!trans || cmd->error) { |
520 | 522 | ||
521 | IRQ_OFF(host, SD_CONFIG_TH | SD_CONFIG_RA|SD_CONFIG_RF); | 523 | IRQ_OFF(host, SD_CONFIG_TH | SD_CONFIG_RA|SD_CONFIG_RF); |
522 | tasklet_schedule(&host->finish_task); | 524 | tasklet_schedule(&host->finish_task); |
@@ -589,7 +591,7 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data) | |||
589 | data->sg_len, host->dma.dir); | 591 | data->sg_len, host->dma.dir); |
590 | 592 | ||
591 | if (host->dma.len == 0) | 593 | if (host->dma.len == 0) |
592 | return MMC_ERR_TIMEOUT; | 594 | return -ETIMEDOUT; |
593 | 595 | ||
594 | au_writel(data->blksz - 1, HOST_BLKSIZE(host)); | 596 | au_writel(data->blksz - 1, HOST_BLKSIZE(host)); |
595 | 597 | ||
@@ -640,11 +642,11 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data) | |||
640 | //IRQ_ON(host, SD_CONFIG_RA|SD_CONFIG_RF); | 642 | //IRQ_ON(host, SD_CONFIG_RA|SD_CONFIG_RF); |
641 | } | 643 | } |
642 | 644 | ||
643 | return MMC_ERR_NONE; | 645 | return 0; |
644 | 646 | ||
645 | dataerr: | 647 | dataerr: |
646 | dma_unmap_sg(mmc_dev(host->mmc),data->sg,data->sg_len,host->dma.dir); | 648 | dma_unmap_sg(mmc_dev(host->mmc),data->sg,data->sg_len,host->dma.dir); |
647 | return MMC_ERR_TIMEOUT; | 649 | return -ETIMEDOUT; |
648 | } | 650 | } |
649 | 651 | ||
650 | /* static void au1xmmc_request | 652 | /* static void au1xmmc_request |
@@ -656,7 +658,7 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq) | |||
656 | 658 | ||
657 | struct au1xmmc_host *host = mmc_priv(mmc); | 659 | struct au1xmmc_host *host = mmc_priv(mmc); |
658 | unsigned int flags = 0; | 660 | unsigned int flags = 0; |
659 | int ret = MMC_ERR_NONE; | 661 | int ret = 0; |
660 | 662 | ||
661 | WARN_ON(irqs_disabled()); | 663 | WARN_ON(irqs_disabled()); |
662 | WARN_ON(host->status != HOST_S_IDLE); | 664 | WARN_ON(host->status != HOST_S_IDLE); |
@@ -672,10 +674,10 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq) | |||
672 | ret = au1xmmc_prepare_data(host, mrq->data); | 674 | ret = au1xmmc_prepare_data(host, mrq->data); |
673 | } | 675 | } |
674 | 676 | ||
675 | if (ret == MMC_ERR_NONE) | 677 | if (!ret) |
676 | ret = au1xmmc_send_command(host, 0, mrq->cmd, flags); | 678 | ret = au1xmmc_send_command(host, 0, mrq->cmd, mrq->data); |
677 | 679 | ||
678 | if (ret != MMC_ERR_NONE) { | 680 | if (ret) { |
679 | mrq->cmd->error = ret; | 681 | mrq->cmd->error = ret; |
680 | au1xmmc_finish_request(host); | 682 | au1xmmc_finish_request(host); |
681 | } | 683 | } |
@@ -764,10 +766,10 @@ static irqreturn_t au1xmmc_irq(int irq, void *dev_id) | |||
764 | 766 | ||
765 | if (host->mrq && (status & STATUS_TIMEOUT)) { | 767 | if (host->mrq && (status & STATUS_TIMEOUT)) { |
766 | if (status & SD_STATUS_RAT) | 768 | if (status & SD_STATUS_RAT) |
767 | host->mrq->cmd->error = MMC_ERR_TIMEOUT; | 769 | host->mrq->cmd->error = -ETIMEDOUT; |
768 | 770 | ||
769 | else if (status & SD_STATUS_DT) | 771 | else if (status & SD_STATUS_DT) |
770 | host->mrq->data->error = MMC_ERR_TIMEOUT; | 772 | host->mrq->data->error = -ETIMEDOUT; |
771 | 773 | ||
772 | /* In PIO mode, interrupts might still be enabled */ | 774 | /* In PIO mode, interrupts might still be enabled */ |
773 | IRQ_OFF(host, SD_CONFIG_NE | SD_CONFIG_TH); | 775 | IRQ_OFF(host, SD_CONFIG_NE | SD_CONFIG_TH); |