diff options
author | Balaji T K <balajitk@ti.com> | 2011-09-01 13:09:26 -0500 |
---|---|---|
committer | Ziyann <jaraidaniel@gmail.com> | 2014-10-01 12:55:53 +0200 |
commit | 79189a1f6611741ac02e1f97d00132b27ea55d29 (patch) | |
tree | 60e7cf9e88e02a1334e2356ac27a1309c074759b /drivers/mmc | |
parent | ea87f952937f51f89e93e77db429d0e0f345a865 (diff) | |
download | kernel_samsung_tuna-79189a1f6611741ac02e1f97d00132b27ea55d29.zip kernel_samsung_tuna-79189a1f6611741ac02e1f97d00132b27ea55d29.tar.gz kernel_samsung_tuna-79189a1f6611741ac02e1f97d00132b27ea55d29.tar.bz2 |
mmc: OMAP HSMMC: Add cmd23 support
Add support for set block count, close ended transfer
Change-Id: Iab7386e1171a42ebdf55306fbf291a3e6dd85b40
Signed-off-by: Viswanath Puttagunta <vishp@ti.com>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/omap_hsmmc.c | 39 |
1 files changed, 34 insertions, 5 deletions
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 6f5d3cc..f6e47a0 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -258,6 +258,9 @@ static void omap_hsmmc_status_notify_cb(int card_present, void *dev_id) } } +static int +omap_hsmmc_prepare_data(struct omap_hsmmc_host *host, struct mmc_request *req); + static int omap_hsmmc_card_detect(struct device *dev, int slot) { struct omap_mmc_platform_data *mmc = dev->platform_data; @@ -877,7 +880,7 @@ static DEVICE_ATTR(slot_name, S_IRUGO, omap_hsmmc_show_slot_name, NULL); */ static void omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, - struct mmc_data *data) + struct mmc_data *data, bool no_autocmd12) { int cmdreg = 0, resptype = 0, cmdtype = 0; @@ -907,7 +910,8 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, cmdtype = 0x3; cmdreg = (cmd->opcode << 24) | (resptype << 16) | (cmdtype << 22); - if ((host->flags & AUTO_CMD12) && mmc_op_multi(cmd->opcode)) + if ((host->flags & AUTO_CMD12) && mmc_op_multi(cmd->opcode) && + !no_autocmd12) cmdreg |= ACEN_ACMD12; if (data) { @@ -985,7 +989,7 @@ omap_hsmmc_xfer_done(struct omap_hsmmc_host *host, struct mmc_data *data) data->bytes_xfered = 0; if (data->stop && ((!(host->flags & AUTO_CMD12)) || data->error)) - omap_hsmmc_start_command(host, data->stop, NULL); + omap_hsmmc_start_command(host, data->stop, NULL, 0); else { if (data->stop) data->stop->resp[0] = OMAP_HSMMC_READ(host->base, @@ -1002,6 +1006,26 @@ omap_hsmmc_xfer_done(struct omap_hsmmc_host *host, struct mmc_data *data) static void omap_hsmmc_cmd_done(struct omap_hsmmc_host *host, struct mmc_command *cmd) { + int err; + struct mmc_request *req; + req = host->mrq; + + if ((host->mrq->sbc) && (host->cmd == host->mrq->sbc)) { + host->cmd = NULL; + err = omap_hsmmc_prepare_data(host, host->mrq); + if (err) { + req->cmd->error = err; + if (req->data) + req->data->error = err; + host->mrq = NULL; + mmc_request_done(host->mmc, req); + return; + } + omap_hsmmc_start_command(host, host->mrq->cmd, + host->mrq->data, 1); + return; + } + host->cmd = NULL; if (cmd->flags & MMC_RSP_PRESENT) { @@ -1667,6 +1691,11 @@ static void omap_hsmmc_request(struct mmc_host *mmc, struct mmc_request *req) host->reqs_blocked = 0; WARN_ON(host->mrq != NULL); host->mrq = req; + if (req->sbc) { + omap_hsmmc_start_command(host, req->sbc, NULL, 0); + return; + } + err = omap_hsmmc_prepare_data(host, req); if (err) { req->cmd->error = err; @@ -1677,7 +1706,7 @@ static void omap_hsmmc_request(struct mmc_host *mmc, struct mmc_request *req) return; } - omap_hsmmc_start_command(host, req->cmd, req->data); + omap_hsmmc_start_command(host, req->cmd, req->data, 0); } /* Routine to configure clock values. Exposed API to core */ @@ -2330,7 +2359,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) mmc->max_seg_size = mmc->max_req_size; mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | - MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_ERASE; + MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_ERASE | MMC_CAP_CMD23; mmc->caps |= mmc_slot(host).caps; if (mmc->caps & MMC_CAP_8_BIT_DATA) |