diff options
author | Pierre Ossman <drzeus@drzeus.cx> | 2007-12-02 19:58:16 +0100 |
---|---|---|
committer | Pierre Ossman <drzeus@drzeus.cx> | 2007-12-12 20:01:00 +0100 |
commit | 84c46a53fc4ea4ff36df783a20187b2f65dd21cc (patch) | |
tree | cfd19b5b6afb71526512fe2241140d0057dd701e /drivers/mmc/host/sdhci.c | |
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/sdhci.c')
-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 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. + * + * Thanks to the following companies for their support: + * + * - JMicron (hardware and technical support) */ #include <linux/delay.h> @@ -47,6 +51,8 @@ static unsigned int debug_quirks = 0; #define SDHCI_QUIRK_32BIT_DMA_ADDR (1<<6) /* Controller can only DMA chunk sizes that are a multiple of 32 bits */ #define SDHCI_QUIRK_32BIT_DMA_SIZE (1<<7) +/* Controller needs to be reset after each request to stay stable */ +#define SDHCI_QUIRK_RESET_AFTER_REQUEST (1<<8) static const struct pci_device_id pci_ids[] __devinitdata = { { @@ -111,6 +117,16 @@ static const struct pci_device_id pci_ids[] __devinitdata = { SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS, }, + { + .vendor = PCI_VENDOR_ID_JMICRON, + .device = PCI_DEVICE_ID_JMICRON_JMB38X_SD, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = SDHCI_QUIRK_32BIT_DMA_ADDR | + SDHCI_QUIRK_32BIT_DMA_SIZE | + SDHCI_QUIRK_RESET_AFTER_REQUEST, + }, + { /* Generic SD host controller */ PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00) }, @@ -922,7 +938,8 @@ static void sdhci_tasklet_finish(unsigned long param) */ if (mrq->cmd->error || (mrq->data && (mrq->data->error || - (mrq->data->stop && mrq->data->stop->error)))) { + (mrq->data->stop && mrq->data->stop->error))) || + (host->chip->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST)) { /* Some controllers need this kick or reset won't work here */ if (host->chip->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) { |