aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorHarald Welte <HaraldWelte@viatech.com>2009-06-18 10:53:38 -0400
committerPierre Ossman <pierre@ossman.eu>2009-06-21 15:00:59 -0400
commit557b06971b1f05cbadec2f376a305ee1954e9b0d (patch)
tree08f0fa936e2483afd3e91fc17277fcc45d5c3469 /drivers/mmc
parentfe9db6cbf16ed64f882999dc0bffef0c65f70c4f (diff)
sdhci: Specific quirk vor VIA SDHCI controller in VX855ES
The SDHCI controller found in the VX855ES requires 10ms delay between applying power and applying clock. This issue has been discovered and documented by the OLPC XO1.5 team. Signed-off-by: Harald Welte <HaraldWelte@viatech.com> Signed-off-by: Pierre Ossman <pierre@ossman.eu>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/sdhci-pci.c20
-rw-r--r--drivers/mmc/host/sdhci.c7
-rw-r--r--drivers/mmc/host/sdhci.h2
3 files changed, 29 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 65be27995d5c..2f15cc17d887 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -284,6 +284,18 @@ static const struct sdhci_pci_fixes sdhci_jmicron = {
284 .resume = jmicron_resume, 284 .resume = jmicron_resume,
285}; 285};
286 286
287static int via_probe(struct sdhci_pci_chip *chip)
288{
289 if (chip->pdev->revision == 0x10)
290 chip->quirks |= SDHCI_QUIRK_DELAY_AFTER_POWER;
291
292 return 0;
293}
294
295static const struct sdhci_pci_fixes sdhci_via = {
296 .probe = via_probe,
297};
298
287static const struct pci_device_id pci_ids[] __devinitdata = { 299static const struct pci_device_id pci_ids[] __devinitdata = {
288 { 300 {
289 .vendor = PCI_VENDOR_ID_RICOH, 301 .vendor = PCI_VENDOR_ID_RICOH,
@@ -349,6 +361,14 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
349 .driver_data = (kernel_ulong_t)&sdhci_jmicron, 361 .driver_data = (kernel_ulong_t)&sdhci_jmicron,
350 }, 362 },
351 363
364 {
365 .vendor = PCI_VENDOR_ID_VIA,
366 .device = 0x95d0,
367 .subvendor = PCI_ANY_ID,
368 .subdevice = PCI_ANY_ID,
369 .driver_data = (kernel_ulong_t)&sdhci_via,
370 },
371
352 { /* Generic SD host controller */ 372 { /* Generic SD host controller */
353 PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00) 373 PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00)
354 }, 374 },
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index c7586739be1e..f4066fdc8906 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1057,6 +1057,13 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
1057 pwr |= SDHCI_POWER_ON; 1057 pwr |= SDHCI_POWER_ON;
1058 1058
1059 sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); 1059 sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
1060
1061 /*
1062 * Some controllers need an extra 10ms delay of 10ms before they
1063 * can apply clock after applying power
1064 */
1065 if ((host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER))
1066 mdelay(10);
1060} 1067}
1061 1068
1062/*****************************************************************************\ 1069/*****************************************************************************\
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 5d37dd94b53f..831ddf7dcb49 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -230,6 +230,8 @@ struct sdhci_host {
230#define SDHCI_QUIRK_NO_MULTIBLOCK (1<<21) 230#define SDHCI_QUIRK_NO_MULTIBLOCK (1<<21)
231/* Controller can only handle 1-bit data transfers */ 231/* Controller can only handle 1-bit data transfers */
232#define SDHCI_QUIRK_FORCE_1_BIT_DATA (1<<22) 232#define SDHCI_QUIRK_FORCE_1_BIT_DATA (1<<22)
233/* Controller needs 10ms delay between applying power and clock */
234#define SDHCI_QUIRK_DELAY_AFTER_POWER (1<<23)
233 235
234 int irq; /* Device IRQ */ 236 int irq; /* Device IRQ */
235 void __iomem * ioaddr; /* Mapped address */ 237 void __iomem * ioaddr; /* Mapped address */