aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/omap_hsmmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/omap_hsmmc.c')
-rw-r--r--drivers/mmc/host/omap_hsmmc.c125
1 files changed, 34 insertions, 91 deletions
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 38adc330c007..54bfd0cc106b 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -35,7 +35,6 @@
35#include <linux/mmc/core.h> 35#include <linux/mmc/core.h>
36#include <linux/mmc/mmc.h> 36#include <linux/mmc/mmc.h>
37#include <linux/io.h> 37#include <linux/io.h>
38#include <linux/semaphore.h>
39#include <linux/gpio.h> 38#include <linux/gpio.h>
40#include <linux/regulator/consumer.h> 39#include <linux/regulator/consumer.h>
41#include <linux/pm_runtime.h> 40#include <linux/pm_runtime.h>
@@ -44,7 +43,6 @@
44#include <plat/cpu.h> 43#include <plat/cpu.h>
45 44
46/* OMAP HSMMC Host Controller Registers */ 45/* OMAP HSMMC Host Controller Registers */
47#define OMAP_HSMMC_SYSCONFIG 0x0010
48#define OMAP_HSMMC_SYSSTATUS 0x0014 46#define OMAP_HSMMC_SYSSTATUS 0x0014
49#define OMAP_HSMMC_CON 0x002C 47#define OMAP_HSMMC_CON 0x002C
50#define OMAP_HSMMC_BLK 0x0104 48#define OMAP_HSMMC_BLK 0x0104
@@ -161,8 +159,6 @@ struct omap_hsmmc_host {
161 unsigned int dma_sg_idx; 159 unsigned int dma_sg_idx;
162 unsigned char bus_mode; 160 unsigned char bus_mode;
163 unsigned char power_mode; 161 unsigned char power_mode;
164 u32 *buffer;
165 u32 bytesleft;
166 int suspended; 162 int suspended;
167 int irq; 163 int irq;
168 int use_dma, dma_ch; 164 int use_dma, dma_ch;
@@ -171,7 +167,6 @@ struct omap_hsmmc_host {
171 int slot_id; 167 int slot_id;
172 int response_busy; 168 int response_busy;
173 int context_loss; 169 int context_loss;
174 int vdd;
175 int protect_card; 170 int protect_card;
176 int reqs_blocked; 171 int reqs_blocked;
177 int use_reg; 172 int use_reg;
@@ -300,12 +295,12 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
300 struct regulator *reg; 295 struct regulator *reg;
301 int ocr_value = 0; 296 int ocr_value = 0;
302 297
303 mmc_slot(host).set_power = omap_hsmmc_set_power;
304
305 reg = regulator_get(host->dev, "vmmc"); 298 reg = regulator_get(host->dev, "vmmc");
306 if (IS_ERR(reg)) { 299 if (IS_ERR(reg)) {
307 dev_dbg(host->dev, "vmmc regulator missing\n"); 300 dev_dbg(host->dev, "vmmc regulator missing\n");
301 return PTR_ERR(reg);
308 } else { 302 } else {
303 mmc_slot(host).set_power = omap_hsmmc_set_power;
309 host->vcc = reg; 304 host->vcc = reg;
310 ocr_value = mmc_regulator_get_ocrmask(reg); 305 ocr_value = mmc_regulator_get_ocrmask(reg);
311 if (!mmc_slot(host).ocr_mask) { 306 if (!mmc_slot(host).ocr_mask) {
@@ -495,7 +490,7 @@ static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host)
495 unsigned long regval; 490 unsigned long regval;
496 unsigned long timeout; 491 unsigned long timeout;
497 492
498 dev_dbg(mmc_dev(host->mmc), "Set clock to %uHz\n", ios->clock); 493 dev_vdbg(mmc_dev(host->mmc), "Set clock to %uHz\n", ios->clock);
499 494
500 omap_hsmmc_stop_clock(host); 495 omap_hsmmc_stop_clock(host);
501 496
@@ -579,21 +574,8 @@ static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host)
579 if (host->context_loss == context_loss) 574 if (host->context_loss == context_loss)
580 return 1; 575 return 1;
581 576
582 /* Wait for hardware reset */ 577 if (!OMAP_HSMMC_READ(host->base, SYSSTATUS) & RESETDONE)
583 timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS); 578 return 1;
584 while ((OMAP_HSMMC_READ(host->base, SYSSTATUS) & RESETDONE) != RESETDONE
585 && time_before(jiffies, timeout))
586 ;
587
588 /* Do software reset */
589 OMAP_HSMMC_WRITE(host->base, SYSCONFIG, SOFTRESET);
590 timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
591 while ((OMAP_HSMMC_READ(host->base, SYSSTATUS) & RESETDONE) != RESETDONE
592 && time_before(jiffies, timeout))
593 ;
594
595 OMAP_HSMMC_WRITE(host->base, SYSCONFIG,
596 OMAP_HSMMC_READ(host->base, SYSCONFIG) | AUTOIDLE);
597 579
598 if (host->pdata->controller_flags & OMAP_HSMMC_SUPPORTS_DUAL_VOLT) { 580 if (host->pdata->controller_flags & OMAP_HSMMC_SUPPORTS_DUAL_VOLT) {
599 if (host->power_mode != MMC_POWER_OFF && 581 if (host->power_mode != MMC_POWER_OFF &&
@@ -745,7 +727,7 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd,
745{ 727{
746 int cmdreg = 0, resptype = 0, cmdtype = 0; 728 int cmdreg = 0, resptype = 0, cmdtype = 0;
747 729
748 dev_dbg(mmc_dev(host->mmc), "%s: CMD%d, argument 0x%08x\n", 730 dev_vdbg(mmc_dev(host->mmc), "%s: CMD%d, argument 0x%08x\n",
749 mmc_hostname(host->mmc), cmd->opcode, cmd->arg); 731 mmc_hostname(host->mmc), cmd->opcode, cmd->arg);
750 host->cmd = cmd; 732 host->cmd = cmd;
751 733
@@ -934,7 +916,7 @@ static void omap_hsmmc_dbg_report_irq(struct omap_hsmmc_host *host, u32 status)
934 buf += len; 916 buf += len;
935 } 917 }
936 918
937 dev_dbg(mmc_dev(host->mmc), "%s\n", res); 919 dev_vdbg(mmc_dev(host->mmc), "%s\n", res);
938} 920}
939#else 921#else
940static inline void omap_hsmmc_dbg_report_irq(struct omap_hsmmc_host *host, 922static inline void omap_hsmmc_dbg_report_irq(struct omap_hsmmc_host *host,
@@ -981,72 +963,40 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host,
981 __func__); 963 __func__);
982} 964}
983 965
966static void hsmmc_command_incomplete(struct omap_hsmmc_host *host, int err)
967{
968 omap_hsmmc_reset_controller_fsm(host, SRC);
969 host->cmd->error = err;
970
971 if (host->data) {
972 omap_hsmmc_reset_controller_fsm(host, SRD);
973 omap_hsmmc_dma_cleanup(host, err);
974 }
975
976}
977
984static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status) 978static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status)
985{ 979{
986 struct mmc_data *data; 980 struct mmc_data *data;
987 int end_cmd = 0, end_trans = 0; 981 int end_cmd = 0, end_trans = 0;
988 982
989 if (!host->req_in_progress) {
990 do {
991 OMAP_HSMMC_WRITE(host->base, STAT, status);
992 /* Flush posted write */
993 status = OMAP_HSMMC_READ(host->base, STAT);
994 } while (status & INT_EN_MASK);
995 return;
996 }
997
998 data = host->data; 983 data = host->data;
999 dev_dbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status); 984 dev_vdbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status);
1000 985
1001 if (status & ERR) { 986 if (status & ERR) {
1002 omap_hsmmc_dbg_report_irq(host, status); 987 omap_hsmmc_dbg_report_irq(host, status);
1003 if ((status & CMD_TIMEOUT) || 988 if (status & (CMD_TIMEOUT | DATA_TIMEOUT))
1004 (status & CMD_CRC)) { 989 hsmmc_command_incomplete(host, -ETIMEDOUT);
1005 if (host->cmd) { 990 else if (status & (CMD_CRC | DATA_CRC))
1006 if (status & CMD_TIMEOUT) { 991 hsmmc_command_incomplete(host, -EILSEQ);
1007 omap_hsmmc_reset_controller_fsm(host, 992
1008 SRC); 993 end_cmd = 1;
1009 host->cmd->error = -ETIMEDOUT; 994 if (host->data || host->response_busy) {
1010 } else { 995 end_trans = 1;
1011 host->cmd->error = -EILSEQ; 996 host->response_busy = 0;
1012 }
1013 end_cmd = 1;
1014 }
1015 if (host->data || host->response_busy) {
1016 if (host->data)
1017 omap_hsmmc_dma_cleanup(host,
1018 -ETIMEDOUT);
1019 host->response_busy = 0;
1020 omap_hsmmc_reset_controller_fsm(host, SRD);
1021 }
1022 }
1023 if ((status & DATA_TIMEOUT) ||
1024 (status & DATA_CRC)) {
1025 if (host->data || host->response_busy) {
1026 int err = (status & DATA_TIMEOUT) ?
1027 -ETIMEDOUT : -EILSEQ;
1028
1029 if (host->data)
1030 omap_hsmmc_dma_cleanup(host, err);
1031 else
1032 host->mrq->cmd->error = err;
1033 host->response_busy = 0;
1034 omap_hsmmc_reset_controller_fsm(host, SRD);
1035 end_trans = 1;
1036 }
1037 }
1038 if (status & CARD_ERR) {
1039 dev_dbg(mmc_dev(host->mmc),
1040 "Ignoring card err CMD%d\n", host->cmd->opcode);
1041 if (host->cmd)
1042 end_cmd = 1;
1043 if (host->data)
1044 end_trans = 1;
1045 } 997 }
1046 } 998 }
1047 999
1048 OMAP_HSMMC_WRITE(host->base, STAT, status);
1049
1050 if (end_cmd || ((status & CC) && host->cmd)) 1000 if (end_cmd || ((status & CC) && host->cmd))
1051 omap_hsmmc_cmd_done(host, host->cmd); 1001 omap_hsmmc_cmd_done(host, host->cmd);
1052 if ((end_trans || (status & TC)) && host->mrq) 1002 if ((end_trans || (status & TC)) && host->mrq)
@@ -1062,11 +1012,13 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id)
1062 int status; 1012 int status;
1063 1013
1064 status = OMAP_HSMMC_READ(host->base, STAT); 1014 status = OMAP_HSMMC_READ(host->base, STAT);
1065 do { 1015 while (status & INT_EN_MASK && host->req_in_progress) {
1066 omap_hsmmc_do_irq(host, status); 1016 omap_hsmmc_do_irq(host, status);
1017
1067 /* Flush posted write */ 1018 /* Flush posted write */
1019 OMAP_HSMMC_WRITE(host->base, STAT, status);
1068 status = OMAP_HSMMC_READ(host->base, STAT); 1020 status = OMAP_HSMMC_READ(host->base, STAT);
1069 } while (status & INT_EN_MASK); 1021 }
1070 1022
1071 return IRQ_HANDLED; 1023 return IRQ_HANDLED;
1072} 1024}
@@ -1501,12 +1453,10 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1501 case MMC_POWER_OFF: 1453 case MMC_POWER_OFF:
1502 mmc_slot(host).set_power(host->dev, host->slot_id, 1454 mmc_slot(host).set_power(host->dev, host->slot_id,
1503 0, 0); 1455 0, 0);
1504 host->vdd = 0;
1505 break; 1456 break;
1506 case MMC_POWER_UP: 1457 case MMC_POWER_UP:
1507 mmc_slot(host).set_power(host->dev, host->slot_id, 1458 mmc_slot(host).set_power(host->dev, host->slot_id,
1508 1, ios->vdd); 1459 1, ios->vdd);
1509 host->vdd = ios->vdd;
1510 break; 1460 break;
1511 case MMC_POWER_ON: 1461 case MMC_POWER_ON:
1512 do_send_init_stream = 1; 1462 do_send_init_stream = 1;
@@ -1598,10 +1548,6 @@ static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host)
1598 value = OMAP_HSMMC_READ(host->base, CAPA); 1548 value = OMAP_HSMMC_READ(host->base, CAPA);
1599 OMAP_HSMMC_WRITE(host->base, CAPA, value | capa); 1549 OMAP_HSMMC_WRITE(host->base, CAPA, value | capa);
1600 1550
1601 /* Set the controller to AUTO IDLE mode */
1602 value = OMAP_HSMMC_READ(host->base, SYSCONFIG);
1603 OMAP_HSMMC_WRITE(host->base, SYSCONFIG, value | AUTOIDLE);
1604
1605 /* Set SD bus power bit */ 1551 /* Set SD bus power bit */
1606 set_sd_bus_power(host); 1552 set_sd_bus_power(host);
1607} 1553}
@@ -1659,8 +1605,6 @@ static int omap_hsmmc_regs_show(struct seq_file *s, void *data)
1659 1605
1660 pm_runtime_get_sync(host->dev); 1606 pm_runtime_get_sync(host->dev);
1661 1607
1662 seq_printf(s, "SYSCONFIG:\t0x%08x\n",
1663 OMAP_HSMMC_READ(host->base, SYSCONFIG));
1664 seq_printf(s, "CON:\t\t0x%08x\n", 1608 seq_printf(s, "CON:\t\t0x%08x\n",
1665 OMAP_HSMMC_READ(host->base, CON)); 1609 OMAP_HSMMC_READ(host->base, CON));
1666 seq_printf(s, "HCTL:\t\t0x%08x\n", 1610 seq_printf(s, "HCTL:\t\t0x%08x\n",
@@ -2105,8 +2049,7 @@ static int omap_hsmmc_suspend(struct device *dev)
2105 if (ret) { 2049 if (ret) {
2106 host->suspended = 0; 2050 host->suspended = 0;
2107 if (host->pdata->resume) { 2051 if (host->pdata->resume) {
2108 ret = host->pdata->resume(dev, host->slot_id); 2052 if (host->pdata->resume(dev, host->slot_id))
2109 if (ret)
2110 dev_dbg(dev, "Unmask interrupt failed\n"); 2053 dev_dbg(dev, "Unmask interrupt failed\n");
2111 } 2054 }
2112 goto err; 2055 goto err;