aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/sdhci-pci.c
diff options
context:
space:
mode:
authorMaxim Levitsky <maximlevitsky@gmail.com>2010-08-10 21:01:42 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-11 11:59:03 -0400
commitccc92c23240cdf952ef7cc39ba563910dcbc9cbe (patch)
treed656aad9e86fff59c1a5cbece4a5ccb019c35011 /drivers/mmc/host/sdhci-pci.c
parent4c2ef25fe0b847d2ae818f74758ddb0be1c27d8e (diff)
mmc: make sdhci work with ricoh mmc controller
The current way of disabling it is not well tested by vendor and has all kinds of bugs that show up on resume from ram/disk. A very good example is a dead SDHCI controller. Old way of disabling is still supported by continuing to use CONFIG_MMC_RICOH_MMC. Based on 'http://list.drzeus.cx/pipermail/sdhci-devel/2007-December/002085.html' Therefore most of the credit for this goes to Andrew de Quincey Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com> Cc: Andrew de Quincey <adq_dvb@lidskialf.net> Acked-by: Philip Langdale <philipl@overt.org> Cc: "Rafael J. Wysocki" <rjw@sisk.pl> Cc: <linux-mmc@vger.kernel.org> 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-pci.c')
-rw-r--r--drivers/mmc/host/sdhci-pci.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 65483fdea45b..e0214316aedb 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -17,6 +17,7 @@
17#include <linux/pci.h> 17#include <linux/pci.h>
18#include <linux/dma-mapping.h> 18#include <linux/dma-mapping.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/device.h>
20 21
21#include <linux/mmc/host.h> 22#include <linux/mmc/host.h>
22 23
@@ -84,7 +85,30 @@ static int ricoh_probe(struct sdhci_pci_chip *chip)
84 if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG || 85 if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG ||
85 chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SONY) 86 chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SONY)
86 chip->quirks |= SDHCI_QUIRK_NO_CARD_NO_RESET; 87 chip->quirks |= SDHCI_QUIRK_NO_CARD_NO_RESET;
88 return 0;
89}
90
91static int ricoh_mmc_probe_slot(struct sdhci_pci_slot *slot)
92{
93 slot->host->caps =
94 ((0x21 << SDHCI_TIMEOUT_CLK_SHIFT)
95 & SDHCI_TIMEOUT_CLK_MASK) |
96
97 ((0x21 << SDHCI_CLOCK_BASE_SHIFT)
98 & SDHCI_CLOCK_BASE_MASK) |
87 99
100 SDHCI_TIMEOUT_CLK_UNIT |
101 SDHCI_CAN_VDD_330 |
102 SDHCI_CAN_DO_SDMA;
103 return 0;
104}
105
106static int ricoh_mmc_resume(struct sdhci_pci_chip *chip)
107{
108 /* Apply a delay to allow controller to settle */
109 /* Otherwise it becomes confused if card state changed
110 during suspend */
111 msleep(500);
88 return 0; 112 return 0;
89} 113}
90 114
@@ -95,6 +119,15 @@ static const struct sdhci_pci_fixes sdhci_ricoh = {
95 SDHCI_QUIRK_CLOCK_BEFORE_RESET, 119 SDHCI_QUIRK_CLOCK_BEFORE_RESET,
96}; 120};
97 121
122static const struct sdhci_pci_fixes sdhci_ricoh_mmc = {
123 .probe_slot = ricoh_mmc_probe_slot,
124 .resume = ricoh_mmc_resume,
125 .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR |
126 SDHCI_QUIRK_CLOCK_BEFORE_RESET |
127 SDHCI_QUIRK_NO_CARD_NO_RESET |
128 SDHCI_QUIRK_MISSING_CAPS
129};
130
98static const struct sdhci_pci_fixes sdhci_ene_712 = { 131static const struct sdhci_pci_fixes sdhci_ene_712 = {
99 .quirks = SDHCI_QUIRK_SINGLE_POWER_WRITE | 132 .quirks = SDHCI_QUIRK_SINGLE_POWER_WRITE |
100 SDHCI_QUIRK_BROKEN_DMA, 133 SDHCI_QUIRK_BROKEN_DMA,
@@ -374,6 +407,14 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
374 }, 407 },
375 408
376 { 409 {
410 .vendor = PCI_VENDOR_ID_RICOH,
411 .device = 0x843,
412 .subvendor = PCI_ANY_ID,
413 .subdevice = PCI_ANY_ID,
414 .driver_data = (kernel_ulong_t)&sdhci_ricoh_mmc,
415 },
416
417 {
377 .vendor = PCI_VENDOR_ID_ENE, 418 .vendor = PCI_VENDOR_ID_ENE,
378 .device = PCI_DEVICE_ID_ENE_CB712_SD, 419 .device = PCI_DEVICE_ID_ENE_CB712_SD,
379 .subvendor = PCI_ANY_ID, 420 .subvendor = PCI_ANY_ID,