diff options
author | Venkatraman S <svenkatr@ti.com> | 2012-04-09 02:38:34 -0400 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2012-04-22 11:16:50 -0400 |
commit | 31463b141587001781d86b2ef360544f101bd998 (patch) | |
tree | 880f30dd87d4d38f3db78b1b6d5e8a7a1fdef3ad /drivers/mmc/host/omap_hsmmc.c | |
parent | 03b5d924b926dd994b16f30f7a13bfb71ee0f478 (diff) |
mmc: omap_hsmmc: use spinlock IRQ safe variant
Prevent possible races between HSMMC/DMA IRQs and next requests.
Signed-off-by: Venkatraman S <svenkatr@ti.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/host/omap_hsmmc.c')
-rw-r--r-- | drivers/mmc/host/omap_hsmmc.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index dc41b9e4299e..a5bca725e414 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
@@ -806,11 +806,12 @@ omap_hsmmc_get_dma_dir(struct omap_hsmmc_host *host, struct mmc_data *data) | |||
806 | static void omap_hsmmc_request_done(struct omap_hsmmc_host *host, struct mmc_request *mrq) | 806 | static void omap_hsmmc_request_done(struct omap_hsmmc_host *host, struct mmc_request *mrq) |
807 | { | 807 | { |
808 | int dma_ch; | 808 | int dma_ch; |
809 | unsigned long flags; | ||
809 | 810 | ||
810 | spin_lock(&host->irq_lock); | 811 | spin_lock_irqsave(&host->irq_lock, flags); |
811 | host->req_in_progress = 0; | 812 | host->req_in_progress = 0; |
812 | dma_ch = host->dma_ch; | 813 | dma_ch = host->dma_ch; |
813 | spin_unlock(&host->irq_lock); | 814 | spin_unlock_irqrestore(&host->irq_lock, flags); |
814 | 815 | ||
815 | omap_hsmmc_disable_irq(host); | 816 | omap_hsmmc_disable_irq(host); |
816 | /* Do not complete the request if DMA is still in progress */ | 817 | /* Do not complete the request if DMA is still in progress */ |
@@ -887,13 +888,14 @@ omap_hsmmc_cmd_done(struct omap_hsmmc_host *host, struct mmc_command *cmd) | |||
887 | static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host *host, int errno) | 888 | static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host *host, int errno) |
888 | { | 889 | { |
889 | int dma_ch; | 890 | int dma_ch; |
891 | unsigned long flags; | ||
890 | 892 | ||
891 | host->data->error = errno; | 893 | host->data->error = errno; |
892 | 894 | ||
893 | spin_lock(&host->irq_lock); | 895 | spin_lock_irqsave(&host->irq_lock, flags); |
894 | dma_ch = host->dma_ch; | 896 | dma_ch = host->dma_ch; |
895 | host->dma_ch = -1; | 897 | host->dma_ch = -1; |
896 | spin_unlock(&host->irq_lock); | 898 | spin_unlock_irqrestore(&host->irq_lock, flags); |
897 | 899 | ||
898 | if (host->use_dma && dma_ch != -1) { | 900 | if (host->use_dma && dma_ch != -1) { |
899 | dma_unmap_sg(mmc_dev(host->mmc), host->data->sg, | 901 | dma_unmap_sg(mmc_dev(host->mmc), host->data->sg, |
@@ -1247,6 +1249,7 @@ static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *cb_data) | |||
1247 | struct omap_hsmmc_host *host = cb_data; | 1249 | struct omap_hsmmc_host *host = cb_data; |
1248 | struct mmc_data *data; | 1250 | struct mmc_data *data; |
1249 | int dma_ch, req_in_progress; | 1251 | int dma_ch, req_in_progress; |
1252 | unsigned long flags; | ||
1250 | 1253 | ||
1251 | if (!(ch_status & OMAP_DMA_BLOCK_IRQ)) { | 1254 | if (!(ch_status & OMAP_DMA_BLOCK_IRQ)) { |
1252 | dev_warn(mmc_dev(host->mmc), "unexpected dma status %x\n", | 1255 | dev_warn(mmc_dev(host->mmc), "unexpected dma status %x\n", |
@@ -1254,9 +1257,9 @@ static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *cb_data) | |||
1254 | return; | 1257 | return; |
1255 | } | 1258 | } |
1256 | 1259 | ||
1257 | spin_lock(&host->irq_lock); | 1260 | spin_lock_irqsave(&host->irq_lock, flags); |
1258 | if (host->dma_ch < 0) { | 1261 | if (host->dma_ch < 0) { |
1259 | spin_unlock(&host->irq_lock); | 1262 | spin_unlock_irqrestore(&host->irq_lock, flags); |
1260 | return; | 1263 | return; |
1261 | } | 1264 | } |
1262 | 1265 | ||
@@ -1266,7 +1269,7 @@ static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *cb_data) | |||
1266 | /* Fire up the next transfer. */ | 1269 | /* Fire up the next transfer. */ |
1267 | omap_hsmmc_config_dma_params(host, data, | 1270 | omap_hsmmc_config_dma_params(host, data, |
1268 | data->sg + host->dma_sg_idx); | 1271 | data->sg + host->dma_sg_idx); |
1269 | spin_unlock(&host->irq_lock); | 1272 | spin_unlock_irqrestore(&host->irq_lock, flags); |
1270 | return; | 1273 | return; |
1271 | } | 1274 | } |
1272 | 1275 | ||
@@ -1277,7 +1280,7 @@ static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *cb_data) | |||
1277 | req_in_progress = host->req_in_progress; | 1280 | req_in_progress = host->req_in_progress; |
1278 | dma_ch = host->dma_ch; | 1281 | dma_ch = host->dma_ch; |
1279 | host->dma_ch = -1; | 1282 | host->dma_ch = -1; |
1280 | spin_unlock(&host->irq_lock); | 1283 | spin_unlock_irqrestore(&host->irq_lock, flags); |
1281 | 1284 | ||
1282 | omap_free_dma(dma_ch); | 1285 | omap_free_dma(dma_ch); |
1283 | 1286 | ||