diff options
Diffstat (limited to 'drivers/mmc/host/msm_sdcc.c')
| -rw-r--r-- | drivers/mmc/host/msm_sdcc.c | 28 |
1 files changed, 25 insertions, 3 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 | ||
