aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/sdhci.c30
-rw-r--r--drivers/mmc/sdhci.h4
2 files changed, 33 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)");
diff --git a/drivers/mmc/sdhci.h b/drivers/mmc/sdhci.h
index 758cf1c24364..8111fa38c05b 100644
--- a/drivers/mmc/sdhci.h
+++ b/drivers/mmc/sdhci.h
@@ -12,6 +12,10 @@
12 * PCI registers 12 * PCI registers
13 */ 13 */
14 14
15#define PCI_SDHCI_IFPIO 0x00
16#define PCI_SDHCI_IFDMA 0x01
17#define PCI_SDHCI_IFVENDOR 0x02
18
15#define PCI_SLOT_INFO 0x40 /* 8 bits */ 19#define PCI_SLOT_INFO 0x40 /* 8 bits */
16#define PCI_SLOT_INFO_SLOTS(x) ((x >> 4) & 7) 20#define PCI_SLOT_INFO_SLOTS(x) ((x >> 4) & 7)
17#define PCI_SLOT_INFO_FIRST_BAR_MASK 0x07 21#define PCI_SLOT_INFO_FIRST_BAR_MASK 0x07