On Thu, 17 Oct 2024 at 15:20, Catalin Popescu <catalin.popescu@xxxxxxxxxxxxxxxxxxxx> wrote: > > Reset controls being refcounted, they allow to share gpios across > drivers. Right now, reset framework and reset-gpio driver supports only > one reset gpio, so add support for one single reset control. If more > than one reset gpio is configured in the device tree, then fallback to > classic gpio control. > > Signed-off-by: Catalin Popescu <catalin.popescu@xxxxxxxxxxxxxxxxxxxx> Applied for next, thanks! Kind regards Uffe > --- > v2: > - drop DT bindings patch > - use reset control with 1 reset gpio and fallback to gpio with > multiple reset gpios > --- > drivers/mmc/core/pwrseq_simple.c | 44 +++++++++++++++++++++++++------- > 1 file changed, 35 insertions(+), 9 deletions(-) > > diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c > index 9e016b0746f5..24e4e63a5dc8 100644 > --- a/drivers/mmc/core/pwrseq_simple.c > +++ b/drivers/mmc/core/pwrseq_simple.c > @@ -17,6 +17,8 @@ > #include <linux/gpio/consumer.h> > #include <linux/delay.h> > #include <linux/property.h> > +#include <linux/of.h> > +#include <linux/reset.h> > > #include <linux/mmc/host.h> > > @@ -29,6 +31,8 @@ struct mmc_pwrseq_simple { > u32 power_off_delay_us; > struct clk *ext_clk; > struct gpio_descs *reset_gpios; > + struct reset_control *reset_ctrl; > + bool use_reset; > }; > > #define to_pwrseq_simple(p) container_of(p, struct mmc_pwrseq_simple, pwrseq) > @@ -67,14 +71,21 @@ static void mmc_pwrseq_simple_pre_power_on(struct mmc_host *host) > pwrseq->clk_enabled = true; > } > > - mmc_pwrseq_simple_set_gpios_value(pwrseq, 1); > + if (pwrseq->use_reset) { > + reset_control_deassert(pwrseq->reset_ctrl); > + reset_control_assert(pwrseq->reset_ctrl); > + } else > + mmc_pwrseq_simple_set_gpios_value(pwrseq, 1); > } > > static void mmc_pwrseq_simple_post_power_on(struct mmc_host *host) > { > struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq); > > - mmc_pwrseq_simple_set_gpios_value(pwrseq, 0); > + if (pwrseq->use_reset) > + reset_control_deassert(pwrseq->reset_ctrl); > + else > + mmc_pwrseq_simple_set_gpios_value(pwrseq, 0); > > if (pwrseq->post_power_on_delay_ms) > msleep(pwrseq->post_power_on_delay_ms); > @@ -84,7 +95,10 @@ static void mmc_pwrseq_simple_power_off(struct mmc_host *host) > { > struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq); > > - mmc_pwrseq_simple_set_gpios_value(pwrseq, 1); > + if (pwrseq->use_reset) > + reset_control_assert(pwrseq->reset_ctrl); > + else > + mmc_pwrseq_simple_set_gpios_value(pwrseq, 1); > > if (pwrseq->power_off_delay_us) > usleep_range(pwrseq->power_off_delay_us, > @@ -112,6 +126,7 @@ static int mmc_pwrseq_simple_probe(struct platform_device *pdev) > { > struct mmc_pwrseq_simple *pwrseq; > struct device *dev = &pdev->dev; > + int ngpio; > > pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL); > if (!pwrseq) > @@ -121,12 +136,23 @@ static int mmc_pwrseq_simple_probe(struct platform_device *pdev) > if (IS_ERR(pwrseq->ext_clk) && PTR_ERR(pwrseq->ext_clk) != -ENOENT) > return dev_err_probe(dev, PTR_ERR(pwrseq->ext_clk), "external clock not ready\n"); > > - pwrseq->reset_gpios = devm_gpiod_get_array(dev, "reset", > - GPIOD_OUT_HIGH); > - if (IS_ERR(pwrseq->reset_gpios) && > - PTR_ERR(pwrseq->reset_gpios) != -ENOENT && > - PTR_ERR(pwrseq->reset_gpios) != -ENOSYS) { > - return dev_err_probe(dev, PTR_ERR(pwrseq->reset_gpios), "reset GPIOs not ready\n"); > + ngpio = of_count_phandle_with_args(dev->of_node, "reset-gpios", "#gpio-cells"); > + if (ngpio == 1) > + pwrseq->use_reset = true; > + > + if (pwrseq->use_reset) { > + pwrseq->reset_ctrl = devm_reset_control_get_optional_shared(dev, NULL); > + if (IS_ERR(pwrseq->reset_ctrl)) > + return dev_err_probe(dev, PTR_ERR(pwrseq->reset_ctrl), > + "reset control not ready\n"); > + } else { > + pwrseq->reset_gpios = devm_gpiod_get_array(dev, "reset", GPIOD_OUT_HIGH); > + if (IS_ERR(pwrseq->reset_gpios) && > + PTR_ERR(pwrseq->reset_gpios) != -ENOENT && > + PTR_ERR(pwrseq->reset_gpios) != -ENOSYS) { > + return dev_err_probe(dev, PTR_ERR(pwrseq->reset_gpios), > + "reset GPIOs not ready\n"); > + } > } > > device_property_read_u32(dev, "post-power-on-delay-ms", > > base-commit: 58ca61c1a866bfdaa5e19fb19a2416764f847d75 > prerequisite-patch-id: 0000000000000000000000000000000000000000 > -- > 2.34.1 >