From: Frank Rowand <frowand.list@gmail.com>
To: Geert Uytterhoeven <geert+renesas@glider.be>,
Linus Walleij <linus.walleij@linaro.org>,
Bartosz Golaszewski <bgolaszewski@baylibre.com>,
Pantelis Antoniou <pantelis.antoniou@konsulko.com>,
Rob Herring <robh+dt@kernel.org>,
Mark Rutland <mark.rutland@arm.com>
Cc: Peter Ujfalusi <peter.ujfalusi@ti.com>,
Chris Brandt <chris.brandt@renesas.com>,
linux-gpio@vger.kernel.org, devicetree@vger.kernel.org,
linux-renesas-soc@vger.kernel.org, linux-kernel@vger.kernel.org,
Frank Rowand <frowand.list@gmail.com>
Subject: Re: [PATCH v2 2/2] gpio: of: Add DT overlay support for GPIO hogs
Date: Thu, 20 Feb 2020 12:51:22 -0600 [thread overview]
Message-ID: <cad0d0a1-9838-55d3-a13e-29d8d5ae7f12@gmail.com> (raw)
In-Reply-To: <20200220130149.26283-3-geert+renesas@glider.be>
On 2/20/20 7:01 AM, Geert Uytterhoeven wrote:
> As GPIO hogs are configured at GPIO controller initialization time,
> adding/removing GPIO hogs in DT overlays does not work.
>
> Add support for GPIO hogs described in DT overlays by registering an OF
> reconfiguration notifier, to handle the addition and removal of GPIO hog
> subnodes to/from a GPIO controller device node.
>
> Note that when a GPIO hog device node is being removed, its "gpios"
> properties is no longer available, so we have to keep track of which
> node a hog belongs to, which is done by adding a pointer to the hog's
> device node to struct gpio_desc.
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---
> v2:
> - Drop RFC state,
> - Document that modifying existing gpio-hog nodes is not supported.
> ---
> drivers/gpio/gpiolib-of.c | 90 +++++++++++++++++++++++++++++++++++++++
> drivers/gpio/gpiolib-of.h | 2 +
> drivers/gpio/gpiolib.c | 14 ++++--
> drivers/gpio/gpiolib.h | 3 ++
> 4 files changed, 106 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
> index 2b47f93886075294..ccc449df3792ae97 100644
> --- a/drivers/gpio/gpiolib-of.c
> +++ b/drivers/gpio/gpiolib-of.c
> @@ -628,6 +628,10 @@ static int of_gpiochip_add_hog(struct gpio_chip *chip, struct device_node *hog)
> ret = gpiod_hog(desc, name, lflags, dflags);
> if (ret < 0)
> return ret;
> +
> +#ifdef CONFIG_OF_DYNAMIC
> + desc->hog = hog;
> +#endif
> }
>
> return 0;
> @@ -655,11 +659,97 @@ static int of_gpiochip_scan_gpios(struct gpio_chip *chip)
> of_node_put(np);
> return ret;
> }
> +
> + of_node_set_flag(np, OF_POPULATED);
> }
>
> return 0;
> }
>
> +#ifdef CONFIG_OF_DYNAMIC
> +/**
> + * of_gpiochip_remove_hog - Remove all hogs in a hog device node
> + * @chip: gpio chip to act on
> + * @hog: device node describing the hogs
> + */
> +static void of_gpiochip_remove_hog(struct gpio_chip *chip,
> + struct device_node *hog)
> +{
> + struct gpio_desc *descs = chip->gpiodev->descs;
> + unsigned int i;
> +
> + for (i = 0; i < chip->ngpio; i++) {
> + if (test_bit(FLAG_IS_HOGGED, &descs[i].flags) &&
> + descs[i].hog == hog)
> + gpiochip_free_own_desc(&descs[i]);
> + }
> +}
> +
> +static int of_gpiochip_match_node(struct gpio_chip *chip, void *data)
> +{
> + return chip->gpiodev->dev.of_node == data;
> +}
> +
> +static struct gpio_chip *of_find_gpiochip_by_node(struct device_node *np)
> +{
> + return gpiochip_find(np, of_gpiochip_match_node);
> +}
> +
> +static int of_gpio_notify(struct notifier_block *nb, unsigned long action,
> + void *arg)
> +{
> + struct of_reconfig_data *rd = arg;
> + struct gpio_chip *chip;
> + int ret;
> +
> + /*
> + * This only supports adding and removing complete gpio-hog nodes.
> + * Modifying an existing gpio-hog node is not supported (except for
> + * changing its "status" property, which is treated the same as
> + * addition/removal).
> + */
> + switch (of_reconfig_get_state_change(action, arg)) {
> + case OF_RECONFIG_CHANGE_ADD:
> + if (!of_property_read_bool(rd->dn, "gpio-hog"))
> + return NOTIFY_OK; /* not for us */
> +
> + if (of_node_test_and_set_flag(rd->dn, OF_POPULATED))
> + return NOTIFY_OK;
> +
> + chip = of_find_gpiochip_by_node(rd->dn->parent);
> + if (chip == NULL)
> + return NOTIFY_OK; /* not for us */
> +
> + ret = of_gpiochip_add_hog(chip, rd->dn);
> + if (ret < 0) {
> + pr_err("%s: failed to add hogs for %pOF\n", __func__,
> + rd->dn);
> + of_node_clear_flag(rd->dn, OF_POPULATED);
> + return notifier_from_errno(ret);
> + }
> + break;
> +
> + case OF_RECONFIG_CHANGE_REMOVE:
> + if (!of_node_check_flag(rd->dn, OF_POPULATED))
> + return NOTIFY_OK; /* already depopulated */
> +
> + chip = of_find_gpiochip_by_node(rd->dn->parent);
> + if (chip == NULL)
> + return NOTIFY_OK; /* not for us */
> +
> + of_gpiochip_remove_hog(chip, rd->dn);
> + of_node_clear_flag(rd->dn, OF_POPULATED);
> + break;
> + }
> +
> + return NOTIFY_OK;
> +}
> +
> +struct notifier_block gpio_of_notifier = {
> + .notifier_call = of_gpio_notify,
> +};
> +#endif /* CONFIG_OF_DYNAMIC */
> +
> /**
> * of_gpio_simple_xlate - translate gpiospec to the GPIO number and flags
> * @gc: pointer to the gpio_chip structure
> diff --git a/drivers/gpio/gpiolib-of.h b/drivers/gpio/gpiolib-of.h
> index 9768831b1fe2f25b..ed26664f153782fc 100644
> --- a/drivers/gpio/gpiolib-of.h
> +++ b/drivers/gpio/gpiolib-of.h
> @@ -35,4 +35,6 @@ static inline bool of_gpio_need_valid_mask(const struct gpio_chip *gc)
> }
> #endif /* CONFIG_OF_GPIO */
>
> +extern struct notifier_block gpio_of_notifier;
> +
> #endif /* GPIOLIB_OF_H */
> diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
> index 56de871060ea211e..6f312220fe80acaf 100644
> --- a/drivers/gpio/gpiolib.c
> +++ b/drivers/gpio/gpiolib.c
> @@ -2925,6 +2925,9 @@ static bool gpiod_free_commit(struct gpio_desc *desc)
> clear_bit(FLAG_PULL_DOWN, &desc->flags);
> clear_bit(FLAG_BIAS_DISABLE, &desc->flags);
> clear_bit(FLAG_IS_HOGGED, &desc->flags);
> +#ifdef CONFIG_OF_DYNAMIC
> + desc->hog = NULL;
> +#endif
> ret = true;
> }
>
> @@ -5126,10 +5129,15 @@ static int __init gpiolib_dev_init(void)
> if (ret < 0) {
> pr_err("gpiolib: failed to allocate char dev region\n");
> bus_unregister(&gpio_bus_type);
> - } else {
> - gpiolib_initialized = true;
> - gpiochip_setup_devs();
> + return ret;
> }
> +
> + gpiolib_initialized = true;
> + gpiochip_setup_devs();
> +
> + if (IS_ENABLED(CONFIG_OF_DYNAMIC))
> + WARN_ON(of_reconfig_notifier_register(&gpio_of_notifier));
> +
> return ret;
> }
> core_initcall(gpiolib_dev_init);
> diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
> index 3e0aab2945d82974..18c75e83fd7679ec 100644
> --- a/drivers/gpio/gpiolib.h
> +++ b/drivers/gpio/gpiolib.h
> @@ -119,6 +119,9 @@ struct gpio_desc {
> const char *label;
> /* Name of the GPIO */
> const char *name;
> +#ifdef CONFIG_OF_DYNAMIC
> + struct device_node *hog;
> +#endif
> };
>
> int gpiod_request(struct gpio_desc *desc, const char *label);
>
Reviewed-by: Frank Rowand <frank.rowand@sony.com>
next prev parent reply other threads:[~2020-02-20 18:51 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-02-20 13:01 [PATCH v2 0/2] gpio: of: Add DT overlay support for GPIO hogs Geert Uytterhoeven
2020-02-20 13:01 ` [PATCH v2 1/2] gpio: of: Extract of_gpiochip_add_hog() Geert Uytterhoeven
2020-02-20 18:50 ` Frank Rowand
2020-02-21 16:08 ` Linus Walleij
2020-02-21 17:18 ` Frank Rowand
2020-02-21 17:20 ` Frank Rowand
2020-02-28 22:43 ` Linus Walleij
2020-03-02 19:57 ` Frank Rowand
2020-02-20 13:01 ` [PATCH v2 2/2] gpio: of: Add DT overlay support for GPIO hogs Geert Uytterhoeven
2020-02-20 18:51 ` Frank Rowand [this message]
2020-02-21 16:10 ` Linus Walleij
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cad0d0a1-9838-55d3-a13e-29d8d5ae7f12@gmail.com \
--to=frowand.list@gmail.com \
--cc=bgolaszewski@baylibre.com \
--cc=chris.brandt@renesas.com \
--cc=devicetree@vger.kernel.org \
--cc=geert+renesas@glider.be \
--cc=linus.walleij@linaro.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-renesas-soc@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=pantelis.antoniou@konsulko.com \
--cc=peter.ujfalusi@ti.com \
--cc=robh+dt@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.