aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/host/sdhci.c18
-rw-r--r--include/linux/pci_ids.h1
2 files changed, 19 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:
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index eafc9d6d2b3..65953822c9c 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1520,6 +1520,7 @@
#define PCI_DEVICE_ID_MARVELL_GT64260 0x6430
#define PCI_DEVICE_ID_MARVELL_MV64360 0x6460
#define PCI_DEVICE_ID_MARVELL_MV64460 0x6480
+#define PCI_DEVICE_ID_MARVELL_CAFE_SD 0x4101
#define PCI_VENDOR_ID_V3 0x11b0
#define PCI_DEVICE_ID_V3_V960 0x0001