aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/host/msm_sdcc.c28
-rw-r--r--drivers/mmc/host/msm_sdcc.h4
2 files changed, 28 insertions, 4 deletions
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index b147971a96ef..67f536ca31d3 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -438,6 +438,11 @@ msmsdcc_start_command_deferred(struct msmsdcc_host *host,
438 (cmd->opcode == 53)) 438 (cmd->opcode == 53))
439 *c |= MCI_CSPM_DATCMD; 439 *c |= MCI_CSPM_DATCMD;
440 440
441 if (host->prog_scan && (cmd->opcode == 12)) {
442 *c |= MCI_CPSM_PROGENA;
443 host->prog_enable = true;
444 }
445
441 if (cmd == cmd->mrq->stop) 446 if (cmd == cmd->mrq->stop)
442 *c |= MCI_CSPM_MCIABORT; 447 *c |= MCI_CSPM_MCIABORT;
443 448
@@ -508,6 +513,8 @@ msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data,
508 host->cmd_c = c; 513 host->cmd_c = c;
509 } 514 }
510 msm_dmov_enqueue_cmd(host->dma.channel, &host->dma.hdr); 515 msm_dmov_enqueue_cmd(host->dma.channel, &host->dma.hdr);
516 if (data->flags & MMC_DATA_WRITE)
517 host->prog_scan = true;
511 } else { 518 } else {
512 msmsdcc_writel(host, timeout, MMCIDATATIMER); 519 msmsdcc_writel(host, timeout, MMCIDATATIMER);
513 520
@@ -718,8 +725,23 @@ static void msmsdcc_do_cmdirq(struct msmsdcc_host *host, uint32_t status)
718 else if (host->curr.data) { /* Non DMA */ 725 else if (host->curr.data) { /* Non DMA */
719 msmsdcc_stop_data(host); 726 msmsdcc_stop_data(host);
720 msmsdcc_request_end(host, cmd->mrq); 727 msmsdcc_request_end(host, cmd->mrq);
721 } else /* host->data == NULL */ 728 } else { /* host->data == NULL */
722 msmsdcc_request_end(host, cmd->mrq); 729 if (!cmd->error && host->prog_enable) {
730 if (status & MCI_PROGDONE) {
731 host->prog_scan = false;
732 host->prog_enable = false;
733 msmsdcc_request_end(host, cmd->mrq);
734 } else {
735 host->curr.cmd = cmd;
736 }
737 } else {
738 if (host->prog_enable) {
739 host->prog_scan = false;
740 host->prog_enable = false;
741 }
742 msmsdcc_request_end(host, cmd->mrq);
743 }
744 }
723 } else if (cmd->data) 745 } else if (cmd->data)
724 if (!(cmd->data->flags & MMC_DATA_READ)) 746 if (!(cmd->data->flags & MMC_DATA_READ))
725 msmsdcc_start_data(host, cmd->data, 747 msmsdcc_start_data(host, cmd->data,
@@ -733,7 +755,7 @@ msmsdcc_handle_irq_data(struct msmsdcc_host *host, u32 status,
733 struct mmc_data *data = host->curr.data; 755 struct mmc_data *data = host->curr.data;
734 756
735 if (status & (MCI_CMDSENT | MCI_CMDRESPEND | MCI_CMDCRCFAIL | 757 if (status & (MCI_CMDSENT | MCI_CMDRESPEND | MCI_CMDCRCFAIL |
736 MCI_CMDTIMEOUT) && host->curr.cmd) { 758 MCI_CMDTIMEOUT | MCI_PROGDONE) && host->curr.cmd) {
737 msmsdcc_do_cmdirq(host, status); 759 msmsdcc_do_cmdirq(host, status);
738 } 760 }
739 761
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index 996990dfc7cc..e0579a1cc9e5 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -138,7 +138,7 @@
138#define MCI_IRQENABLE \ 138#define MCI_IRQENABLE \
139 (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \ 139 (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \
140 MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \ 140 MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \
141 MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATAENDMASK) 141 MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATAENDMASK|MCI_PROGDONEMASK)
142 142
143/* 143/*
144 * The size of the FIFO in bytes. 144 * The size of the FIFO in bytes.
@@ -245,6 +245,8 @@ struct msmsdcc_host {
245 struct mmc_command *cmd_cmd; 245 struct mmc_command *cmd_cmd;
246 u32 cmd_c; 246 u32 cmd_c;
247 247
248 bool prog_scan;
249 bool prog_enable;
248}; 250};
249 251
250#endif 252#endif