summaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/sdhci.c
diff options
context:
space:
mode:
authorAndres Salomon <dilinger@queued.net>2008-07-04 10:00:03 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-04 10:40:09 -0700
commite08c1694d9e2138204f2b79b73f0f159074ce2f5 (patch)
tree78078c43810ab607516445c9543220f26306eecf /drivers/mmc/host/sdhci.c
parent491539982aa01fa71de93c2a06ac5d890d4cf1e2 (diff)
downloadkernel-crypto-e08c1694d9e2138204f2b79b73f0f159074ce2f5.tar.gz
kernel-crypto-e08c1694d9e2138204f2b79b73f0f159074ce2f5.tar.xz
kernel-crypto-e08c1694d9e2138204f2b79b73f0f159074ce2f5.zip
olpc: sdhci: add quirk for the Marvell CaFe's vdd/powerup issue
This has been sitting around unloved for way too long.. The Marvell CaFe chip's SD implementation chokes during card insertion if one attempts to set the voltage and power up in the same SDHCI_POWER_CONTROL register write. This adds a quirk that does that particular dance in two steps. It also adds an entry to pci_ids.h for the CaFe chip's SD device. Signed-off-by: Andres Salomon <dilinger@debian.org> Cc: Pierre Ossman <drzeus-list@drzeus.cx> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/mmc/host/sdhci.c')
-rw-r--r--drivers/mmc/host/sdhci.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 07c2048b230..5b74c8cf440 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -55,6 +55,8 @@ static unsigned int debug_quirks = 0;
#define SDHCI_QUIRK_32BIT_DMA_SIZE (1<<7)
/* Controller needs to be reset after each request to stay stable */
#define SDHCI_QUIRK_RESET_AFTER_REQUEST (1<<8)
+/* Controller needs voltage and power writes to happen separately */
+#define SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER (1<<9)
static const struct pci_device_id pci_ids[] __devinitdata = {
{
@@ -128,6 +130,14 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
},
{
+ .vendor = PCI_VENDOR_ID_MARVELL,
+ .device = PCI_DEVICE_ID_MARVELL_CAFE_SD,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER,
+ },
+
+ {
.vendor = PCI_VENDOR_ID_JMICRON,
.device = PCI_DEVICE_ID_JMICRON_JMB38X_SD,
.subvendor = PCI_ANY_ID,
@@ -774,6 +784,14 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
BUG();
}
+ /*
+ * At least the CaFe chip gets confused if we set the voltage
+ * and set turn on power at the same time, so set the voltage first.
+ */
+ if ((host->chip->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER))
+ writeb(pwr & ~SDHCI_POWER_ON,
+ host->ioaddr + SDHCI_POWER_CONTROL);
+
writeb(pwr, host->ioaddr + SDHCI_POWER_CONTROL);
out: