On 2022-03-19 15:41, Peter Rosin wrote: > On 2022-02-16 08:46, Patrick Rudolph wrote: >> Add a vdd regulator and enable it for boards that have the >> mux powered off by default. >> >> Signed-off-by: Patrick Rudolph <patrick.rudolph@xxxxxxxxxxxxx> >> --- >> drivers/i2c/muxes/i2c-mux-pca954x.c | 34 ++++++++++++++++++++++++----- >> 1 file changed, 29 insertions(+), 5 deletions(-) >> >> diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c >> index 33b9a6a1fffa..e25383752616 100644 >> --- a/drivers/i2c/muxes/i2c-mux-pca954x.c >> +++ b/drivers/i2c/muxes/i2c-mux-pca954x.c >> @@ -49,6 +49,7 @@ >> #include <linux/module.h> >> #include <linux/pm.h> >> #include <linux/property.h> >> +#include <linux/regulator/consumer.h> >> #include <linux/slab.h> >> #include <linux/spinlock.h> >> #include <dt-bindings/mux/mux.h> >> @@ -119,6 +120,7 @@ struct pca954x { >> struct irq_domain *irq; >> unsigned int irq_mask; >> raw_spinlock_t lock; >> + struct regulator *supply; >> }; >> >> /* Provide specs for the PCA954x and MAX735x types we know about */ >> @@ -459,6 +461,9 @@ static void pca954x_cleanup(struct i2c_mux_core *muxc) >> struct pca954x *data = i2c_mux_priv(muxc); >> int c, irq; >> >> + if (!IS_ERR_OR_NULL(data->supply)) Hmm, this is a bit confusing, but I guess it's fine since the cleanup function is then ok even if it at some point in the future is called before data->supply has been filled in. But this is what confused me into the below comment... >> + regulator_disable(data->supply); >> + >> if (data->irq) { >> for (c = 0; c < data->chip->nchans; c++) { >> irq = irq_find_mapping(data->irq, c); >> @@ -513,15 +518,32 @@ static int pca954x_probe(struct i2c_client *client, >> pca954x_select_chan, pca954x_deselect_mux); >> if (!muxc) >> return -ENOMEM; >> + >> data = i2c_mux_priv(muxc); >> >> i2c_set_clientdata(client, muxc); >> data->client = client; >> >> + data->supply = devm_regulator_get(dev, "vdd"); >> + if (IS_ERR(data->supply)) { >> + ret = PTR_ERR(data->supply); >> + if (ret != -EPROBE_DEFER) >> + dev_err(dev, "Failed to request regulator: %d\n", ret); >> + return ret; >> + } >> + > > I think you need enclose the below in "if (data->supply)" I just realized that no, you don't, because it falls back to the dummy regulator. But then, data->supply cannot be NULL, but see above for why it's a good thing to check for it either way when cleaning up. All is fine as-is. Reviewed-by: Peter Rosin <peda@xxxxxxxxxx> Cheers, Peter >> + ret = regulator_enable(data->supply); >> + if (ret) { >> + dev_err(dev, "Failed to enable regulator: %d\n", ret); >> + return ret; >> + } >> + >> /* Reset the mux if a reset GPIO is specified. */ >> gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); >> - if (IS_ERR(gpio)) >> - return PTR_ERR(gpio); >> + if (IS_ERR(gpio)) { >> + ret = PTR_ERR(gpio); >> + goto fail_cleanup; >> + } >> if (gpio) { >> udelay(1); >> gpiod_set_value_cansleep(gpio, 0); >> @@ -538,7 +560,7 @@ static int pca954x_probe(struct i2c_client *client, >> >> ret = i2c_get_device_id(client, &id); >> if (ret && ret != -EOPNOTSUPP) >> - return ret; >> + goto fail_cleanup; >> >> if (!ret && >> (id.manufacturer_id != data->chip->id.manufacturer_id || >> @@ -546,7 +568,8 @@ static int pca954x_probe(struct i2c_client *client, >> dev_warn(dev, "unexpected device id %03x-%03x-%x\n", >> id.manufacturer_id, id.part_id, >> id.die_revision); >> - return -ENODEV; >> + ret = -ENODEV; >> + goto fail_cleanup; >> } >> } >> >> @@ -565,7 +588,8 @@ static int pca954x_probe(struct i2c_client *client, >> ret = pca954x_init(client, data); >> if (ret < 0) { >> dev_warn(dev, "probe failed\n"); >> - return -ENODEV; >> + ret = -ENODEV; >> + goto fail_cleanup; >> } >> >> ret = pca954x_irq_setup(muxc);