diff options
-rw-r--r-- | drivers/mmc/host/msm_sdcc.c | 28 | ||||
-rw-r--r-- | drivers/mmc/host/msm_sdcc.h | 4 |
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 |