aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorSeungwon Jeon <tgih.jun@samsung.com>2011-12-22 04:01:29 -0500
committerChris Ball <cjb@laptop.org>2012-01-11 23:58:44 -0500
commit053b3ce6c15f0199c20b3fb06c3ae479de0324e2 (patch)
treec8d3b4a2dcb50d7a02197c9bd727d632da57907b /drivers/mmc
parent5b93a4595b6c39f78b69cc6eb9a3fa0ae6efe4a6 (diff)
mmc: dw_mmc: Support predefined mutiple block transfers
This patch adds the support for predefined multiple block r/w. dw_mmc can support MMC_CAP_CMD23 capability. Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com> Acked-by: Will Newton <will.newton@imgtec.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/dw_mmc.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 9b839fabfb3c..c583b943f615 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -588,11 +588,11 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot)
588 mci_writel(host, CTYPE, (slot->ctype << slot->id)); 588 mci_writel(host, CTYPE, (slot->ctype << slot->id));
589} 589}
590 590
591static void dw_mci_start_request(struct dw_mci *host, 591static void __dw_mci_start_request(struct dw_mci *host,
592 struct dw_mci_slot *slot) 592 struct dw_mci_slot *slot,
593 struct mmc_command *cmd)
593{ 594{
594 struct mmc_request *mrq; 595 struct mmc_request *mrq;
595 struct mmc_command *cmd;
596 struct mmc_data *data; 596 struct mmc_data *data;
597 u32 cmdflags; 597 u32 cmdflags;
598 598
@@ -610,14 +610,13 @@ static void dw_mci_start_request(struct dw_mci *host,
610 host->completed_events = 0; 610 host->completed_events = 0;
611 host->data_status = 0; 611 host->data_status = 0;
612 612
613 data = mrq->data; 613 data = cmd->data;
614 if (data) { 614 if (data) {
615 dw_mci_set_timeout(host); 615 dw_mci_set_timeout(host);
616 mci_writel(host, BYTCNT, data->blksz*data->blocks); 616 mci_writel(host, BYTCNT, data->blksz*data->blocks);
617 mci_writel(host, BLKSIZ, data->blksz); 617 mci_writel(host, BLKSIZ, data->blksz);
618 } 618 }
619 619
620 cmd = mrq->cmd;
621 cmdflags = dw_mci_prepare_command(slot->mmc, cmd); 620 cmdflags = dw_mci_prepare_command(slot->mmc, cmd);
622 621
623 /* this is the first command, send the initialization clock */ 622 /* this is the first command, send the initialization clock */
@@ -635,6 +634,16 @@ static void dw_mci_start_request(struct dw_mci *host,
635 host->stop_cmdr = dw_mci_prepare_command(slot->mmc, mrq->stop); 634 host->stop_cmdr = dw_mci_prepare_command(slot->mmc, mrq->stop);
636} 635}
637 636
637static void dw_mci_start_request(struct dw_mci *host,
638 struct dw_mci_slot *slot)
639{
640 struct mmc_request *mrq = slot->mrq;
641 struct mmc_command *cmd;
642
643 cmd = mrq->sbc ? mrq->sbc : mrq->cmd;
644 __dw_mci_start_request(host, slot, cmd);
645}
646
638/* must be called with host->lock held */ 647/* must be called with host->lock held */
639static void dw_mci_queue_request(struct dw_mci *host, struct dw_mci_slot *slot, 648static void dw_mci_queue_request(struct dw_mci *host, struct dw_mci_slot *slot,
640 struct mmc_request *mrq) 649 struct mmc_request *mrq)
@@ -889,7 +898,14 @@ static void dw_mci_tasklet_func(unsigned long priv)
889 cmd = host->cmd; 898 cmd = host->cmd;
890 host->cmd = NULL; 899 host->cmd = NULL;
891 set_bit(EVENT_CMD_COMPLETE, &host->completed_events); 900 set_bit(EVENT_CMD_COMPLETE, &host->completed_events);
892 dw_mci_command_complete(host, host->mrq->cmd); 901 dw_mci_command_complete(host, cmd);
902 if (cmd == host->mrq->sbc && !cmd->error) {
903 prev_state = state = STATE_SENDING_CMD;
904 __dw_mci_start_request(host, host->cur_slot,
905 host->mrq->cmd);
906 goto unlock;
907 }
908
893 if (!host->mrq->data || cmd->error) { 909 if (!host->mrq->data || cmd->error) {
894 dw_mci_request_end(host, host->mrq); 910 dw_mci_request_end(host, host->mrq);
895 goto unlock; 911 goto unlock;
@@ -967,6 +983,12 @@ static void dw_mci_tasklet_func(unsigned long priv)
967 goto unlock; 983 goto unlock;
968 } 984 }
969 985
986 if (host->mrq->sbc && !data->error) {
987 data->stop->error = 0;
988 dw_mci_request_end(host, host->mrq);
989 goto unlock;
990 }
991
970 prev_state = state = STATE_SENDING_STOP; 992 prev_state = state = STATE_SENDING_STOP;
971 if (!data->error) 993 if (!data->error)
972 send_stop_cmd(host, data); 994 send_stop_cmd(host, data);