aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/host/sh_mmcif.c79
1 files changed, 34 insertions, 45 deletions
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index 0cba85a7f561..8aee127e60b8 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -124,6 +124,11 @@
124#define MASK_MRBSYTO (1 << 1) 124#define MASK_MRBSYTO (1 << 1)
125#define MASK_MRSPTO (1 << 0) 125#define MASK_MRSPTO (1 << 0)
126 126
127#define MASK_START_CMD (MASK_MCMDVIO | MASK_MBUFVIO | MASK_MWDATERR | \
128 MASK_MRDATERR | MASK_MRIDXERR | MASK_MRSPERR | \
129 MASK_MCCSTO | MASK_MCRCSTO | MASK_MWDATTO | \
130 MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO)
131
127/* CE_HOST_STS1 */ 132/* CE_HOST_STS1 */
128#define STS1_CMDSEQ (1 << 31) 133#define STS1_CMDSEQ (1 << 31)
129 134
@@ -176,8 +181,8 @@ struct sh_mmcif_host {
176 long timeout; 181 long timeout;
177 void __iomem *addr; 182 void __iomem *addr;
178 struct completion intr_wait; 183 struct completion intr_wait;
184 spinlock_t lock; /* protect sh_mmcif_host::state */
179 enum mmcif_state state; 185 enum mmcif_state state;
180 spinlock_t lock;
181 bool power; 186 bool power;
182 bool card_present; 187 bool card_present;
183 188
@@ -422,7 +427,7 @@ static void sh_mmcif_sync_reset(struct sh_mmcif_host *host)
422static int sh_mmcif_error_manage(struct sh_mmcif_host *host) 427static int sh_mmcif_error_manage(struct sh_mmcif_host *host)
423{ 428{
424 u32 state1, state2; 429 u32 state1, state2;
425 int ret, timeout = 10000000; 430 int ret, timeout;
426 431
427 host->sd_error = false; 432 host->sd_error = false;
428 433
@@ -434,31 +439,30 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host)
434 if (state1 & STS1_CMDSEQ) { 439 if (state1 & STS1_CMDSEQ) {
435 sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, CMD_CTRL_BREAK); 440 sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, CMD_CTRL_BREAK);
436 sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, ~CMD_CTRL_BREAK); 441 sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, ~CMD_CTRL_BREAK);
437 while (1) { 442 for (timeout = 10000000; timeout; timeout--) {
438 timeout--;
439 if (timeout < 0) {
440 dev_err(&host->pd->dev,
441 "Forceed end of command sequence timeout err\n");
442 return -EIO;
443 }
444 if (!(sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS1) 443 if (!(sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS1)
445 & STS1_CMDSEQ)) 444 & STS1_CMDSEQ))
446 break; 445 break;
447 mdelay(1); 446 mdelay(1);
448 } 447 }
448 if (!timeout) {
449 dev_err(&host->pd->dev,
450 "Forced end of command sequence timeout err\n");
451 return -EIO;
452 }
449 sh_mmcif_sync_reset(host); 453 sh_mmcif_sync_reset(host);
450 dev_dbg(&host->pd->dev, "Forced end of command sequence\n"); 454 dev_dbg(&host->pd->dev, "Forced end of command sequence\n");
451 return -EIO; 455 return -EIO;
452 } 456 }
453 457
454 if (state2 & STS2_CRC_ERR) { 458 if (state2 & STS2_CRC_ERR) {
455 dev_dbg(&host->pd->dev, ": Happened CRC error\n"); 459 dev_dbg(&host->pd->dev, ": CRC error\n");
456 ret = -EIO; 460 ret = -EIO;
457 } else if (state2 & STS2_TIMEOUT_ERR) { 461 } else if (state2 & STS2_TIMEOUT_ERR) {
458 dev_dbg(&host->pd->dev, ": Happened Timeout error\n"); 462 dev_dbg(&host->pd->dev, ": Timeout\n");
459 ret = -ETIMEDOUT; 463 ret = -ETIMEDOUT;
460 } else { 464 } else {
461 dev_dbg(&host->pd->dev, ": Happened End/Index error\n"); 465 dev_dbg(&host->pd->dev, ": End/Index error\n");
462 ret = -EIO; 466 ret = -EIO;
463 } 467 }
464 return ret; 468 return ret;
@@ -681,55 +685,44 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
681static int sh_mmcif_data_trans(struct sh_mmcif_host *host, 685static int sh_mmcif_data_trans(struct sh_mmcif_host *host,
682 struct mmc_request *mrq, u32 opc) 686 struct mmc_request *mrq, u32 opc)
683{ 687{
684 int ret;
685
686 switch (opc) { 688 switch (opc) {
687 case MMC_READ_MULTIPLE_BLOCK: 689 case MMC_READ_MULTIPLE_BLOCK:
688 ret = sh_mmcif_multi_read(host, mrq); 690 return sh_mmcif_multi_read(host, mrq);
689 break;
690 case MMC_WRITE_MULTIPLE_BLOCK: 691 case MMC_WRITE_MULTIPLE_BLOCK:
691 ret = sh_mmcif_multi_write(host, mrq); 692 return sh_mmcif_multi_write(host, mrq);
692 break;
693 case MMC_WRITE_BLOCK: 693 case MMC_WRITE_BLOCK:
694 ret = sh_mmcif_single_write(host, mrq); 694 return sh_mmcif_single_write(host, mrq);
695 break;
696 case MMC_READ_SINGLE_BLOCK: 695 case MMC_READ_SINGLE_BLOCK:
697 case MMC_SEND_EXT_CSD: 696 case MMC_SEND_EXT_CSD:
698 ret = sh_mmcif_single_read(host, mrq); 697 return sh_mmcif_single_read(host, mrq);
699 break;
700 default: 698 default:
701 dev_err(&host->pd->dev, "UNSUPPORTED CMD = d'%08d\n", opc); 699 dev_err(&host->pd->dev, "UNSUPPORTED CMD = d'%08d\n", opc);
702 ret = -EINVAL; 700 return -EINVAL;
703 break;
704 } 701 }
705 return ret;
706} 702}
707 703
708static void sh_mmcif_start_cmd(struct sh_mmcif_host *host, 704static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
709 struct mmc_request *mrq, struct mmc_command *cmd) 705 struct mmc_request *mrq)
710{ 706{
707 struct mmc_command *cmd = mrq->cmd;
711 long time; 708 long time;
712 int ret = 0, mask = 0; 709 int ret = 0;
713 u32 opc = cmd->opcode; 710 u32 mask, opc = cmd->opcode;
714 711
715 switch (opc) { 712 switch (opc) {
716 /* respons busy check */ 713 /* response busy check */
717 case MMC_SWITCH: 714 case MMC_SWITCH:
718 case MMC_STOP_TRANSMISSION: 715 case MMC_STOP_TRANSMISSION:
719 case MMC_SET_WRITE_PROT: 716 case MMC_SET_WRITE_PROT:
720 case MMC_CLR_WRITE_PROT: 717 case MMC_CLR_WRITE_PROT:
721 case MMC_ERASE: 718 case MMC_ERASE:
722 case MMC_GEN_CMD: 719 case MMC_GEN_CMD:
723 mask = MASK_MRBSYE; 720 mask = MASK_START_CMD | MASK_MRBSYE;
724 break; 721 break;
725 default: 722 default:
726 mask = MASK_MCRSPE; 723 mask = MASK_START_CMD | MASK_MCRSPE;
727 break; 724 break;
728 } 725 }
729 mask |= MASK_MCMDVIO | MASK_MBUFVIO | MASK_MWDATERR |
730 MASK_MRDATERR | MASK_MRIDXERR | MASK_MRSPERR |
731 MASK_MCCSTO | MASK_MCRCSTO | MASK_MWDATTO |
732 MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO;
733 726
734 if (host->data) { 727 if (host->data) {
735 sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET, 0); 728 sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET, 0);
@@ -797,8 +790,9 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
797} 790}
798 791
799static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host, 792static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host,
800 struct mmc_request *mrq, struct mmc_command *cmd) 793 struct mmc_request *mrq)
801{ 794{
795 struct mmc_command *cmd = mrq->stop;
802 long time; 796 long time;
803 797
804 if (mrq->cmd->opcode == MMC_READ_MULTIPLE_BLOCK) 798 if (mrq->cmd->opcode == MMC_READ_MULTIPLE_BLOCK)
@@ -867,11 +861,11 @@ static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq)
867 sh_mmcif_start_dma_tx(host); 861 sh_mmcif_start_dma_tx(host);
868 } 862 }
869 } 863 }
870 sh_mmcif_start_cmd(host, mrq, mrq->cmd); 864 sh_mmcif_start_cmd(host, mrq);
871 host->data = NULL; 865 host->data = NULL;
872 866
873 if (!mrq->cmd->error && mrq->stop) 867 if (!mrq->cmd->error && mrq->stop)
874 sh_mmcif_stop_cmd(host, mrq, mrq->stop); 868 sh_mmcif_stop_cmd(host, mrq);
875 host->state = STATE_IDLE; 869 host->state = STATE_IDLE;
876 mmc_request_done(mmc, mrq); 870 mmc_request_done(mmc, mrq);
877} 871}
@@ -948,11 +942,6 @@ static struct mmc_host_ops sh_mmcif_ops = {
948 .get_cd = sh_mmcif_get_cd, 942 .get_cd = sh_mmcif_get_cd,
949}; 943};
950 944
951static void sh_mmcif_detect(struct mmc_host *mmc)
952{
953 mmc_detect_change(mmc, 0);
954}
955
956static irqreturn_t sh_mmcif_intr(int irq, void *dev_id) 945static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
957{ 946{
958 struct sh_mmcif_host *host = dev_id; 947 struct sh_mmcif_host *host = dev_id;
@@ -1114,7 +1103,7 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
1114 goto clean_up3; 1103 goto clean_up3;
1115 } 1104 }
1116 1105
1117 sh_mmcif_detect(host->mmc); 1106 mmc_detect_change(host->mmc, 0);
1118 1107
1119 dev_info(&pdev->dev, "driver version %s\n", DRIVER_VERSION); 1108 dev_info(&pdev->dev, "driver version %s\n", DRIVER_VERSION);
1120 dev_dbg(&pdev->dev, "chip ver H'%04x\n", 1109 dev_dbg(&pdev->dev, "chip ver H'%04x\n",