aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/au1xmmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/au1xmmc.c')
-rw-r--r--drivers/mmc/host/au1xmmc.c58
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
188static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, 188static 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
259static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status) 261static 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);