aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorPierre Ossman <drzeus@drzeus.cx>2007-12-02 13:58:16 -0500
committerPierre Ossman <drzeus@drzeus.cx>2007-12-12 14:01:00 -0500
commit84c46a53fc4ea4ff36df783a20187b2f65dd21cc (patch)
treecfd19b5b6afb71526512fe2241140d0057dd701e /drivers
parentc9fddbc4f844f5a16b5957c61fe2cfcb5c12f990 (diff)
sdhci: support JMicron JMB38x chips
The JMicron JMB38x chip doesn't support transfers that aren't 32-bit aligned (both size and start address). It also doesn't like switching between PIO and DMA mode, so it needs to be reset after each request. Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/host/sdhci.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index a5300f238d98..785bbdcf4a58 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -7,6 +7,10 @@
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or (at 8 * the Free Software Foundation; either version 2 of the License, or (at
9 * your option) any later version. 9 * your option) any later version.
10 *
11 * Thanks to the following companies for their support:
12 *
13 * - JMicron (hardware and technical support)
10 */ 14 */
11 15
12#include <linux/delay.h> 16#include <linux/delay.h>
@@ -47,6 +51,8 @@ static unsigned int debug_quirks = 0;
47#define SDHCI_QUIRK_32BIT_DMA_ADDR (1<<6) 51#define SDHCI_QUIRK_32BIT_DMA_ADDR (1<<6)
48/* Controller can only DMA chunk sizes that are a multiple of 32 bits */ 52/* Controller can only DMA chunk sizes that are a multiple of 32 bits */
49#define SDHCI_QUIRK_32BIT_DMA_SIZE (1<<7) 53#define SDHCI_QUIRK_32BIT_DMA_SIZE (1<<7)
54/* Controller needs to be reset after each request to stay stable */
55#define SDHCI_QUIRK_RESET_AFTER_REQUEST (1<<8)
50 56
51static const struct pci_device_id pci_ids[] __devinitdata = { 57static const struct pci_device_id pci_ids[] __devinitdata = {
52 { 58 {
@@ -111,6 +117,16 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
111 SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS, 117 SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS,
112 }, 118 },
113 119
120 {
121 .vendor = PCI_VENDOR_ID_JMICRON,
122 .device = PCI_DEVICE_ID_JMICRON_JMB38X_SD,
123 .subvendor = PCI_ANY_ID,
124 .subdevice = PCI_ANY_ID,
125 .driver_data = SDHCI_QUIRK_32BIT_DMA_ADDR |
126 SDHCI_QUIRK_32BIT_DMA_SIZE |
127 SDHCI_QUIRK_RESET_AFTER_REQUEST,
128 },
129
114 { /* Generic SD host controller */ 130 { /* Generic SD host controller */
115 PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00) 131 PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00)
116 }, 132 },
@@ -922,7 +938,8 @@ static void sdhci_tasklet_finish(unsigned long param)
922 */ 938 */
923 if (mrq->cmd->error || 939 if (mrq->cmd->error ||
924 (mrq->data && (mrq->data->error || 940 (mrq->data && (mrq->data->error ||
925 (mrq->data->stop && mrq->data->stop->error)))) { 941 (mrq->data->stop && mrq->data->stop->error))) ||
942 (host->chip->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST)) {
926 943
927 /* Some controllers need this kick or reset won't work here */ 944 /* Some controllers need this kick or reset won't work here */
928 if (host->chip->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) { 945 if (host->chip->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) {