diff options
author | Pierre Ossman <drzeus@drzeus.cx> | 2007-12-02 13:58:16 -0500 |
---|---|---|
committer | Pierre Ossman <drzeus@drzeus.cx> | 2007-12-12 14:01:00 -0500 |
commit | 84c46a53fc4ea4ff36df783a20187b2f65dd21cc (patch) | |
tree | cfd19b5b6afb71526512fe2241140d0057dd701e /drivers/mmc/host | |
parent | c9fddbc4f844f5a16b5957c61fe2cfcb5c12f990 (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/mmc/host')
-rw-r--r-- | drivers/mmc/host/sdhci.c | 19 |
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 | ||
51 | static const struct pci_device_id pci_ids[] __devinitdata = { | 57 | static 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) { |