Kangkai, > My analysis is that when you try to do sdhci_try_get_regulator(host) > in sdhci_add_host(), it will trigger mmc_detect_change(), and then > mmc_rescan(), then mmc_power_up()... > > At the same time, driver initialise code continues run into > mmc_start_host(), and then mmc_power_off().
This cannot happen.
sdhci_try_get_regulator(host) cannot be called by the platform code until the
sdhci host's slot is fully initialized. I took care of that very carefully (but
seems I forgot another check in the original patch). Please look at the two
code snippets to convice you:
slot = sdhci_pci_probe_slot(pdev, chip, first_bar + i);
if (IS_ERR(slot)) {
for (i--;i >= 0;i--)
sdhci_pci_remove_slot(chip->slots[i]);
ret = PTR_ERR(slot);
goto free;
}
chip->slots[i] = slot; // chip->slots[i] is only initialized
when slot is fully initialized
@@ -663,10 +663,13 @@ static int try_request_regulator(struct device *dev, void
*data)
for (i = 0; i < chip->num_slots; i++) {
slot = chip->slots[i];
+ if (!slot)
+ continue;
host = slot->host;
if (!host)
continue;
- sdhci_try_get_regulator(host);
+ if(sdhci_try_get_regulator(host)==0)
+ mmc_detect_change(host->mmc, 0);
}
return 0;
and at the end of sdhci_pci_probe()
we do a last call to
sdhci_pci_request_regulators();
in order to make sure that we did not hit the race condition.
The BUG() you hit is actually related to another issue. I did a mmc_rescan()
when the sdhci is not yet full initialized. See temporary patch for review. We
need to rebase it against latest meego kernel.
>From 7435ae1483749c9451f0ea85872f805e85e99c20 Mon Sep 17 00:00:00 2001
From: Pierre Tardy <[email protected]>
Date: Tue, 7 Dec 2010 11:36:06 +0100
Subject: [PATCH] sdhci: dont rescan in sdhci_try_get_regulator()
this function is also called by sdhci_probe at
a point where the sdhci is not yet initialized
also fix another race condition check
Change-Id: I558a985bbd93885844b82b357685ce19ed672e80
Signed-off-by: Pierre Tardy <[email protected]>
---
drivers/mmc/host/sdhci-pci.c | 5 ++++-
drivers/mmc/host/sdhci.c | 5 +++--
drivers/mmc/host/sdhci.h | 2 +-
3 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index f251d06..eb8797a 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -663,10 +663,13 @@ static int try_request_regulator(struct device *dev, void
*data)
for (i = 0; i < chip->num_slots; i++) {
slot = chip->slots[i];
+ if (!slot)
+ continue;
host = slot->host;
if (!host)
continue;
- sdhci_try_get_regulator(host);
+ if(sdhci_try_get_regulator(host)==0)
+ mmc_detect_change(host->mmc, 0);
}
return 0;
}
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 894c086..ccae6fc 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1778,7 +1778,7 @@ struct sdhci_host *sdhci_alloc_host(struct device *dev,
EXPORT_SYMBOL_GPL(sdhci_alloc_host);
-void sdhci_try_get_regulator(struct sdhci_host *host)
+int sdhci_try_get_regulator(struct sdhci_host *host)
{
struct regulator *vmmc;
unsigned long flags;
@@ -1790,13 +1790,14 @@ void sdhci_try_get_regulator(struct sdhci_host *host)
host->vmmc = vmmc;
spin_unlock_irqrestore(&host->lock, flags);
regulator_enable(host->vmmc);
- mmc_detect_change(host->mmc, 0);
+ return 0;
} else { /* race! we got the regulator twice */
spin_unlock_irqrestore(&host->lock, flags);
regulator_put(vmmc);
}
}
}
+ return -EAGAIN;
}
EXPORT_SYMBOL_GPL(sdhci_try_get_regulator);
int sdhci_add_host(struct sdhci_host *host)
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index b3661ba..13b7791 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -314,7 +314,7 @@ static inline void *sdhci_priv(struct sdhci_host *host)
extern void sdhci_card_detect(struct sdhci_host *host);
extern int sdhci_add_host(struct sdhci_host *host);
extern void sdhci_remove_host(struct sdhci_host *host, int dead);
-extern void sdhci_try_get_regulator(struct sdhci_host *host);
+extern int sdhci_try_get_regulator(struct sdhci_host *host);
#ifdef CONFIG_PM
extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state);
--
1.7.0.4
---------------------------------------------------------------------
Intel Corporation SAS (French simplified joint stock company)
Registered headquarters: "Les Montalets"- 2, rue de Paris,
92196 Meudon Cedex, France
Registration Number: 302 456 199 R.C.S. NANTERRE
Capital: 4,572,000 Euros
This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.
0001-sdhci-dont-rescan-in-sdhci_try_get_regulator.patch
Description: 0001-sdhci-dont-rescan-in-sdhci_try_get_regulator.patch
_______________________________________________ MeeGo-kernel mailing list [email protected] http://lists.meego.com/listinfo/meego-kernel
