diff options
Diffstat (limited to 'drivers/mmc/host/msm_sdcc.c')
| -rw-r--r-- | drivers/mmc/host/msm_sdcc.c | 49 |
1 files changed, 33 insertions, 16 deletions
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index 1290d14c5839..b147971a96ef 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c | |||
| @@ -189,42 +189,40 @@ msmsdcc_dma_exec_func(struct msm_dmov_cmd *cmd) | |||
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | static void | 191 | static void |
| 192 | msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd, | 192 | msmsdcc_dma_complete_tlet(unsigned long data) |
| 193 | unsigned int result, | ||
| 194 | struct msm_dmov_errdata *err) | ||
| 195 | { | 193 | { |
| 196 | struct msmsdcc_dma_data *dma_data = | 194 | struct msmsdcc_host *host = (struct msmsdcc_host *)data; |
| 197 | container_of(cmd, struct msmsdcc_dma_data, hdr); | ||
| 198 | struct msmsdcc_host *host = dma_data->host; | ||
| 199 | unsigned long flags; | 195 | unsigned long flags; |
| 200 | struct mmc_request *mrq; | 196 | struct mmc_request *mrq; |
| 197 | struct msm_dmov_errdata err; | ||
| 201 | 198 | ||
| 202 | spin_lock_irqsave(&host->lock, flags); | 199 | spin_lock_irqsave(&host->lock, flags); |
| 203 | host->dma.active = 0; | 200 | host->dma.active = 0; |
| 204 | 201 | ||
| 202 | err = host->dma.err; | ||
| 205 | mrq = host->curr.mrq; | 203 | mrq = host->curr.mrq; |
| 206 | BUG_ON(!mrq); | 204 | BUG_ON(!mrq); |
| 207 | WARN_ON(!mrq->data); | 205 | WARN_ON(!mrq->data); |
| 208 | 206 | ||
| 209 | if (!(result & DMOV_RSLT_VALID)) { | 207 | if (!(host->dma.result & DMOV_RSLT_VALID)) { |
| 210 | pr_err("msmsdcc: Invalid DataMover result\n"); | 208 | pr_err("msmsdcc: Invalid DataMover result\n"); |
| 211 | goto out; | 209 | goto out; |
| 212 | } | 210 | } |
| 213 | 211 | ||
| 214 | if (result & DMOV_RSLT_DONE) { | 212 | if (host->dma.result & DMOV_RSLT_DONE) { |
| 215 | host->curr.data_xfered = host->curr.xfer_size; | 213 | host->curr.data_xfered = host->curr.xfer_size; |
| 216 | } else { | 214 | } else { |
| 217 | /* Error or flush */ | 215 | /* Error or flush */ |
| 218 | if (result & DMOV_RSLT_ERROR) | 216 | if (host->dma.result & DMOV_RSLT_ERROR) |
| 219 | pr_err("%s: DMA error (0x%.8x)\n", | 217 | pr_err("%s: DMA error (0x%.8x)\n", |
| 220 | mmc_hostname(host->mmc), result); | 218 | mmc_hostname(host->mmc), host->dma.result); |
| 221 | if (result & DMOV_RSLT_FLUSH) | 219 | if (host->dma.result & DMOV_RSLT_FLUSH) |
| 222 | pr_err("%s: DMA channel flushed (0x%.8x)\n", | 220 | pr_err("%s: DMA channel flushed (0x%.8x)\n", |
| 223 | mmc_hostname(host->mmc), result); | 221 | mmc_hostname(host->mmc), host->dma.result); |
| 224 | if (err) | 222 | |
| 225 | pr_err("Flush data: %.8x %.8x %.8x %.8x %.8x %.8x\n", | 223 | pr_err("Flush data: %.8x %.8x %.8x %.8x %.8x %.8x\n", |
| 226 | err->flush[0], err->flush[1], err->flush[2], | 224 | err.flush[0], err.flush[1], err.flush[2], |
| 227 | err->flush[3], err->flush[4], err->flush[5]); | 225 | err.flush[3], err.flush[4], err.flush[5]); |
| 228 | if (!mrq->data->error) | 226 | if (!mrq->data->error) |
| 229 | mrq->data->error = -EIO; | 227 | mrq->data->error = -EIO; |
| 230 | } | 228 | } |
| @@ -273,6 +271,22 @@ out: | |||
| 273 | return; | 271 | return; |
| 274 | } | 272 | } |
| 275 | 273 | ||
| 274 | static void | ||
| 275 | msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd, | ||
| 276 | unsigned int result, | ||
| 277 | struct msm_dmov_errdata *err) | ||
| 278 | { | ||
| 279 | struct msmsdcc_dma_data *dma_data = | ||
| 280 | container_of(cmd, struct msmsdcc_dma_data, hdr); | ||
| 281 | struct msmsdcc_host *host = dma_data->host; | ||
| 282 | |||
| 283 | dma_data->result = result; | ||
| 284 | if (err) | ||
| 285 | memcpy(&dma_data->err, err, sizeof(struct msm_dmov_errdata)); | ||
| 286 | |||
| 287 | tasklet_schedule(&host->dma_tlet); | ||
| 288 | } | ||
| 289 | |||
| 276 | static int validate_dma(struct msmsdcc_host *host, struct mmc_data *data) | 290 | static int validate_dma(struct msmsdcc_host *host, struct mmc_data *data) |
| 277 | { | 291 | { |
| 278 | if (host->dma.channel == -1) | 292 | if (host->dma.channel == -1) |
| @@ -1118,6 +1132,9 @@ msmsdcc_probe(struct platform_device *pdev) | |||
| 1118 | host->dmares = dmares; | 1132 | host->dmares = dmares; |
| 1119 | spin_lock_init(&host->lock); | 1133 | spin_lock_init(&host->lock); |
| 1120 | 1134 | ||
| 1135 | tasklet_init(&host->dma_tlet, msmsdcc_dma_complete_tlet, | ||
| 1136 | (unsigned long)host); | ||
| 1137 | |||
| 1121 | /* | 1138 | /* |
| 1122 | * Setup DMA | 1139 | * Setup DMA |
| 1123 | */ | 1140 | */ |
