aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/host/mxcmmc.c36
1 files changed, 26 insertions, 10 deletions
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index dcc9cdb2a4df..f4cbe473670e 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -162,7 +162,7 @@ static void mxcmci_softreset(struct mxcmci_host *host)
162 writew(0xff, host->base + MMC_REG_RES_TO); 162 writew(0xff, host->base + MMC_REG_RES_TO);
163} 163}
164 164
165static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) 165static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
166{ 166{
167 unsigned int nob = data->blocks; 167 unsigned int nob = data->blocks;
168 unsigned int blksz = data->blksz; 168 unsigned int blksz = data->blksz;
@@ -170,6 +170,7 @@ static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
170#ifdef HAS_DMA 170#ifdef HAS_DMA
171 struct scatterlist *sg; 171 struct scatterlist *sg;
172 int i; 172 int i;
173 int ret;
173#endif 174#endif
174 if (data->flags & MMC_DATA_STREAM) 175 if (data->flags & MMC_DATA_STREAM)
175 nob = 0xffff; 176 nob = 0xffff;
@@ -185,7 +186,7 @@ static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
185 for_each_sg(data->sg, sg, data->sg_len, i) { 186 for_each_sg(data->sg, sg, data->sg_len, i) {
186 if (sg->offset & 3 || sg->length & 3) { 187 if (sg->offset & 3 || sg->length & 3) {
187 host->do_dma = 0; 188 host->do_dma = 0;
188 return; 189 return 0;
189 } 190 }
190 } 191 }
191 192
@@ -194,23 +195,30 @@ static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
194 host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg, 195 host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,
195 data->sg_len, host->dma_dir); 196 data->sg_len, host->dma_dir);
196 197
197 imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, datasize, 198 ret = imx_dma_setup_sg(host->dma, data->sg, host->dma_nents,
198 host->res->start + MMC_REG_BUFFER_ACCESS, 199 datasize,
199 DMA_MODE_READ); 200 host->res->start + MMC_REG_BUFFER_ACCESS,
201 DMA_MODE_READ);
200 } else { 202 } else {
201 host->dma_dir = DMA_TO_DEVICE; 203 host->dma_dir = DMA_TO_DEVICE;
202 host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg, 204 host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,
203 data->sg_len, host->dma_dir); 205 data->sg_len, host->dma_dir);
204 206
205 imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, datasize, 207 ret = imx_dma_setup_sg(host->dma, data->sg, host->dma_nents,
206 host->res->start + MMC_REG_BUFFER_ACCESS, 208 datasize,
207 DMA_MODE_WRITE); 209 host->res->start + MMC_REG_BUFFER_ACCESS,
210 DMA_MODE_WRITE);
208 } 211 }
209 212
213 if (ret) {
214 dev_err(mmc_dev(host->mmc), "failed to setup DMA : %d\n", ret);
215 return ret;
216 }
210 wmb(); 217 wmb();
211 218
212 imx_dma_enable(host->dma); 219 imx_dma_enable(host->dma);
213#endif /* HAS_DMA */ 220#endif /* HAS_DMA */
221 return 0;
214} 222}
215 223
216static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd, 224static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd,
@@ -536,6 +544,7 @@ static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req)
536{ 544{
537 struct mxcmci_host *host = mmc_priv(mmc); 545 struct mxcmci_host *host = mmc_priv(mmc);
538 unsigned int cmdat = host->cmdat; 546 unsigned int cmdat = host->cmdat;
547 int error;
539 548
540 WARN_ON(host->req != NULL); 549 WARN_ON(host->req != NULL);
541 550
@@ -545,7 +554,12 @@ static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req)
545 host->do_dma = 1; 554 host->do_dma = 1;
546#endif 555#endif
547 if (req->data) { 556 if (req->data) {
548 mxcmci_setup_data(host, req->data); 557 error = mxcmci_setup_data(host, req->data);
558 if (error) {
559 req->cmd->error = error;
560 goto out;
561 }
562
549 563
550 cmdat |= CMD_DAT_CONT_DATA_ENABLE; 564 cmdat |= CMD_DAT_CONT_DATA_ENABLE;
551 565
@@ -553,7 +567,9 @@ static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req)
553 cmdat |= CMD_DAT_CONT_WRITE; 567 cmdat |= CMD_DAT_CONT_WRITE;
554 } 568 }
555 569
556 if (mxcmci_start_cmd(host, req->cmd, cmdat)) 570 error = mxcmci_start_cmd(host, req->cmd, cmdat);
571out:
572 if (error)
557 mxcmci_finish_request(host, req); 573 mxcmci_finish_request(host, req);
558} 574}
559 575