diff options
-rw-r--r-- | drivers/mmc/host/sdhci-pci.c | 41 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.c | 3 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.h | 4 |
3 files changed, 47 insertions, 1 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 | |||
91 | static 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 | |||
106 | static 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 | ||
122 | static 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 | |||
98 | static const struct sdhci_pci_fixes sdhci_ene_712 = { | 131 | static 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, |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index c6d1bd8d4ac4..483b78eee3ac 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -1687,7 +1687,8 @@ int sdhci_add_host(struct sdhci_host *host) | |||
1687 | host->version); | 1687 | host->version); |
1688 | } | 1688 | } |
1689 | 1689 | ||
1690 | caps = sdhci_readl(host, SDHCI_CAPABILITIES); | 1690 | caps = (host->quirks & SDHCI_QUIRK_MISSING_CAPS) ? host->caps : |
1691 | sdhci_readl(host, SDHCI_CAPABILITIES); | ||
1691 | 1692 | ||
1692 | if (host->quirks & SDHCI_QUIRK_FORCE_DMA) | 1693 | if (host->quirks & SDHCI_QUIRK_FORCE_DMA) |
1693 | host->flags |= SDHCI_USE_SDMA; | 1694 | host->flags |= SDHCI_USE_SDMA; |
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index c8468134adc9..b1839a315b86 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -240,6 +240,8 @@ struct sdhci_host { | |||
240 | #define SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN (1<<25) | 240 | #define SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN (1<<25) |
241 | /* Controller cannot support End Attribute in NOP ADMA descriptor */ | 241 | /* Controller cannot support End Attribute in NOP ADMA descriptor */ |
242 | #define SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC (1<<26) | 242 | #define SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC (1<<26) |
243 | /* Controller is missing device caps. Use caps provided by host */ | ||
244 | #define SDHCI_QUIRK_MISSING_CAPS (1<<27) | ||
243 | 245 | ||
244 | int irq; /* Device IRQ */ | 246 | int irq; /* Device IRQ */ |
245 | void __iomem * ioaddr; /* Mapped address */ | 247 | void __iomem * ioaddr; /* Mapped address */ |
@@ -292,6 +294,8 @@ struct sdhci_host { | |||
292 | 294 | ||
293 | struct timer_list timer; /* Timer for timeouts */ | 295 | struct timer_list timer; /* Timer for timeouts */ |
294 | 296 | ||
297 | unsigned int caps; /* Alternative capabilities */ | ||
298 | |||
295 | unsigned long private[0] ____cacheline_aligned; | 299 | unsigned long private[0] ____cacheline_aligned; |
296 | }; | 300 | }; |
297 | 301 | ||