summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorPavan Kunapuli <pkunapuli@nvidia.com>2011-06-16 21:19:09 +0530
committerNiket Sirsi <nsirsi@nvidia.com>2011-06-29 15:32:26 -0700
commita649dd12854f408c7cdd014fd133baee168199d2 (patch)
treefd8f66c151052a49540ec57c8d52c73a0147d3ca /drivers
parentd8e82cb6c507074c0a502c33cfa5d2635f3e5673 (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.c13
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);