aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@linaro.org>2014-12-05 06:59:40 -0500
committerUlf Hansson <ulf.hansson@linaro.org>2014-12-08 03:20:47 -0500
commitd1785326891c2f9919163be5dae8f2538cfcae58 (patch)
tree0599f9c6d18ca1f0b70cbd8deed2b266b238547d /drivers/mmc
parentfe5afb13d46e76b07ab7e732f2b694dcafef4d9d (diff)
mmc: sdhci-esdhc-imx: Convert to mmc_send_tuning()
Instead of having a local function taking care of sending the tuning command, let's use the common mmc_send_tuning() API provided by the mmc core. In this way the request will be handled as any other request by sdhci core. As an effect of this change, the pm_runtime_get_sync() call at esdhc_prepare_tuning() isn't needed any more. This patch will also introduce another change in behavior, since before the response pattern to the tuning command wasn't verified by sdhci-esdhc-imx. The mmc_send_tuning() does that. Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Tested-by: Dong Aisheng <b29396@freescale.com> Acked-by: Dong Aisheng <b29396@freescale.com>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c68
1 files changed, 3 insertions, 65 deletions
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 0135f00f826f..12711ab51aed 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -65,8 +65,6 @@
65/* NOTE: the minimum valid tuning start tap for mx6sl is 1 */ 65/* NOTE: the minimum valid tuning start tap for mx6sl is 1 */
66#define ESDHC_TUNING_START_TAP 0x1 66#define ESDHC_TUNING_START_TAP 0x1
67 67
68#define ESDHC_TUNING_BLOCK_PATTERN_LEN 64
69
70/* pinctrl state */ 68/* pinctrl state */
71#define ESDHC_PINCTRL_STATE_100MHZ "state_100mhz" 69#define ESDHC_PINCTRL_STATE_100MHZ "state_100mhz"
72#define ESDHC_PINCTRL_STATE_200MHZ "state_200mhz" 70#define ESDHC_PINCTRL_STATE_200MHZ "state_200mhz"
@@ -692,8 +690,6 @@ static void esdhc_prepare_tuning(struct sdhci_host *host, u32 val)
692 /* FIXME: delay a bit for card to be ready for next tuning due to errors */ 690 /* FIXME: delay a bit for card to be ready for next tuning due to errors */
693 mdelay(1); 691 mdelay(1);
694 692
695 /* This is balanced by the runtime put in sdhci_tasklet_finish */
696 pm_runtime_get_sync(host->mmc->parent);
697 reg = readl(host->ioaddr + ESDHC_MIX_CTRL); 693 reg = readl(host->ioaddr + ESDHC_MIX_CTRL);
698 reg |= ESDHC_MIX_CTRL_EXE_TUNE | ESDHC_MIX_CTRL_SMPCLK_SEL | 694 reg |= ESDHC_MIX_CTRL_EXE_TUNE | ESDHC_MIX_CTRL_SMPCLK_SEL |
699 ESDHC_MIX_CTRL_FBCLK_SEL; 695 ESDHC_MIX_CTRL_FBCLK_SEL;
@@ -704,54 +700,6 @@ static void esdhc_prepare_tuning(struct sdhci_host *host, u32 val)
704 val, readl(host->ioaddr + ESDHC_TUNE_CTRL_STATUS)); 700 val, readl(host->ioaddr + ESDHC_TUNE_CTRL_STATUS));
705} 701}
706 702
707static void esdhc_request_done(struct mmc_request *mrq)
708{
709 complete(&mrq->completion);
710}
711
712static int esdhc_send_tuning_cmd(struct sdhci_host *host, u32 opcode,
713 struct scatterlist *sg)
714{
715 struct mmc_command cmd = {0};
716 struct mmc_request mrq = {NULL};
717 struct mmc_data data = {0};
718
719 cmd.opcode = opcode;
720 cmd.arg = 0;
721 cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
722
723 data.blksz = ESDHC_TUNING_BLOCK_PATTERN_LEN;
724 data.blocks = 1;
725 data.flags = MMC_DATA_READ;
726 data.sg = sg;
727 data.sg_len = 1;
728
729 mrq.cmd = &cmd;
730 mrq.cmd->mrq = &mrq;
731 mrq.data = &data;
732 mrq.data->mrq = &mrq;
733 mrq.cmd->data = mrq.data;
734
735 mrq.done = esdhc_request_done;
736 init_completion(&(mrq.completion));
737
738 spin_lock_irq(&host->lock);
739 host->mrq = &mrq;
740
741 sdhci_send_command(host, mrq.cmd);
742
743 spin_unlock_irq(&host->lock);
744
745 wait_for_completion(&mrq.completion);
746
747 if (cmd.error)
748 return cmd.error;
749 if (data.error)
750 return data.error;
751
752 return 0;
753}
754
755static void esdhc_post_tuning(struct sdhci_host *host) 703static void esdhc_post_tuning(struct sdhci_host *host)
756{ 704{
757 u32 reg; 705 u32 reg;
@@ -763,21 +711,13 @@ static void esdhc_post_tuning(struct sdhci_host *host)
763 711
764static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode) 712static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
765{ 713{
766 struct scatterlist sg;
767 char *tuning_pattern;
768 int min, max, avg, ret; 714 int min, max, avg, ret;
769 715
770 tuning_pattern = kmalloc(ESDHC_TUNING_BLOCK_PATTERN_LEN, GFP_KERNEL);
771 if (!tuning_pattern)
772 return -ENOMEM;
773
774 sg_init_one(&sg, tuning_pattern, ESDHC_TUNING_BLOCK_PATTERN_LEN);
775
776 /* find the mininum delay first which can pass tuning */ 716 /* find the mininum delay first which can pass tuning */
777 min = ESDHC_TUNE_CTRL_MIN; 717 min = ESDHC_TUNE_CTRL_MIN;
778 while (min < ESDHC_TUNE_CTRL_MAX) { 718 while (min < ESDHC_TUNE_CTRL_MAX) {
779 esdhc_prepare_tuning(host, min); 719 esdhc_prepare_tuning(host, min);
780 if (!esdhc_send_tuning_cmd(host, opcode, &sg)) 720 if (!mmc_send_tuning(host->mmc))
781 break; 721 break;
782 min += ESDHC_TUNE_CTRL_STEP; 722 min += ESDHC_TUNE_CTRL_STEP;
783 } 723 }
@@ -786,7 +726,7 @@ static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
786 max = min + ESDHC_TUNE_CTRL_STEP; 726 max = min + ESDHC_TUNE_CTRL_STEP;
787 while (max < ESDHC_TUNE_CTRL_MAX) { 727 while (max < ESDHC_TUNE_CTRL_MAX) {
788 esdhc_prepare_tuning(host, max); 728 esdhc_prepare_tuning(host, max);
789 if (esdhc_send_tuning_cmd(host, opcode, &sg)) { 729 if (mmc_send_tuning(host->mmc)) {
790 max -= ESDHC_TUNE_CTRL_STEP; 730 max -= ESDHC_TUNE_CTRL_STEP;
791 break; 731 break;
792 } 732 }
@@ -796,11 +736,9 @@ static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
796 /* use average delay to get the best timing */ 736 /* use average delay to get the best timing */
797 avg = (min + max) / 2; 737 avg = (min + max) / 2;
798 esdhc_prepare_tuning(host, avg); 738 esdhc_prepare_tuning(host, avg);
799 ret = esdhc_send_tuning_cmd(host, opcode, &sg); 739 ret = mmc_send_tuning(host->mmc);
800 esdhc_post_tuning(host); 740 esdhc_post_tuning(host);
801 741
802 kfree(tuning_pattern);
803
804 dev_dbg(mmc_dev(host->mmc), "tunning %s at 0x%x ret %d\n", 742 dev_dbg(mmc_dev(host->mmc), "tunning %s at 0x%x ret %d\n",
805 ret ? "failed" : "passed", avg, ret); 743 ret ? "failed" : "passed", avg, ret);
806 744