Skip to content

Commit

Permalink
mmc: msm_sdcc: Add prog done interrupt support
Browse files Browse the repository at this point in the history
Enable prog done interrupt for stop command(CMD12) that is sent
after a multi-block write(CMD25). The PROG_DONE bit is set when
the card has finished its programming and is ready for next data.

After every write request the card will be polled for ready status
using CMD13. For a multi-block write(CMD25) before sending CMD13,
stop command (CMD12) will be sent.  If we enable prog done interrupt
for CMD12, then CMD13 polling can be avoided. The prog done interrupt
means that the card is done with its programming and is ready for
next request.

Signed-off-by: Sahitya Tummala <stummala@codeaurora.org>
Signed-off-by: David Brown <davidb@codeaurora.org>
  • Loading branch information
Sahitya Tummala authored and David Brown committed Dec 20, 2010
1 parent 62612cf commit d5137bd
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 4 deletions.
28 changes: 25 additions & 3 deletions drivers/mmc/host/msm_sdcc.c
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,11 @@ msmsdcc_start_command_deferred(struct msmsdcc_host *host,
(cmd->opcode == 53))
*c |= MCI_CSPM_DATCMD;

if (host->prog_scan && (cmd->opcode == 12)) {
*c |= MCI_CPSM_PROGENA;
host->prog_enable = true;
}

if (cmd == cmd->mrq->stop)
*c |= MCI_CSPM_MCIABORT;

Expand Down Expand Up @@ -508,6 +513,8 @@ msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data,
host->cmd_c = c;
}
msm_dmov_enqueue_cmd(host->dma.channel, &host->dma.hdr);
if (data->flags & MMC_DATA_WRITE)
host->prog_scan = true;
} else {
msmsdcc_writel(host, timeout, MMCIDATATIMER);

Expand Down Expand Up @@ -718,8 +725,23 @@ static void msmsdcc_do_cmdirq(struct msmsdcc_host *host, uint32_t status)
else if (host->curr.data) { /* Non DMA */
msmsdcc_stop_data(host);
msmsdcc_request_end(host, cmd->mrq);
} else /* host->data == NULL */
msmsdcc_request_end(host, cmd->mrq);
} else { /* host->data == NULL */
if (!cmd->error && host->prog_enable) {
if (status & MCI_PROGDONE) {
host->prog_scan = false;
host->prog_enable = false;
msmsdcc_request_end(host, cmd->mrq);
} else {
host->curr.cmd = cmd;
}
} else {
if (host->prog_enable) {
host->prog_scan = false;
host->prog_enable = false;
}
msmsdcc_request_end(host, cmd->mrq);
}
}
} else if (cmd->data)
if (!(cmd->data->flags & MMC_DATA_READ))
msmsdcc_start_data(host, cmd->data,
Expand All @@ -733,7 +755,7 @@ msmsdcc_handle_irq_data(struct msmsdcc_host *host, u32 status,
struct mmc_data *data = host->curr.data;

if (status & (MCI_CMDSENT | MCI_CMDRESPEND | MCI_CMDCRCFAIL |
MCI_CMDTIMEOUT) && host->curr.cmd) {
MCI_CMDTIMEOUT | MCI_PROGDONE) && host->curr.cmd) {
msmsdcc_do_cmdirq(host, status);
}

Expand Down
4 changes: 3 additions & 1 deletion drivers/mmc/host/msm_sdcc.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@
#define MCI_IRQENABLE \
(MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \
MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \
MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATAENDMASK)
MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATAENDMASK|MCI_PROGDONEMASK)

/*
* The size of the FIFO in bytes.
Expand Down Expand Up @@ -245,6 +245,8 @@ struct msmsdcc_host {
struct mmc_command *cmd_cmd;
u32 cmd_c;

bool prog_scan;
bool prog_enable;
};

#endif

0 comments on commit d5137bd

Please sign in to comment.