aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/sdhci.c
diff options
context:
space:
mode:
authorPierre Ossman <drzeus@drzeus.cx>2006-06-30 05:22:31 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-07-02 11:54:56 -0400
commit6743527441430586aa82a0dee1b2700a2a974ebc (patch)
tree6977160737a9d300c236bde53fb8ca5535e8bafb /drivers/mmc/sdhci.c
parentd96649ed5ace812ffc8d86252d7c663326ca47f8 (diff)
[MMC] sdhci: more DMA capabilities tests
Properly test for controller interface to see if it's DMA capable. As many controllers are misconfigured in this regard, also add debug parameters to force DMA support either way. Signed-off-by: Pierre Ossman <drzeus@drzeus.cx> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/mmc/sdhci.c')
-rw-r--r--drivers/mmc/sdhci.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 06dec744d53e..315ab49e4b2c 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -28,6 +28,9 @@
28#define DBG(f, x...) \ 28#define DBG(f, x...) \
29 pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x) 29 pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x)
30 30
31static unsigned int debug_nodma = 0;
32static unsigned int debug_forcedma = 0;
33
31static const struct pci_device_id pci_ids[] __devinitdata = { 34static const struct pci_device_id pci_ids[] __devinitdata = {
32 /* handle any SD host controller */ 35 /* handle any SD host controller */
33 {PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00)}, 36 {PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00)},
@@ -1105,6 +1108,16 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
1105 return -ENODEV; 1108 return -ENODEV;
1106 } 1109 }
1107 1110
1111 if ((pdev->class & 0x0000FF) == PCI_SDHCI_IFVENDOR) {
1112 printk(KERN_ERR DRIVER_NAME ": Vendor specific interface. Aborting.\n");
1113 return -ENODEV;
1114 }
1115
1116 if ((pdev->class & 0x0000FF) > PCI_SDHCI_IFVENDOR) {
1117 printk(KERN_ERR DRIVER_NAME ": Unknown interface. Aborting.\n");
1118 return -ENODEV;
1119 }
1120
1108 mmc = mmc_alloc_host(sizeof(struct sdhci_host), &pdev->dev); 1121 mmc = mmc_alloc_host(sizeof(struct sdhci_host), &pdev->dev);
1109 if (!mmc) 1122 if (!mmc)
1110 return -ENOMEM; 1123 return -ENOMEM;
@@ -1146,7 +1159,16 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
1146 1159
1147 caps = readl(host->ioaddr + SDHCI_CAPABILITIES); 1160 caps = readl(host->ioaddr + SDHCI_CAPABILITIES);
1148 1161
1149 if ((caps & SDHCI_CAN_DO_DMA) && ((pdev->class & 0x0000FF) == 0x01)) 1162 if (debug_nodma)
1163 DBG("DMA forced off\n");
1164 else if (debug_forcedma) {
1165 DBG("DMA forced on\n");
1166 host->flags |= SDHCI_USE_DMA;
1167 } else if ((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA)
1168 DBG("Controller doesn't have DMA interface\n");
1169 else if (!(caps & SDHCI_CAN_DO_DMA))
1170 DBG("Controller doesn't have DMA capability\n");
1171 else
1150 host->flags |= SDHCI_USE_DMA; 1172 host->flags |= SDHCI_USE_DMA;
1151 1173
1152 if (host->flags & SDHCI_USE_DMA) { 1174 if (host->flags & SDHCI_USE_DMA) {
@@ -1429,7 +1451,13 @@ static void __exit sdhci_drv_exit(void)
1429module_init(sdhci_drv_init); 1451module_init(sdhci_drv_init);
1430module_exit(sdhci_drv_exit); 1452module_exit(sdhci_drv_exit);
1431 1453
1454module_param(debug_nodma, uint, 0444);
1455module_param(debug_forcedma, uint, 0444);
1456
1432MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>"); 1457MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>");
1433MODULE_DESCRIPTION("Secure Digital Host Controller Interface driver"); 1458MODULE_DESCRIPTION("Secure Digital Host Controller Interface driver");
1434MODULE_VERSION(DRIVER_VERSION); 1459MODULE_VERSION(DRIVER_VERSION);
1435MODULE_LICENSE("GPL"); 1460MODULE_LICENSE("GPL");
1461
1462MODULE_PARM_DESC(debug_nodma, "Forcefully disable DMA transfers. (default 0)");
1463MODULE_PARM_DESC(debug_forcedma, "Forcefully enable DMA transfers. (default 0)");