diff options
author | Pierre Ossman <drzeus@drzeus.cx> | 2008-07-28 18:11:16 -0400 |
---|---|---|
committer | Pierre Ossman <drzeus@drzeus.cx> | 2008-08-01 13:03:35 -0400 |
commit | 4a3cba32cb514168bb2516c045b178e6660421d1 (patch) | |
tree | 2722540273e51cae20f80e85b9c275960ceb39b3 /drivers/mmc | |
parent | 94ad374a0751f40d25e22e036c37f7263569d24c (diff) |
sdhci: handle bug in JMB38x for sizes < 4 bytes
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/sdhci-pci.c | 3 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.c | 9 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.h | 2 |
3 files changed, 13 insertions, 1 deletions
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index deb607c52c0d..fcb14c2346cc 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
@@ -143,7 +143,8 @@ static int jmicron_probe(struct sdhci_pci_chip *chip) | |||
143 | chip->quirks |= SDHCI_QUIRK_32BIT_DMA_ADDR | | 143 | chip->quirks |= SDHCI_QUIRK_32BIT_DMA_ADDR | |
144 | SDHCI_QUIRK_32BIT_DMA_SIZE | | 144 | SDHCI_QUIRK_32BIT_DMA_SIZE | |
145 | SDHCI_QUIRK_32BIT_ADMA_SIZE | | 145 | SDHCI_QUIRK_32BIT_ADMA_SIZE | |
146 | SDHCI_QUIRK_RESET_AFTER_REQUEST; | 146 | SDHCI_QUIRK_RESET_AFTER_REQUEST | |
147 | SDHCI_QUIRK_BROKEN_SMALL_PIO; | ||
147 | } | 148 | } |
148 | 149 | ||
149 | /* | 150 | /* |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 5f95e10229b5..be09739f692d 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -278,6 +278,15 @@ static void sdhci_transfer_pio(struct sdhci_host *host) | |||
278 | else | 278 | else |
279 | mask = SDHCI_SPACE_AVAILABLE; | 279 | mask = SDHCI_SPACE_AVAILABLE; |
280 | 280 | ||
281 | /* | ||
282 | * Some controllers (JMicron JMB38x) mess up the buffer bits | ||
283 | * for transfers < 4 bytes. As long as it is just one block, | ||
284 | * we can ignore the bits. | ||
285 | */ | ||
286 | if ((host->quirks & SDHCI_QUIRK_BROKEN_SMALL_PIO) && | ||
287 | (host->data->blocks == 1)) | ||
288 | mask = ~0; | ||
289 | |||
281 | while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) { | 290 | while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) { |
282 | if (host->data->flags & MMC_DATA_READ) | 291 | if (host->data->flags & MMC_DATA_READ) |
283 | sdhci_read_block_pio(host); | 292 | sdhci_read_block_pio(host); |
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index e354faee5df0..197d4a05f4ae 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -206,6 +206,8 @@ struct sdhci_host { | |||
206 | #define SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER (1<<11) | 206 | #define SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER (1<<11) |
207 | /* Controller provides an incorrect timeout value for transfers */ | 207 | /* Controller provides an incorrect timeout value for transfers */ |
208 | #define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL (1<<12) | 208 | #define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL (1<<12) |
209 | /* Controller has an issue with buffer bits for small transfers */ | ||
210 | #define SDHCI_QUIRK_BROKEN_SMALL_PIO (1<<13) | ||
209 | 211 | ||
210 | int irq; /* Device IRQ */ | 212 | int irq; /* Device IRQ */ |
211 | void __iomem * ioaddr; /* Mapped address */ | 213 | void __iomem * ioaddr; /* Mapped address */ |