diff options
author | Pavan Kunapuli <pkunapuli@nvidia.com> | 2011-06-16 21:19:09 +0530 |
---|---|---|
committer | Niket Sirsi <nsirsi@nvidia.com> | 2011-06-29 15:32:26 -0700 |
commit | a649dd12854f408c7cdd014fd133baee168199d2 (patch) | |
tree | fd8f66c151052a49540ec57c8d52c73a0147d3ca /drivers | |
parent | d8e82cb6c507074c0a502c33cfa5d2635f3e5673 (diff) |
sdhci: tegra: Release spinlock when setting clock
Release spinlock when setting clock. This is required
to avoid lock up and scheduling in atomic issues when
dvfs is enabled.
Bug 827959
Change-Id: I6b95c6f9fef0ed8862a258736ff02c19affbda2e
Reviewed-on: http://git-master/r/37017
Tested-by: Pavan Kunapuli <pkunapuli@nvidia.com>
Reviewed-by: Narendra Damahe <ndamahe@nvidia.com>
Tested-by: Narendra Damahe <ndamahe@nvidia.com>
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/host/sdhci-tegra.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index bf1f3fae9456..ead3273e826d 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c @@ -77,6 +77,7 @@ struct tegra_sdhci_host { unsigned int card_present; struct regulator *reg_vdd_slot; struct regulator *reg_vddio; + unsigned int acquire_spinlock; }; static irqreturn_t carddetect_irq(int irq, void *data) @@ -156,6 +157,11 @@ static void tegra_sdhci_enable_clock(struct tegra_sdhci_host *host, int clock) { u8 val; + if (spin_is_locked(&host->sdhci->lock)) { + spin_unlock_irqrestore(&host->sdhci->lock, host->sdhci->spinlock_flags); + host->acquire_spinlock = 1; + } + if (clock) { if (!host->clk_enabled) { clk_enable(host->clk); @@ -175,6 +181,12 @@ static void tegra_sdhci_enable_clock(struct tegra_sdhci_host *host, int clock) clk_disable(host->clk); host->clk_enabled = 0; } + + if (host->acquire_spinlock) { + spin_lock_irqsave(&host->sdhci->lock, host->sdhci->spinlock_flags); + host->acquire_spinlock = 0; + } + if (host->clk_enabled) host->sdhci->max_clk = clk_get_rate(host->clk); else @@ -292,6 +304,7 @@ static int __devinit tegra_sdhci_probe(struct platform_device *pdev) #ifdef CONFIG_MMC_TEGRA_TAP_DELAY host->sdhci->tap_value = plat->tap_delay; #endif + host->acquire_spinlock = 0; host->clk = clk_get(&pdev->dev, plat->clk_id); if (IS_ERR(host->clk)) { rc = PTR_ERR(host->clk); |