Message ID | 20230131210229.68129-2-paul@crapouillou.net |
---|---|
State | New |
Headers | show |
Series | [1/2] mmc: jz4740: Work around bug on JZ4760(B) | expand |
On Tue, 31 Jan 2023 at 22:02, Paul Cercueil <paul@crapouillou.net> wrote: > > Support enabling / disabling the vqmmc power supply if it was provided > by the firmware. > > Provide the .start_signal_voltage_switch callback to change the voltage > of the external vqmmc power supply. > > Signed-off-by: Paul Cercueil <paul@crapouillou.net> Applied for next, thanks! Kind regards Uffe > --- > drivers/mmc/host/jz4740_mmc.c | 38 ++++++++++++++++++++++++++++++++++- > 1 file changed, 37 insertions(+), 1 deletion(-) > > diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c > index eb8e9607b086..ccd2c3aed0f0 100644 > --- a/drivers/mmc/host/jz4740_mmc.c > +++ b/drivers/mmc/host/jz4740_mmc.c > @@ -21,6 +21,7 @@ > #include <linux/of_device.h> > #include <linux/pinctrl/consumer.h> > #include <linux/platform_device.h> > +#include <linux/regulator/consumer.h> > #include <linux/rwsem.h> > #include <linux/scatterlist.h> > > @@ -162,6 +163,8 @@ struct jz4740_mmc_host { > struct mmc_request *req; > struct mmc_command *cmd; > > + bool vqmmc_enabled; > + > unsigned long waiting; > > uint32_t cmdat; > @@ -943,6 +946,8 @@ static void jz4740_mmc_request(struct mmc_host *mmc, struct mmc_request *req) > static void jz4740_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) > { > struct jz4740_mmc_host *host = mmc_priv(mmc); > + int ret; > + > if (ios->clock) > jz4740_mmc_set_clock_rate(host, ios->clock); > > @@ -955,12 +960,25 @@ static void jz4740_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) > clk_prepare_enable(host->clk); > break; > case MMC_POWER_ON: > + if (!IS_ERR(mmc->supply.vqmmc) && !host->vqmmc_enabled) { > + ret = regulator_enable(mmc->supply.vqmmc); > + if (ret) > + dev_err(&host->pdev->dev, "Failed to set vqmmc power!\n"); > + else > + host->vqmmc_enabled = true; > + } > break; > - default: > + case MMC_POWER_OFF: > if (!IS_ERR(mmc->supply.vmmc)) > mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); > + if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) { > + regulator_disable(mmc->supply.vqmmc); > + host->vqmmc_enabled = false; > + } > clk_disable_unprepare(host->clk); > break; > + default: > + break; > } > > switch (ios->bus_width) { > @@ -986,6 +1004,23 @@ static void jz4740_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) > jz4740_mmc_set_irq_enabled(host, JZ_MMC_IRQ_SDIO, enable); > } > > +static int jz4740_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios) > +{ > + int ret; > + > + /* vqmmc regulator is available */ > + if (!IS_ERR(mmc->supply.vqmmc)) { > + ret = mmc_regulator_set_vqmmc(mmc, ios); > + return ret < 0 ? ret : 0; > + } > + > + /* no vqmmc regulator, assume fixed regulator at 3/3.3V */ > + if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) > + return 0; > + > + return -EINVAL; > +} > + > static const struct mmc_host_ops jz4740_mmc_ops = { > .request = jz4740_mmc_request, > .pre_req = jz4740_mmc_pre_request, > @@ -994,6 +1029,7 @@ static const struct mmc_host_ops jz4740_mmc_ops = { > .get_ro = mmc_gpio_get_ro, > .get_cd = mmc_gpio_get_cd, > .enable_sdio_irq = jz4740_mmc_enable_sdio_irq, > + .start_signal_voltage_switch = jz4740_voltage_switch, > }; > > static inline struct jz4740_mmc_host * > -- > 2.39.1 >
diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c index eb8e9607b086..ccd2c3aed0f0 100644 --- a/drivers/mmc/host/jz4740_mmc.c +++ b/drivers/mmc/host/jz4740_mmc.c @@ -21,6 +21,7 @@ #include <linux/of_device.h> #include <linux/pinctrl/consumer.h> #include <linux/platform_device.h> +#include <linux/regulator/consumer.h> #include <linux/rwsem.h> #include <linux/scatterlist.h> @@ -162,6 +163,8 @@ struct jz4740_mmc_host { struct mmc_request *req; struct mmc_command *cmd; + bool vqmmc_enabled; + unsigned long waiting; uint32_t cmdat; @@ -943,6 +946,8 @@ static void jz4740_mmc_request(struct mmc_host *mmc, struct mmc_request *req) static void jz4740_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { struct jz4740_mmc_host *host = mmc_priv(mmc); + int ret; + if (ios->clock) jz4740_mmc_set_clock_rate(host, ios->clock); @@ -955,12 +960,25 @@ static void jz4740_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) clk_prepare_enable(host->clk); break; case MMC_POWER_ON: + if (!IS_ERR(mmc->supply.vqmmc) && !host->vqmmc_enabled) { + ret = regulator_enable(mmc->supply.vqmmc); + if (ret) + dev_err(&host->pdev->dev, "Failed to set vqmmc power!\n"); + else + host->vqmmc_enabled = true; + } break; - default: + case MMC_POWER_OFF: if (!IS_ERR(mmc->supply.vmmc)) mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); + if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) { + regulator_disable(mmc->supply.vqmmc); + host->vqmmc_enabled = false; + } clk_disable_unprepare(host->clk); break; + default: + break; } switch (ios->bus_width) { @@ -986,6 +1004,23 @@ static void jz4740_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) jz4740_mmc_set_irq_enabled(host, JZ_MMC_IRQ_SDIO, enable); } +static int jz4740_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios) +{ + int ret; + + /* vqmmc regulator is available */ + if (!IS_ERR(mmc->supply.vqmmc)) { + ret = mmc_regulator_set_vqmmc(mmc, ios); + return ret < 0 ? ret : 0; + } + + /* no vqmmc regulator, assume fixed regulator at 3/3.3V */ + if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) + return 0; + + return -EINVAL; +} + static const struct mmc_host_ops jz4740_mmc_ops = { .request = jz4740_mmc_request, .pre_req = jz4740_mmc_pre_request, @@ -994,6 +1029,7 @@ static const struct mmc_host_ops jz4740_mmc_ops = { .get_ro = mmc_gpio_get_ro, .get_cd = mmc_gpio_get_cd, .enable_sdio_irq = jz4740_mmc_enable_sdio_irq, + .start_signal_voltage_switch = jz4740_voltage_switch, }; static inline struct jz4740_mmc_host *
Support enabling / disabling the vqmmc power supply if it was provided by the firmware. Provide the .start_signal_voltage_switch callback to change the voltage of the external vqmmc power supply. Signed-off-by: Paul Cercueil <paul@crapouillou.net> --- drivers/mmc/host/jz4740_mmc.c | 38 ++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-)