diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-07-02 19:35:07 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-07-02 19:35:07 -0400 |
commit | f82bc1762e0e74b7e0040a4d83be06d32c37fc2e (patch) | |
tree | 685e0c3b5a962928efb66e36d9185febddaf5964 /drivers | |
parent | 4ebd9ab387b39c44165cd296a6637082a4f0f66a (diff) | |
parent | 4cca56c50427eecfa2428cdee722848cd82f443c (diff) |
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-mmc
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-mmc:
[MMC] sdhci: remove duplicate error message
[MMC] sdhci: force DMA on some controllers
[MMC] sdhci: quirk for broken reset
[MMC] sdhci: Add SDHCI controller ids
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/sdhci.c | 55 |
1 files changed, 49 insertions, 6 deletions
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 74134699ccee..893319108ba4 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c | |||
@@ -32,9 +32,39 @@ static unsigned int debug_nodma = 0; | |||
32 | static unsigned int debug_forcedma = 0; | 32 | static unsigned int debug_forcedma = 0; |
33 | static unsigned int debug_quirks = 0; | 33 | static unsigned int debug_quirks = 0; |
34 | 34 | ||
35 | #define SDHCI_QUIRK_CLOCK_BEFORE_RESET (1<<0) | ||
36 | #define SDHCI_QUIRK_FORCE_DMA (1<<1) | ||
37 | |||
35 | static const struct pci_device_id pci_ids[] __devinitdata = { | 38 | static const struct pci_device_id pci_ids[] __devinitdata = { |
36 | /* handle any SD host controller */ | 39 | { |
37 | {PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00)}, | 40 | .vendor = PCI_VENDOR_ID_RICOH, |
41 | .device = PCI_DEVICE_ID_RICOH_R5C822, | ||
42 | .subvendor = PCI_VENDOR_ID_IBM, | ||
43 | .subdevice = PCI_ANY_ID, | ||
44 | .driver_data = SDHCI_QUIRK_CLOCK_BEFORE_RESET | | ||
45 | SDHCI_QUIRK_FORCE_DMA, | ||
46 | }, | ||
47 | |||
48 | { | ||
49 | .vendor = PCI_VENDOR_ID_RICOH, | ||
50 | .device = PCI_DEVICE_ID_RICOH_R5C822, | ||
51 | .subvendor = PCI_ANY_ID, | ||
52 | .subdevice = PCI_ANY_ID, | ||
53 | .driver_data = SDHCI_QUIRK_FORCE_DMA, | ||
54 | }, | ||
55 | |||
56 | { | ||
57 | .vendor = PCI_VENDOR_ID_TI, | ||
58 | .device = PCI_DEVICE_ID_TI_XX21_XX11_SD, | ||
59 | .subvendor = PCI_ANY_ID, | ||
60 | .subdevice = PCI_ANY_ID, | ||
61 | .driver_data = SDHCI_QUIRK_FORCE_DMA, | ||
62 | }, | ||
63 | |||
64 | { /* Generic SD host controller */ | ||
65 | PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00) | ||
66 | }, | ||
67 | |||
38 | { /* end: all zeroes */ }, | 68 | { /* end: all zeroes */ }, |
39 | }; | 69 | }; |
40 | 70 | ||
@@ -440,9 +470,7 @@ static void sdhci_finish_data(struct sdhci_host *host) | |||
440 | "though there were blocks left. Please report this " | 470 | "though there were blocks left. Please report this " |
441 | "to " BUGMAIL ".\n", mmc_hostname(host->mmc)); | 471 | "to " BUGMAIL ".\n", mmc_hostname(host->mmc)); |
442 | data->error = MMC_ERR_FAILED; | 472 | data->error = MMC_ERR_FAILED; |
443 | } | 473 | } else if (host->size != 0) { |
444 | |||
445 | if (host->size != 0) { | ||
446 | printk(KERN_ERR "%s: %d bytes were left untransferred. " | 474 | printk(KERN_ERR "%s: %d bytes were left untransferred. " |
447 | "Please report this to " BUGMAIL ".\n", | 475 | "Please report this to " BUGMAIL ".\n", |
448 | mmc_hostname(host->mmc), host->size); | 476 | mmc_hostname(host->mmc), host->size); |
@@ -808,6 +836,19 @@ static void sdhci_tasklet_finish(unsigned long param) | |||
808 | if ((mrq->cmd->error != MMC_ERR_NONE) || | 836 | if ((mrq->cmd->error != MMC_ERR_NONE) || |
809 | (mrq->data && ((mrq->data->error != MMC_ERR_NONE) || | 837 | (mrq->data && ((mrq->data->error != MMC_ERR_NONE) || |
810 | (mrq->data->stop && (mrq->data->stop->error != MMC_ERR_NONE))))) { | 838 | (mrq->data->stop && (mrq->data->stop->error != MMC_ERR_NONE))))) { |
839 | |||
840 | /* Some controllers need this kick or reset won't work here */ | ||
841 | if (host->chip->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) { | ||
842 | unsigned int clock; | ||
843 | |||
844 | /* This is to force an update */ | ||
845 | clock = host->clock; | ||
846 | host->clock = 0; | ||
847 | sdhci_set_clock(host, clock); | ||
848 | } | ||
849 | |||
850 | /* Spec says we should do both at the same time, but Ricoh | ||
851 | controllers do not like that. */ | ||
811 | sdhci_reset(host, SDHCI_RESET_CMD); | 852 | sdhci_reset(host, SDHCI_RESET_CMD); |
812 | sdhci_reset(host, SDHCI_RESET_DATA); | 853 | sdhci_reset(host, SDHCI_RESET_DATA); |
813 | } | 854 | } |
@@ -1165,7 +1206,9 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) | |||
1165 | else if (debug_forcedma) { | 1206 | else if (debug_forcedma) { |
1166 | DBG("DMA forced on\n"); | 1207 | DBG("DMA forced on\n"); |
1167 | host->flags |= SDHCI_USE_DMA; | 1208 | host->flags |= SDHCI_USE_DMA; |
1168 | } else if ((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA) | 1209 | } else if (chip->quirks & SDHCI_QUIRK_FORCE_DMA) |
1210 | host->flags |= SDHCI_USE_DMA; | ||
1211 | else if ((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA) | ||
1169 | DBG("Controller doesn't have DMA interface\n"); | 1212 | DBG("Controller doesn't have DMA interface\n"); |
1170 | else if (!(caps & SDHCI_CAN_DO_DMA)) | 1213 | else if (!(caps & SDHCI_CAN_DO_DMA)) |
1171 | DBG("Controller doesn't have DMA capability\n"); | 1214 | DBG("Controller doesn't have DMA capability\n"); |