Messages in this thread | | | Subject | Re: [PATCH 2/3] regulator: Only free GPIOs if the core requested them | From | Marek Szyprowski <> | Date | Fri, 23 Nov 2018 10:24:46 +0100 |
| |
Hi Charles,
On 2018-11-22 18:30, Charles Keepax wrote: > Currently, the regulator core will take ownership of any GPIO passed > into it. Makes end driver code fairly error prone as the normal devm_ > patterns of allocation don't work. Update the regulator core to only > free the GPIO if it requested it, this allows the drivers to manage the > GPIO lifetime as they normally would. > > Reported-by: Marek Szyprowski <m.szyprowski@samsung.com> > Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
> --- > drivers/regulator/core.c | 19 +++++++++++-------- > 1 file changed, 11 insertions(+), 8 deletions(-) > > diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c > index dbe2f2e6e6254..9da7d27c7145e 100644 > --- a/drivers/regulator/core.c > +++ b/drivers/regulator/core.c > @@ -83,6 +83,7 @@ struct regulator_enable_gpio { > u32 enable_count; /* a number of enabled shared GPIO */ > u32 request_count; /* a number of requested shared GPIO */ > unsigned int ena_gpio_invert:1; > + unsigned int locally_requested:1; > }; > > /* > @@ -2233,19 +2234,20 @@ static int regulator_ena_gpio_request(struct regulator_dev *rdev, > } > } > > + pin = kzalloc(sizeof(struct regulator_enable_gpio), GFP_KERNEL); > + if (pin == NULL) > + return -ENOMEM; > + > if (!config->ena_gpiod) { > ret = gpio_request_one(config->ena_gpio, > GPIOF_DIR_OUT | config->ena_gpio_flags, > rdev_get_name(rdev)); > - if (ret) > + if (ret) { > + kfree(pin); > return ret; > - } > + } > > - pin = kzalloc(sizeof(struct regulator_enable_gpio), GFP_KERNEL); > - if (pin == NULL) { > - if (!config->ena_gpiod) > - gpio_free(config->ena_gpio); > - return -ENOMEM; > + pin->locally_requested = 1; > } > > pin->gpiod = gpiod; > @@ -2270,7 +2272,8 @@ static void regulator_ena_gpio_free(struct regulator_dev *rdev) > if (pin->gpiod == rdev->ena_pin->gpiod) { > if (pin->request_count <= 1) { > pin->request_count = 0; > - gpiod_put(pin->gpiod); > + if (pin->locally_requested) > + gpiod_put(pin->gpiod); > list_del(&pin->list); > kfree(pin); > rdev->ena_pin = NULL;
Best regards -- Marek Szyprowski, PhD Samsung R&D Institute Poland
| |