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

+61 -10
+58 -5
drivers/mmc/host/sdhci.c
··· 7 7 * it under the terms of the GNU General Public License as published by 8 8 * the Free Software Foundation; either version 2 of the License, or (at 9 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 16 #include <linux/delay.h> ··· 30 26 31 27 static unsigned int debug_quirks = 0; 32 28 29 + /* 30 + * Different quirks to handle when the hardware deviates from a strict 31 + * interpretation of the SDHCI specification. 32 + */ 33 + 34 + /* Controller doesn't honor resets unless we touch the clock register */ 33 35 #define SDHCI_QUIRK_CLOCK_BEFORE_RESET (1<<0) 36 + /* Controller has bad caps bits, but really supports DMA */ 34 37 #define SDHCI_QUIRK_FORCE_DMA (1<<1) 35 38 /* Controller doesn't like some resets when there is no card inserted. */ 36 39 #define SDHCI_QUIRK_NO_CARD_NO_RESET (1<<2) 40 + /* Controller doesn't like clearing the power reg before a change */ 37 41 #define SDHCI_QUIRK_SINGLE_POWER_WRITE (1<<3) 42 + /* Controller has flaky internal state so reset it on each ios change */ 38 43 #define SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS (1<<4) 44 + /* Controller has an unusable DMA engine */ 39 45 #define SDHCI_QUIRK_BROKEN_DMA (1<<5) 46 + /* Controller can only DMA from 32-bit aligned addresses */ 47 + #define SDHCI_QUIRK_32BIT_DMA_ADDR (1<<6) 48 + /* Controller can only DMA chunk sizes that are a multiple of 32 bits */ 49 + #define SDHCI_QUIRK_32BIT_DMA_SIZE (1<<7) 50 + /* Controller needs to be reset after each request to stay stable */ 51 + #define SDHCI_QUIRK_RESET_AFTER_REQUEST (1<<8) 40 52 41 53 static const struct pci_device_id pci_ids[] __devinitdata = { 42 54 { ··· 115 95 .subdevice = PCI_ANY_ID, 116 96 .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE | 117 97 SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS, 98 + }, 99 + 100 + { 101 + .vendor = PCI_VENDOR_ID_JMICRON, 102 + .device = PCI_DEVICE_ID_JMICRON_JMB38X_SD, 103 + .subvendor = PCI_ANY_ID, 104 + .subdevice = PCI_ANY_ID, 105 + .driver_data = SDHCI_QUIRK_32BIT_DMA_ADDR | 106 + SDHCI_QUIRK_32BIT_DMA_SIZE | 107 + SDHCI_QUIRK_RESET_AFTER_REQUEST, 118 108 }, 119 109 120 110 { /* Generic SD host controller */ ··· 449 419 450 420 writeb(count, host->ioaddr + SDHCI_TIMEOUT_CONTROL); 451 421 452 - if (host->flags & SDHCI_USE_DMA) { 422 + if (host->flags & SDHCI_USE_DMA) 423 + host->flags |= SDHCI_REQ_USE_DMA; 424 + 425 + if (unlikely((host->flags & SDHCI_REQ_USE_DMA) && 426 + (host->chip->quirks & SDHCI_QUIRK_32BIT_DMA_SIZE) && 427 + ((data->blksz * data->blocks) & 0x3))) { 428 + DBG("Reverting to PIO because of transfer size (%d)\n", 429 + data->blksz * data->blocks); 430 + host->flags &= ~SDHCI_REQ_USE_DMA; 431 + } 432 + 433 + /* 434 + * The assumption here being that alignment is the same after 435 + * translation to device address space. 436 + */ 437 + if (unlikely((host->flags & SDHCI_REQ_USE_DMA) && 438 + (host->chip->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) && 439 + (data->sg->offset & 0x3))) { 440 + DBG("Reverting to PIO because of bad alignment\n"); 441 + host->flags &= ~SDHCI_REQ_USE_DMA; 442 + } 443 + 444 + if (host->flags & SDHCI_REQ_USE_DMA) { 453 445 int count; 454 446 455 447 count = pci_map_sg(host->chip->pdev, data->sg, data->sg_len, ··· 508 456 mode |= SDHCI_TRNS_MULTI; 509 457 if (data->flags & MMC_DATA_READ) 510 458 mode |= SDHCI_TRNS_READ; 511 - if (host->flags & SDHCI_USE_DMA) 459 + if (host->flags & SDHCI_REQ_USE_DMA) 512 460 mode |= SDHCI_TRNS_DMA; 513 461 514 462 writew(mode, host->ioaddr + SDHCI_TRANSFER_MODE); ··· 524 472 data = host->data; 525 473 host->data = NULL; 526 474 527 - if (host->flags & SDHCI_USE_DMA) { 475 + if (host->flags & SDHCI_REQ_USE_DMA) { 528 476 pci_unmap_sg(host->chip->pdev, data->sg, data->sg_len, 529 477 (data->flags & MMC_DATA_READ)?PCI_DMA_FROMDEVICE:PCI_DMA_TODEVICE); 530 478 } ··· 938 886 */ 939 887 if (mrq->cmd->error || 940 888 (mrq->data && (mrq->data->error || 941 - (mrq->data->stop && mrq->data->stop->error)))) { 889 + (mrq->data->stop && mrq->data->stop->error))) || 890 + (host->chip->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST)) { 942 891 943 892 /* Some controllers need this kick or reset won't work here */ 944 893 if (host->chip->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) { ··· 1337 1284 1338 1285 version = readw(host->ioaddr + SDHCI_HOST_VERSION); 1339 1286 version = (version & SDHCI_SPEC_VER_MASK) >> SDHCI_SPEC_VER_SHIFT; 1340 - if (version != 0) { 1287 + if (version > 1) { 1341 1288 printk(KERN_ERR "%s: Unknown controller version (%d). " 1342 1289 "You may experience problems.\n", host->slot_descr, 1343 1290 version);
+2 -1
drivers/mmc/host/sdhci.h
··· 171 171 spinlock_t lock; /* Mutex */ 172 172 173 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 177 unsigned int max_clk; /* Max possible freq (MHz) */ 177 178 unsigned int timeout_clk; /* Timeout freq (KHz) */
-4
include/linux/mmc/host.h
··· 118 118 unsigned int removed:1; /* host is being removed */ 119 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 121 struct mmc_card *card; /* device attached to this host */ 126 122 127 123 wait_queue_head_t wq;
+1
include/linux/pci_ids.h
··· 2148 2148 #define PCI_DEVICE_ID_JMICRON_JMB365 0x2365 2149 2149 #define PCI_DEVICE_ID_JMICRON_JMB366 0x2366 2150 2150 #define PCI_DEVICE_ID_JMICRON_JMB368 0x2368 2151 + #define PCI_DEVICE_ID_JMICRON_JMB38X_SD 0x2381 2151 2152 2152 2153 #define PCI_VENDOR_ID_KORENIX 0x1982 2153 2154 #define PCI_DEVICE_ID_KORENIX_JETCARDF0 0x1600