]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
mmc: sdhci: tegra: atomic clk control
authorBitan Biswas <bbiswas@nvidia.com>
Thu, 21 Nov 2013 12:12:21 +0000 (17:42 +0530)
committerBitan Biswas <bbiswas@nvidia.com>
Fri, 22 Nov 2013 09:09:31 +0000 (01:09 -0800)
Tegra sdhci set clock API is made atomic to
prevent race between multiple callers

bug 1405624

Change-Id: Ib2815d332fda8f5ac55b6e87a3a8dce31076ab9e
Signed-off-by: Bitan Biswas <bbiswas@nvidia.com>
Reviewed-on: http://git-master/r/334014
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Pavan Kunapuli <pkunapuli@nvidia.com>
drivers/mmc/host/sdhci-tegra.c

index 382d40a97e66ca4b52fab843b9ea1b8f9a09090d..571ff79c6b2e5078f52bebe1e868a2d35755dad2 100644 (file)
@@ -328,6 +328,8 @@ struct sdhci_tegra {
        const struct tegra_sdhci_platform_data *plat;
        const 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;
@@ -1212,9 +1214,9 @@ 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);
-
        if (clock) {
                if (!tegra_host->clk_enabled) {
                        pm_runtime_get_sync(&pdev->dev);
@@ -1251,6 +1253,7 @@ static void tegra_sdhci_set_clock(struct sdhci_host *sdhci, unsigned int clock)
                tegra_host->clk_enabled = false;
        }
        sdhci->is_clk_on = tegra_host->clk_enabled;
+       mutex_unlock(&tegra_host->set_clock_mutex);
 }
 
 static unsigned int get_calibration_offsets(struct sdhci_host *sdhci)
@@ -3233,6 +3236,8 @@ static int 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->instance = pdev->id;