summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorBitan Biswas <bbiswas@nvidia.com>2013-11-21 17:42:21 +0530
committerHarry Hong <hhong@nvidia.com>2014-01-12 17:01:52 -0800
commitfccc33265935c572c7e66e76b255cd52b070a330 (patch)
tree63326c9b6cb990d597474e40ae4a7f3d0c34ef5c /drivers
parentd992ac22487a3d2c66fe7fbd174dcbd2f9613b85 (diff)
mmc: sdhci: tegra: exclusive clk control
Exclusive access to Tegra sdhci set clock API to prevent race between multiple callers bug 1405624 Change-Id: If83f4bf7e0f4c9e39e0f581403d33f4efc9f8476 Signed-off-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-on: http://git-master/r/334014 Reviewed-by: Pavan Kunapuli <pkunapuli@nvidia.com> Reviewed-on: http://git-master/r/339783 (cherry picked from commit 9d5e83e800ed775ccabed82746b7ea07f952be06) Reviewed-on: http://git-master/r/353625 Reviewed-by: Harry Hong <hhong@nvidia.com> Tested-by: Harry Hong <hhong@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/host/sdhci-tegra.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 8b9c89673e81..4c8d536aa7d2 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2010 Google, Inc.
*
- * Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2012-2014, NVIDIA CORPORATION. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -306,6 +306,8 @@ struct sdhci_tegra {
const struct tegra_sdhci_platform_data *plat;
struct sdhci_tegra_soc_data *soc_data;
bool clk_enabled;
+ /* ensure atomic set clock calls */
+ struct mutex set_clock_mutex;
struct regulator *vdd_io_reg;
struct regulator *vdd_slot_reg;
struct regulator *vcore_reg;
@@ -1131,6 +1133,7 @@ static void tegra_sdhci_set_clock(struct sdhci_host *sdhci, unsigned int clock)
struct platform_device *pdev = to_platform_device(mmc_dev(sdhci->mmc));
u8 ctrl;
+ mutex_lock(&tegra_host->set_clock_mutex);
pr_debug("%s %s %u enabled=%u\n", __func__,
mmc_hostname(sdhci->mmc), clock, tegra_host->clk_enabled);
@@ -1175,6 +1178,7 @@ static void tegra_sdhci_set_clock(struct sdhci_host *sdhci, unsigned int clock)
pm_runtime_put_sync(&pdev->dev);
}
sdhci->is_clk_on = tegra_host->clk_enabled;
+ mutex_unlock(&tegra_host->set_clock_mutex);
}
static void tegra_sdhci_do_calibration(struct sdhci_host *sdhci)
{
@@ -3052,6 +3056,8 @@ static int __devinit sdhci_tegra_probe(struct platform_device *pdev)
pltfm_host->priv = tegra_host;
tegra_host->clk_enabled = true;
host->is_clk_on = tegra_host->clk_enabled;
+ mutex_init(&tegra_host->set_clock_mutex);
+
tegra_host->max_clk_limit = plat->max_clk_limit;
tegra_host->ddr_clk_limit = plat->ddr_clk_limit;
tegra_host->sd_detect_in_suspend = plat->sd_detect_in_suspend;