aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-12-18 11:03:01 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-12-18 11:03:01 -0500
commitd55653377df36f8c04a966f3420335f1a0eb4d83 (patch)
treea986fbd0e8310b1fec44886001f8aeecce32f42a
parentc63a1190368771b8207d86c4217ae4afdf1cbd5e (diff)
parentcc3000e4ef13fa9f388f5a37f11c0fa3cc68112b (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc: mmc: remove unused 'mode' from the mmc_host structure sdhci: support JMicron JMB38x chips sdhci: use PIO when DMA can't satisfy the request sdhci: don't warn about sdhci 2.0 controllers sdhci: describe quirks
-rw-r--r--drivers/mmc/host/sdhci.c63
-rw-r--r--drivers/mmc/host/sdhci.h3
-rw-r--r--include/linux/mmc/host.h4
-rw-r--r--include/linux/pci_ids.h1
4 files changed, 61 insertions, 10 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index ff59d2e0475b..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>
@@ -26,13 +30,29 @@
26 30
27static unsigned int debug_quirks = 0; 31static unsigned int debug_quirks = 0;
28 32
33/*
34 * Different quirks to handle when the hardware deviates from a strict
35 * interpretation of the SDHCI specification.
36 */
37
38/* Controller doesn't honor resets unless we touch the clock register */
29#define SDHCI_QUIRK_CLOCK_BEFORE_RESET (1<<0) 39#define SDHCI_QUIRK_CLOCK_BEFORE_RESET (1<<0)
40/* Controller has bad caps bits, but really supports DMA */
30#define SDHCI_QUIRK_FORCE_DMA (1<<1) 41#define SDHCI_QUIRK_FORCE_DMA (1<<1)
31/* Controller doesn't like some resets when there is no card inserted. */ 42/* Controller doesn't like some resets when there is no card inserted. */
32#define SDHCI_QUIRK_NO_CARD_NO_RESET (1<<2) 43#define SDHCI_QUIRK_NO_CARD_NO_RESET (1<<2)
44/* Controller doesn't like clearing the power reg before a change */
33#define SDHCI_QUIRK_SINGLE_POWER_WRITE (1<<3) 45#define SDHCI_QUIRK_SINGLE_POWER_WRITE (1<<3)
46/* Controller has flaky internal state so reset it on each ios change */
34#define SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS (1<<4) 47#define SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS (1<<4)
48/* Controller has an unusable DMA engine */
35#define SDHCI_QUIRK_BROKEN_DMA (1<<5) 49#define SDHCI_QUIRK_BROKEN_DMA (1<<5)
50/* Controller can only DMA from 32-bit aligned addresses */
51#define SDHCI_QUIRK_32BIT_DMA_ADDR (1<<6)
52/* Controller can only DMA chunk sizes that are a multiple of 32 bits */
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)
36 56
37static const struct pci_device_id pci_ids[] __devinitdata = { 57static const struct pci_device_id pci_ids[] __devinitdata = {
38 { 58 {
@@ -97,6 +117,16 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
97 SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS, 117 SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS,
98 }, 118 },
99 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
100 { /* Generic SD host controller */ 130 { /* Generic SD host controller */
101 PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00) 131 PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00)
102 }, 132 },
@@ -419,7 +449,29 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
419 449
420 writeb(count, host->ioaddr + SDHCI_TIMEOUT_CONTROL); 450 writeb(count, host->ioaddr + SDHCI_TIMEOUT_CONTROL);
421 451
422 if (host->flags & SDHCI_USE_DMA) { 452 if (host->flags & SDHCI_USE_DMA)
453 host->flags |= SDHCI_REQ_USE_DMA;
454
455 if (unlikely((host->flags & SDHCI_REQ_USE_DMA) &&
456 (host->chip->quirks & SDHCI_QUIRK_32BIT_DMA_SIZE) &&
457 ((data->blksz * data->blocks) & 0x3))) {
458 DBG("Reverting to PIO because of transfer size (%d)\n",
459 data->blksz * data->blocks);
460 host->flags &= ~SDHCI_REQ_USE_DMA;
461 }
462
463 /*
464 * The assumption here being that alignment is the same after
465 * translation to device address space.
466 */
467 if (unlikely((host->flags & SDHCI_REQ_USE_DMA) &&
468 (host->chip->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) &&
469 (data->sg->offset & 0x3))) {
470 DBG("Reverting to PIO because of bad alignment\n");
471 host->flags &= ~SDHCI_REQ_USE_DMA;
472 }
473
474 if (host->flags & SDHCI_REQ_USE_DMA) {
423 int count; 475 int count;
424 476
425 count = pci_map_sg(host->chip->pdev, data->sg, data->sg_len, 477 count = pci_map_sg(host->chip->pdev, data->sg, data->sg_len,
@@ -456,7 +508,7 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host,
456 mode |= SDHCI_TRNS_MULTI; 508 mode |= SDHCI_TRNS_MULTI;
457 if (data->flags & MMC_DATA_READ) 509 if (data->flags & MMC_DATA_READ)
458 mode |= SDHCI_TRNS_READ; 510 mode |= SDHCI_TRNS_READ;
459 if (host->flags & SDHCI_USE_DMA) 511 if (host->flags & SDHCI_REQ_USE_DMA)
460 mode |= SDHCI_TRNS_DMA; 512 mode |= SDHCI_TRNS_DMA;
461 513
462 writew(mode, host->ioaddr + SDHCI_TRANSFER_MODE); 514 writew(mode, host->ioaddr + SDHCI_TRANSFER_MODE);
@@ -472,7 +524,7 @@ static void sdhci_finish_data(struct sdhci_host *host)
472 data = host->data; 524 data = host->data;
473 host->data = NULL; 525 host->data = NULL;
474 526
475 if (host->flags & SDHCI_USE_DMA) { 527 if (host->flags & SDHCI_REQ_USE_DMA) {
476 pci_unmap_sg(host->chip->pdev, data->sg, data->sg_len, 528 pci_unmap_sg(host->chip->pdev, data->sg, data->sg_len,
477 (data->flags & MMC_DATA_READ)?PCI_DMA_FROMDEVICE:PCI_DMA_TODEVICE); 529 (data->flags & MMC_DATA_READ)?PCI_DMA_FROMDEVICE:PCI_DMA_TODEVICE);
478 } 530 }
@@ -886,7 +938,8 @@ static void sdhci_tasklet_finish(unsigned long param)
886 */ 938 */
887 if (mrq->cmd->error || 939 if (mrq->cmd->error ||
888 (mrq->data && (mrq->data->error || 940 (mrq->data && (mrq->data->error ||
889 (mrq->data->stop && mrq->data->stop->error)))) { 941 (mrq->data->stop && mrq->data->stop->error))) ||
942 (host->chip->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST)) {
890 943
891 /* Some controllers need this kick or reset won't work here */ 944 /* Some controllers need this kick or reset won't work here */
892 if (host->chip->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) { 945 if (host->chip->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) {
@@ -1284,7 +1337,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
1284 1337
1285 version = readw(host->ioaddr + SDHCI_HOST_VERSION); 1338 version = readw(host->ioaddr + SDHCI_HOST_VERSION);
1286 version = (version & SDHCI_SPEC_VER_MASK) >> SDHCI_SPEC_VER_SHIFT; 1339 version = (version & SDHCI_SPEC_VER_MASK) >> SDHCI_SPEC_VER_SHIFT;
1287 if (version != 0) { 1340 if (version > 1) {
1288 printk(KERN_ERR "%s: Unknown controller version (%d). " 1341 printk(KERN_ERR "%s: Unknown controller version (%d). "
1289 "You may experience problems.\n", host->slot_descr, 1342 "You may experience problems.\n", host->slot_descr,
1290 version); 1343 version);
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 05195ea900f4..e4d77b038bfa 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -171,7 +171,8 @@ struct sdhci_host {
171 spinlock_t lock; /* Mutex */ 171 spinlock_t lock; /* Mutex */
172 172
173 int flags; /* Host attributes */ 173 int flags; /* Host attributes */
174#define SDHCI_USE_DMA (1<<0) 174#define SDHCI_USE_DMA (1<<0) /* Host is DMA capable */
175#define SDHCI_REQ_USE_DMA (1<<1) /* Use DMA for this req. */
175 176
176 unsigned int max_clk; /* Max possible freq (MHz) */ 177 unsigned int max_clk; /* Max possible freq (MHz) */
177 unsigned int timeout_clk; /* Timeout freq (KHz) */ 178 unsigned int timeout_clk; /* Timeout freq (KHz) */
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 125eee1407ff..7ab962fa1d73 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -118,10 +118,6 @@ struct mmc_host {
118 unsigned int removed:1; /* host is being removed */ 118 unsigned int removed:1; /* host is being removed */
119#endif 119#endif
120 120
121 unsigned int mode; /* current card mode of host */
122#define MMC_MODE_MMC 0
123#define MMC_MODE_SD 1
124
125 struct mmc_card *card; /* device attached to this host */ 121 struct mmc_card *card; /* device attached to this host */
126 122
127 wait_queue_head_t wq; 123 wait_queue_head_t wq;
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 111aa10f1136..023656d2f1da 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2148,6 +2148,7 @@
2148#define PCI_DEVICE_ID_JMICRON_JMB365 0x2365 2148#define PCI_DEVICE_ID_JMICRON_JMB365 0x2365
2149#define PCI_DEVICE_ID_JMICRON_JMB366 0x2366 2149#define PCI_DEVICE_ID_JMICRON_JMB366 0x2366
2150#define PCI_DEVICE_ID_JMICRON_JMB368 0x2368 2150#define PCI_DEVICE_ID_JMICRON_JMB368 0x2368
2151#define PCI_DEVICE_ID_JMICRON_JMB38X_SD 0x2381
2151 2152
2152#define PCI_VENDOR_ID_KORENIX 0x1982 2153#define PCI_VENDOR_ID_KORENIX 0x1982
2153#define PCI_DEVICE_ID_KORENIX_JETCARDF0 0x1600 2154#define PCI_DEVICE_ID_KORENIX_JETCARDF0 0x1600