diff options
author | Ulf Hansson <ulf.hansson@linaro.org> | 2014-12-05 06:59:40 -0500 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2014-12-08 03:20:47 -0500 |
commit | d1785326891c2f9919163be5dae8f2538cfcae58 (patch) | |
tree | 0599f9c6d18ca1f0b70cbd8deed2b266b238547d /drivers/mmc | |
parent | fe5afb13d46e76b07ab7e732f2b694dcafef4d9d (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.c | 68 |
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 | ||
707 | static void esdhc_request_done(struct mmc_request *mrq) | ||
708 | { | ||
709 | complete(&mrq->completion); | ||
710 | } | ||
711 | |||
712 | static 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 | |||
755 | static void esdhc_post_tuning(struct sdhci_host *host) | 703 | static 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 | ||
764 | static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode) | 712 | static 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 | ||