diff options
author | Ludovic Barre <ludovic.barre@st.com> | 2020-01-28 10:06:34 +0100 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2020-03-24 14:35:40 +0100 |
commit | 7577316528816e8e9a49c1b4b5822bacbc62d113 (patch) | |
tree | 3f85793c1eb4eb24c06cf282dfd5b36e81da91d0 /drivers/mmc | |
parent | mmc: mmci_sdmmc: Add execute tuning with delay block (diff) | |
download | linux-7577316528816e8e9a49c1b4b5822bacbc62d113.tar.xz linux-7577316528816e8e9a49c1b4b5822bacbc62d113.zip |
mmc: mmci: Add callbacks for to manage signal voltage switch
A variant may need to define some actions before and after a voltage
switch.
This patch adds 2 callbacks to manage signal voltage switch in the struct
mmci_host_ops. ->pre_sig_volt_switch() allows to prepare a signal voltage
switch before sending the SD_SWITCH_VOLTAGE command (CMD11).
->post_sig_volt_switch callback allows specific actions to be executed,
after the I/O signal voltage level has been changed.
Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Link: https://lore.kernel.org/r/20200128090636.13689-8-ludovic.barre@st.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/mmci.c | 8 | ||||
-rw-r--r-- | drivers/mmc/host/mmci.h | 2 |
2 files changed, 10 insertions, 0 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index d0a041c9e6cd..24e630183ed4 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -22,6 +22,7 @@ #include <linux/mmc/pm.h> #include <linux/mmc/host.h> #include <linux/mmc/card.h> +#include <linux/mmc/sd.h> #include <linux/mmc/slot-gpio.h> #include <linux/amba/bus.h> #include <linux/clk.h> @@ -1217,6 +1218,9 @@ mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c) writel_relaxed(clks, host->base + MMCIDATATIMER); } + if (host->ops->pre_sig_volt_switch && cmd->opcode == SD_SWITCH_VOLTAGE) + host->ops->pre_sig_volt_switch(host); + if (/*interrupt*/0) c |= MCI_CPSM_INTERRUPT; @@ -1830,6 +1834,7 @@ static int mmci_get_cd(struct mmc_host *mmc) static int mmci_sig_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios) { + struct mmci_host *host = mmc_priv(mmc); int ret = 0; if (!IS_ERR(mmc->supply.vqmmc)) { @@ -1849,6 +1854,9 @@ static int mmci_sig_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios) break; } + if (!ret && host->ops && host->ops->post_sig_volt_switch) + ret = host->ops->post_sig_volt_switch(host, ios); + if (ret) dev_warn(mmc_dev(mmc), "Voltage switch failed\n"); } diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index ddcdfb827996..c3bc0a38d4cb 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -377,6 +377,8 @@ struct mmci_host_ops { void (*set_clkreg)(struct mmci_host *host, unsigned int desired); void (*set_pwrreg)(struct mmci_host *host, unsigned int pwr); bool (*busy_complete)(struct mmci_host *host, u32 status, u32 err_msk); + void (*pre_sig_volt_switch)(struct mmci_host *host); + int (*post_sig_volt_switch)(struct mmci_host *host, struct mmc_ios *ios); }; struct mmci_host { |