aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorDavid Lanzendörfer <david.lanzendoerfer@o2s.ch>2014-12-16 09:11:04 -0500
committerUlf Hansson <ulf.hansson@linaro.org>2015-01-19 03:56:09 -0500
commitdd9b38039262040c02286b82c413d30b8f0cc6af (patch)
treeddfd5db44c466ab453256a638735e1ea85e2b934 /drivers/mmc
parente8a5904945ec4c37e468dfe0ef73418e8e63deef (diff)
mmc: sunxi: Lock fix
1) Adding a comment in order to clarify the choice of the locks within sunxi_mmc_handle_manual_stop 2) As <lixiang@allwinnertech.com> has pointed out the wait_dma variable was not accessed within the spin lock block in sunxi_mmc_request and so (even if it should never happend) it would have theoretically been possible that some other function would access the variable at the same time as the function. This has been changed now and the function is using local variables outside the lock and copys the value over during the lock phase. Signed-off-by: David Lanzendörfer <david.lanzendoerfer@o2s.ch> Reported-by: <lixiang@allwinnertech.com> Acked-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/sunxi-mmc.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
index 1fe54a889ce3..67e680c128c5 100644
--- a/drivers/mmc/host/sunxi-mmc.c
+++ b/drivers/mmc/host/sunxi-mmc.c
@@ -572,6 +572,15 @@ static irqreturn_t sunxi_mmc_handle_manual_stop(int irq, void *dev_id)
572 } 572 }
573 573
574 dev_err(mmc_dev(host->mmc), "data error, sending stop command\n"); 574 dev_err(mmc_dev(host->mmc), "data error, sending stop command\n");
575
576 /*
577 * We will never have more than one outstanding request,
578 * and we do not complete the request until after
579 * we've cleared host->manual_stop_mrq so we do not need to
580 * spin lock this function.
581 * Additionally we have wait states within this function
582 * so having it in a lock is a very bad idea.
583 */
575 sunxi_mmc_send_manual_stop(host, mrq); 584 sunxi_mmc_send_manual_stop(host, mrq);
576 585
577 spin_lock_irqsave(&host->lock, iflags); 586 spin_lock_irqsave(&host->lock, iflags);
@@ -768,6 +777,7 @@ static void sunxi_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
768 unsigned long iflags; 777 unsigned long iflags;
769 u32 imask = SDXC_INTERRUPT_ERROR_BIT; 778 u32 imask = SDXC_INTERRUPT_ERROR_BIT;
770 u32 cmd_val = SDXC_START | (cmd->opcode & 0x3f); 779 u32 cmd_val = SDXC_START | (cmd->opcode & 0x3f);
780 bool wait_dma = host->wait_dma;
771 int ret; 781 int ret;
772 782
773 /* Check for set_ios errors (should never happen) */ 783 /* Check for set_ios errors (should never happen) */
@@ -818,7 +828,7 @@ static void sunxi_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
818 if (cmd->data->flags & MMC_DATA_WRITE) 828 if (cmd->data->flags & MMC_DATA_WRITE)
819 cmd_val |= SDXC_WRITE; 829 cmd_val |= SDXC_WRITE;
820 else 830 else
821 host->wait_dma = true; 831 wait_dma = true;
822 } else { 832 } else {
823 imask |= SDXC_COMMAND_DONE; 833 imask |= SDXC_COMMAND_DONE;
824 } 834 }
@@ -852,6 +862,7 @@ static void sunxi_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
852 } 862 }
853 863
854 host->mrq = mrq; 864 host->mrq = mrq;
865 host->wait_dma = wait_dma;
855 mmc_writel(host, REG_IMASK, host->sdio_imask | imask); 866 mmc_writel(host, REG_IMASK, host->sdio_imask | imask);
856 mmc_writel(host, REG_CARG, cmd->arg); 867 mmc_writel(host, REG_CARG, cmd->arg);
857 mmc_writel(host, REG_CMDR, cmd_val); 868 mmc_writel(host, REG_CMDR, cmd_val);