aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/sdhci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/sdhci.c')
-rw-r--r--drivers/mmc/host/sdhci.c127
1 files changed, 82 insertions, 45 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 20a7d89e01ba..b397121b947d 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -25,8 +25,6 @@
25#define DBG(f, x...) \ 25#define DBG(f, x...) \
26 pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x) 26 pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x)
27 27
28static unsigned int debug_nodma = 0;
29static unsigned int debug_forcedma = 0;
30static unsigned int debug_quirks = 0; 28static unsigned int debug_quirks = 0;
31 29
32#define SDHCI_QUIRK_CLOCK_BEFORE_RESET (1<<0) 30#define SDHCI_QUIRK_CLOCK_BEFORE_RESET (1<<0)
@@ -35,6 +33,7 @@ static unsigned int debug_quirks = 0;
35#define SDHCI_QUIRK_NO_CARD_NO_RESET (1<<2) 33#define SDHCI_QUIRK_NO_CARD_NO_RESET (1<<2)
36#define SDHCI_QUIRK_SINGLE_POWER_WRITE (1<<3) 34#define SDHCI_QUIRK_SINGLE_POWER_WRITE (1<<3)
37#define SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS (1<<4) 35#define SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS (1<<4)
36#define SDHCI_QUIRK_BROKEN_DMA (1<<5)
38 37
39static const struct pci_device_id pci_ids[] __devinitdata = { 38static const struct pci_device_id pci_ids[] __devinitdata = {
40 { 39 {
@@ -68,7 +67,8 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
68 .device = PCI_DEVICE_ID_ENE_CB712_SD, 67 .device = PCI_DEVICE_ID_ENE_CB712_SD,
69 .subvendor = PCI_ANY_ID, 68 .subvendor = PCI_ANY_ID,
70 .subdevice = PCI_ANY_ID, 69 .subdevice = PCI_ANY_ID,
71 .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE, 70 .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE |
71 SDHCI_QUIRK_BROKEN_DMA,
72 }, 72 },
73 73
74 { 74 {
@@ -76,7 +76,8 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
76 .device = PCI_DEVICE_ID_ENE_CB712_SD_2, 76 .device = PCI_DEVICE_ID_ENE_CB712_SD_2,
77 .subvendor = PCI_ANY_ID, 77 .subvendor = PCI_ANY_ID,
78 .subdevice = PCI_ANY_ID, 78 .subdevice = PCI_ANY_ID,
79 .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE, 79 .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE |
80 SDHCI_QUIRK_BROKEN_DMA,
80 }, 81 },
81 82
82 { 83 {
@@ -132,7 +133,7 @@ static void sdhci_dumpregs(struct sdhci_host *host)
132 readb(host->ioaddr + SDHCI_POWER_CONTROL), 133 readb(host->ioaddr + SDHCI_POWER_CONTROL),
133 readb(host->ioaddr + SDHCI_BLOCK_GAP_CONTROL)); 134 readb(host->ioaddr + SDHCI_BLOCK_GAP_CONTROL));
134 printk(KERN_DEBUG DRIVER_NAME ": Wake-up: 0x%08x | Clock: 0x%08x\n", 135 printk(KERN_DEBUG DRIVER_NAME ": Wake-up: 0x%08x | Clock: 0x%08x\n",
135 readb(host->ioaddr + SDHCI_WALK_UP_CONTROL), 136 readb(host->ioaddr + SDHCI_WAKE_UP_CONTROL),
136 readw(host->ioaddr + SDHCI_CLOCK_CONTROL)); 137 readw(host->ioaddr + SDHCI_CLOCK_CONTROL));
137 printk(KERN_DEBUG DRIVER_NAME ": Timeout: 0x%08x | Int stat: 0x%08x\n", 138 printk(KERN_DEBUG DRIVER_NAME ": Timeout: 0x%08x | Int stat: 0x%08x\n",
138 readb(host->ioaddr + SDHCI_TIMEOUT_CONTROL), 139 readb(host->ioaddr + SDHCI_TIMEOUT_CONTROL),
@@ -481,16 +482,16 @@ static void sdhci_finish_data(struct sdhci_host *host)
481 * Controller doesn't count down when in single block mode. 482 * Controller doesn't count down when in single block mode.
482 */ 483 */
483 if (data->blocks == 1) 484 if (data->blocks == 1)
484 blocks = (data->error == MMC_ERR_NONE) ? 0 : 1; 485 blocks = (data->error == 0) ? 0 : 1;
485 else 486 else
486 blocks = readw(host->ioaddr + SDHCI_BLOCK_COUNT); 487 blocks = readw(host->ioaddr + SDHCI_BLOCK_COUNT);
487 data->bytes_xfered = data->blksz * (data->blocks - blocks); 488 data->bytes_xfered = data->blksz * (data->blocks - blocks);
488 489
489 if ((data->error == MMC_ERR_NONE) && blocks) { 490 if (!data->error && blocks) {
490 printk(KERN_ERR "%s: Controller signalled completion even " 491 printk(KERN_ERR "%s: Controller signalled completion even "
491 "though there were blocks left.\n", 492 "though there were blocks left.\n",
492 mmc_hostname(host->mmc)); 493 mmc_hostname(host->mmc));
493 data->error = MMC_ERR_FAILED; 494 data->error = -EIO;
494 } 495 }
495 496
496 if (data->stop) { 497 if (data->stop) {
@@ -498,7 +499,7 @@ static void sdhci_finish_data(struct sdhci_host *host)
498 * The controller needs a reset of internal state machines 499 * The controller needs a reset of internal state machines
499 * upon error conditions. 500 * upon error conditions.
500 */ 501 */
501 if (data->error != MMC_ERR_NONE) { 502 if (data->error) {
502 sdhci_reset(host, SDHCI_RESET_CMD); 503 sdhci_reset(host, SDHCI_RESET_CMD);
503 sdhci_reset(host, SDHCI_RESET_DATA); 504 sdhci_reset(host, SDHCI_RESET_DATA);
504 } 505 }
@@ -533,7 +534,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
533 printk(KERN_ERR "%s: Controller never released " 534 printk(KERN_ERR "%s: Controller never released "
534 "inhibit bit(s).\n", mmc_hostname(host->mmc)); 535 "inhibit bit(s).\n", mmc_hostname(host->mmc));
535 sdhci_dumpregs(host); 536 sdhci_dumpregs(host);
536 cmd->error = MMC_ERR_FAILED; 537 cmd->error = -EIO;
537 tasklet_schedule(&host->finish_tasklet); 538 tasklet_schedule(&host->finish_tasklet);
538 return; 539 return;
539 } 540 }
@@ -554,7 +555,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
554 if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) { 555 if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) {
555 printk(KERN_ERR "%s: Unsupported response type!\n", 556 printk(KERN_ERR "%s: Unsupported response type!\n",
556 mmc_hostname(host->mmc)); 557 mmc_hostname(host->mmc));
557 cmd->error = MMC_ERR_INVALID; 558 cmd->error = -EINVAL;
558 tasklet_schedule(&host->finish_tasklet); 559 tasklet_schedule(&host->finish_tasklet);
559 return; 560 return;
560 } 561 }
@@ -601,7 +602,7 @@ static void sdhci_finish_command(struct sdhci_host *host)
601 } 602 }
602 } 603 }
603 604
604 host->cmd->error = MMC_ERR_NONE; 605 host->cmd->error = 0;
605 606
606 if (host->data && host->data_early) 607 if (host->data && host->data_early)
607 sdhci_finish_data(host); 608 sdhci_finish_data(host);
@@ -722,7 +723,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
722 host->mrq = mrq; 723 host->mrq = mrq;
723 724
724 if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) { 725 if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
725 host->mrq->cmd->error = MMC_ERR_TIMEOUT; 726 host->mrq->cmd->error = -ENOMEDIUM;
726 tasklet_schedule(&host->finish_tasklet); 727 tasklet_schedule(&host->finish_tasklet);
727 } else 728 } else
728 sdhci_send_command(host, mrq->cmd); 729 sdhci_send_command(host, mrq->cmd);
@@ -800,10 +801,35 @@ static int sdhci_get_ro(struct mmc_host *mmc)
800 return !(present & SDHCI_WRITE_PROTECT); 801 return !(present & SDHCI_WRITE_PROTECT);
801} 802}
802 803
804static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
805{
806 struct sdhci_host *host;
807 unsigned long flags;
808 u32 ier;
809
810 host = mmc_priv(mmc);
811
812 spin_lock_irqsave(&host->lock, flags);
813
814 ier = readl(host->ioaddr + SDHCI_INT_ENABLE);
815
816 ier &= ~SDHCI_INT_CARD_INT;
817 if (enable)
818 ier |= SDHCI_INT_CARD_INT;
819
820 writel(ier, host->ioaddr + SDHCI_INT_ENABLE);
821 writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE);
822
823 mmiowb();
824
825 spin_unlock_irqrestore(&host->lock, flags);
826}
827
803static const struct mmc_host_ops sdhci_ops = { 828static const struct mmc_host_ops sdhci_ops = {
804 .request = sdhci_request, 829 .request = sdhci_request,
805 .set_ios = sdhci_set_ios, 830 .set_ios = sdhci_set_ios,
806 .get_ro = sdhci_get_ro, 831 .get_ro = sdhci_get_ro,
832 .enable_sdio_irq = sdhci_enable_sdio_irq,
807}; 833};
808 834
809/*****************************************************************************\ 835/*****************************************************************************\
@@ -831,7 +857,7 @@ static void sdhci_tasklet_card(unsigned long param)
831 sdhci_reset(host, SDHCI_RESET_CMD); 857 sdhci_reset(host, SDHCI_RESET_CMD);
832 sdhci_reset(host, SDHCI_RESET_DATA); 858 sdhci_reset(host, SDHCI_RESET_DATA);
833 859
834 host->mrq->cmd->error = MMC_ERR_FAILED; 860 host->mrq->cmd->error = -ENOMEDIUM;
835 tasklet_schedule(&host->finish_tasklet); 861 tasklet_schedule(&host->finish_tasklet);
836 } 862 }
837 } 863 }
@@ -859,9 +885,9 @@ static void sdhci_tasklet_finish(unsigned long param)
859 * The controller needs a reset of internal state machines 885 * The controller needs a reset of internal state machines
860 * upon error conditions. 886 * upon error conditions.
861 */ 887 */
862 if ((mrq->cmd->error != MMC_ERR_NONE) || 888 if (mrq->cmd->error ||
863 (mrq->data && ((mrq->data->error != MMC_ERR_NONE) || 889 (mrq->data && (mrq->data->error ||
864 (mrq->data->stop && (mrq->data->stop->error != MMC_ERR_NONE))))) { 890 (mrq->data->stop && mrq->data->stop->error)))) {
865 891
866 /* Some controllers need this kick or reset won't work here */ 892 /* Some controllers need this kick or reset won't work here */
867 if (host->chip->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) { 893 if (host->chip->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) {
@@ -906,13 +932,13 @@ static void sdhci_timeout_timer(unsigned long data)
906 sdhci_dumpregs(host); 932 sdhci_dumpregs(host);
907 933
908 if (host->data) { 934 if (host->data) {
909 host->data->error = MMC_ERR_TIMEOUT; 935 host->data->error = -ETIMEDOUT;
910 sdhci_finish_data(host); 936 sdhci_finish_data(host);
911 } else { 937 } else {
912 if (host->cmd) 938 if (host->cmd)
913 host->cmd->error = MMC_ERR_TIMEOUT; 939 host->cmd->error = -ETIMEDOUT;
914 else 940 else
915 host->mrq->cmd->error = MMC_ERR_TIMEOUT; 941 host->mrq->cmd->error = -ETIMEDOUT;
916 942
917 tasklet_schedule(&host->finish_tasklet); 943 tasklet_schedule(&host->finish_tasklet);
918 } 944 }
@@ -941,13 +967,12 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
941 } 967 }
942 968
943 if (intmask & SDHCI_INT_TIMEOUT) 969 if (intmask & SDHCI_INT_TIMEOUT)
944 host->cmd->error = MMC_ERR_TIMEOUT; 970 host->cmd->error = -ETIMEDOUT;
945 else if (intmask & SDHCI_INT_CRC) 971 else if (intmask & (SDHCI_INT_CRC | SDHCI_INT_END_BIT |
946 host->cmd->error = MMC_ERR_BADCRC; 972 SDHCI_INT_INDEX))
947 else if (intmask & (SDHCI_INT_END_BIT | SDHCI_INT_INDEX)) 973 host->cmd->error = -EILSEQ;
948 host->cmd->error = MMC_ERR_FAILED;
949 974
950 if (host->cmd->error != MMC_ERR_NONE) 975 if (host->cmd->error)
951 tasklet_schedule(&host->finish_tasklet); 976 tasklet_schedule(&host->finish_tasklet);
952 else if (intmask & SDHCI_INT_RESPONSE) 977 else if (intmask & SDHCI_INT_RESPONSE)
953 sdhci_finish_command(host); 978 sdhci_finish_command(host);
@@ -974,13 +999,11 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
974 } 999 }
975 1000
976 if (intmask & SDHCI_INT_DATA_TIMEOUT) 1001 if (intmask & SDHCI_INT_DATA_TIMEOUT)
977 host->data->error = MMC_ERR_TIMEOUT; 1002 host->data->error = -ETIMEDOUT;
978 else if (intmask & SDHCI_INT_DATA_CRC) 1003 else if (intmask & (SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_END_BIT))
979 host->data->error = MMC_ERR_BADCRC; 1004 host->data->error = -EILSEQ;
980 else if (intmask & SDHCI_INT_DATA_END_BIT)
981 host->data->error = MMC_ERR_FAILED;
982 1005
983 if (host->data->error != MMC_ERR_NONE) 1006 if (host->data->error)
984 sdhci_finish_data(host); 1007 sdhci_finish_data(host);
985 else { 1008 else {
986 if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL)) 1009 if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL))
@@ -1015,6 +1038,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
1015 irqreturn_t result; 1038 irqreturn_t result;
1016 struct sdhci_host* host = dev_id; 1039 struct sdhci_host* host = dev_id;
1017 u32 intmask; 1040 u32 intmask;
1041 int cardint = 0;
1018 1042
1019 spin_lock(&host->lock); 1043 spin_lock(&host->lock);
1020 1044
@@ -1059,6 +1083,11 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
1059 1083
1060 intmask &= ~SDHCI_INT_BUS_POWER; 1084 intmask &= ~SDHCI_INT_BUS_POWER;
1061 1085
1086 if (intmask & SDHCI_INT_CARD_INT)
1087 cardint = 1;
1088
1089 intmask &= ~SDHCI_INT_CARD_INT;
1090
1062 if (intmask) { 1091 if (intmask) {
1063 printk(KERN_ERR "%s: Unexpected interrupt 0x%08x.\n", 1092 printk(KERN_ERR "%s: Unexpected interrupt 0x%08x.\n",
1064 mmc_hostname(host->mmc), intmask); 1093 mmc_hostname(host->mmc), intmask);
@@ -1073,6 +1102,12 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
1073out: 1102out:
1074 spin_unlock(&host->lock); 1103 spin_unlock(&host->lock);
1075 1104
1105 /*
1106 * We have to delay this as it calls back into the driver.
1107 */
1108 if (cardint)
1109 mmc_signal_sdio_irq(host->mmc);
1110
1076 return result; 1111 return result;
1077} 1112}
1078 1113
@@ -1258,20 +1293,26 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
1258 1293
1259 caps = readl(host->ioaddr + SDHCI_CAPABILITIES); 1294 caps = readl(host->ioaddr + SDHCI_CAPABILITIES);
1260 1295
1261 if (debug_nodma) 1296 if (chip->quirks & SDHCI_QUIRK_FORCE_DMA)
1262 DBG("DMA forced off\n");
1263 else if (debug_forcedma) {
1264 DBG("DMA forced on\n");
1265 host->flags |= SDHCI_USE_DMA;
1266 } else if (chip->quirks & SDHCI_QUIRK_FORCE_DMA)
1267 host->flags |= SDHCI_USE_DMA; 1297 host->flags |= SDHCI_USE_DMA;
1268 else if ((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA)
1269 DBG("Controller doesn't have DMA interface\n");
1270 else if (!(caps & SDHCI_CAN_DO_DMA)) 1298 else if (!(caps & SDHCI_CAN_DO_DMA))
1271 DBG("Controller doesn't have DMA capability\n"); 1299 DBG("Controller doesn't have DMA capability\n");
1272 else 1300 else
1273 host->flags |= SDHCI_USE_DMA; 1301 host->flags |= SDHCI_USE_DMA;
1274 1302
1303 if ((chip->quirks & SDHCI_QUIRK_BROKEN_DMA) &&
1304 (host->flags & SDHCI_USE_DMA)) {
1305 DBG("Disabling DMA as it is marked broken");
1306 host->flags &= ~SDHCI_USE_DMA;
1307 }
1308
1309 if (((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA) &&
1310 (host->flags & SDHCI_USE_DMA)) {
1311 printk(KERN_WARNING "%s: Will use DMA "
1312 "mode even though HW doesn't fully "
1313 "claim to support it.\n", host->slot_descr);
1314 }
1315
1275 if (host->flags & SDHCI_USE_DMA) { 1316 if (host->flags & SDHCI_USE_DMA) {
1276 if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { 1317 if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1277 printk(KERN_WARNING "%s: No suitable DMA available. " 1318 printk(KERN_WARNING "%s: No suitable DMA available. "
@@ -1312,7 +1353,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
1312 mmc->ops = &sdhci_ops; 1353 mmc->ops = &sdhci_ops;
1313 mmc->f_min = host->max_clk / 256; 1354 mmc->f_min = host->max_clk / 256;
1314 mmc->f_max = host->max_clk; 1355 mmc->f_max = host->max_clk;
1315 mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_BYTEBLOCK; 1356 mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_SDIO_IRQ;
1316 1357
1317 if (caps & SDHCI_CAN_DO_HISPD) 1358 if (caps & SDHCI_CAN_DO_HISPD)
1318 mmc->caps |= MMC_CAP_SD_HIGHSPEED; 1359 mmc->caps |= MMC_CAP_SD_HIGHSPEED;
@@ -1565,14 +1606,10 @@ static void __exit sdhci_drv_exit(void)
1565module_init(sdhci_drv_init); 1606module_init(sdhci_drv_init);
1566module_exit(sdhci_drv_exit); 1607module_exit(sdhci_drv_exit);
1567 1608
1568module_param(debug_nodma, uint, 0444);
1569module_param(debug_forcedma, uint, 0444);
1570module_param(debug_quirks, uint, 0444); 1609module_param(debug_quirks, uint, 0444);
1571 1610
1572MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>"); 1611MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>");
1573MODULE_DESCRIPTION("Secure Digital Host Controller Interface driver"); 1612MODULE_DESCRIPTION("Secure Digital Host Controller Interface driver");
1574MODULE_LICENSE("GPL"); 1613MODULE_LICENSE("GPL");
1575 1614
1576MODULE_PARM_DESC(debug_nodma, "Forcefully disable DMA transfers. (default 0)");
1577MODULE_PARM_DESC(debug_forcedma, "Forcefully enable DMA transfers. (default 0)");
1578MODULE_PARM_DESC(debug_quirks, "Force certain quirks."); 1615MODULE_PARM_DESC(debug_quirks, "Force certain quirks.");