From: Ray Jui <rjui@broadcom.com>
To: Jonas Gorski <jogo@openwrt.org>, linux-gpio@vger.kernel.org
Cc: Linus Walleij <linus.walleij@linaro.org>,
Alexandre Courbot <gnurou@gmail.com>,
Florian Fainelli <f.fainelli@gmail.com>,
Scott Branden <sbranden@broadcom.com>,
Pramod KUMAR <pramodku@broadcom.com>,
Vikram Prakash <vikramp@broadcom.com>,
Yendapally Reddy Dhananjaya Reddy <yrdreddy@broadcom.com>
Subject: Re: [PATCH RFC/RFT 1/2] gpio: allow atomic registration of gpio chip with pin ranges
Date: Tue, 13 Oct 2015 13:32:47 -0700 [thread overview]
Message-ID: <561D6A6F.2080009@broadcom.com> (raw)
In-Reply-To: <1444578499-17980-2-git-send-email-jogo@openwrt.org>
++ Broadcom engineers working on Cygnus GPIO driver
On 10/11/2015 8:48 AM, Jonas Gorski wrote:
> Allow registering gpio chip with ranges at the same time, so we know
> at registration time whether there is an associated pin controller.
>
> This allows us to automatically populate the request/free callbacks,
> so that drivers are free to omit the assignment, if they do not need
> any special handling.
>
> Signed-off-by: Jonas Gorski <jogo@openwrt.org>
> ---
> drivers/gpio/gpiolib-of.c | 5 +++++
> drivers/gpio/gpiolib.c | 43 +++++++++++++++++++++++++++++++++++--------
> drivers/gpio/gpiolib.h | 9 +++++++++
> include/linux/gpio/driver.h | 10 +++++++++-
> 4 files changed, 58 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
> index 5fe34a9..e05f0c2e 100644
> --- a/drivers/gpio/gpiolib-of.c
> +++ b/drivers/gpio/gpiolib-of.c
> @@ -415,6 +415,11 @@ static int of_gpiochip_add_pin_range(struct gpio_chip *chip)
> return 0;
> }
>
> +bool of_gpiochip_has_pin_range(struct gpio_chip *chip)
> +{
> + return !!of_find_property(chip->of_node, "gpio-ranges", NULL);
> +}
> +
> #else
> static int of_gpiochip_add_pin_range(struct gpio_chip *chip) { return 0; }
> #endif
> diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
> index 8eba02d..09d87ae 100644
> --- a/drivers/gpio/gpiolib.c
> +++ b/drivers/gpio/gpiolib.c
> @@ -280,30 +280,47 @@ static int gpiochip_set_desc_names(struct gpio_chip *gc)
> }
>
> /**
> - * gpiochip_add() - register a gpio_chip
> + * gpiochip_add_with_ranges() - register a gpio_chip with pin ranges
> * @chip: the chip to register, with chip->base initialized
> + * @pinctrl_name: the dev_name() of the pin controller to map to
> + * @ranges: the mappings of relative gpio offsets to pins
> + * @nranges: the number of ranges
> * Context: potentially before irqs will work
> *
> * Returns a negative errno if the chip can't be registered, such as
> * because the chip->base is invalid or already associated with a
> * different chip. Otherwise it returns zero as a success code.
> *
> - * When gpiochip_add() is called very early during boot, so that GPIOs
> - * can be freely used, the chip->dev device must be registered before
> - * the gpio framework's arch_initcall(). Otherwise sysfs initialization
> - * for GPIOs will fail rudely.
> + * When gpiochip_add_with_ranges() is called very early during boot, so
> + * that GPIOs can be freely used, the chip->dev device must be
> + * registered before the gpio framework's arch_initcall(). Otherwise
> + * sysfs initialization for GPIOs will fail rudely.
> *
> * If chip->base is negative, this requests dynamic assignment of
> * a range of valid GPIOs.
> + *
> + * If nranges is zero, pinctrl_name and ranges may be NULL.
> + * If nranges is not zero or chip->of_node is populated and has a
> + * "gpio-ranges" property, chip->request and chip->free will be populated
> + * with generic callbacks if not yet set.
> */
> -int gpiochip_add(struct gpio_chip *chip)
> +int gpiochip_add_with_ranges(struct gpio_chip *chip, const char *pinctl_name,
> + const struct pinctrl_gpio_range *ranges,
> + unsigned int nranges)
> {
> unsigned long flags;
> int status = 0;
> - unsigned id;
> + unsigned id, i;
> int base = chip->base;
> struct gpio_desc *descs;
>
> + if ((ranges > 0) || of_gpiochip_has_pin_range(chip)) {
> + if (!chip->request)
> + chip->request = gpiochip_generic_request;
> + if (!chip->free)
> + chip->free = gpiochip_generic_free;
> + }
> +
> descs = kcalloc(chip->ngpio, sizeof(descs[0]), GFP_KERNEL);
> if (!descs)
> return -ENOMEM;
> @@ -359,6 +376,15 @@ int gpiochip_add(struct gpio_chip *chip)
> if (status)
> goto err_remove_chip;
>
> + for (i = 0; i < nranges; i++) {
> + const struct pinctrl_gpio_range *range = &ranges[i];
> +
> + status = gpiochip_add_pin_range(chip, pinctl_name, range->base,
> + range->pin_base, range->npins);
> + if (status)
> + goto err_remove_chip;
> + }
> +
> acpi_gpiochip_add(chip);
>
> status = gpiochip_sysfs_register(chip);
> @@ -373,6 +399,7 @@ int gpiochip_add(struct gpio_chip *chip)
>
> err_remove_chip:
> acpi_gpiochip_remove(chip);
> + gpiochip_remove_pin_ranges(chip);
> gpiochip_free_hogs(chip);
> of_gpiochip_remove(chip);
> err_remove_from_list:
> @@ -389,7 +416,7 @@ err_free_descs:
> chip->label ? : "generic");
> return status;
> }
> -EXPORT_SYMBOL_GPL(gpiochip_add);
> +EXPORT_SYMBOL_GPL(gpiochip_add_with_ranges);
>
> /**
> * gpiochip_remove() - unregister a gpio_chip
> diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
> index 78e634d..6f49e25 100644
> --- a/drivers/gpio/gpiolib.h
> +++ b/drivers/gpio/gpiolib.h
> @@ -72,6 +72,15 @@ struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np,
>
> struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip, u16 hwnum);
>
> +#if defined(CONFIG_OF_GPIO) && defined(CONFIG_PINCTRL)
> +bool of_gpiochip_has_pin_range(struct gpio_chip *chip);
> +#else
> +static inline bool of_gpiochip_has_pin_range(struct gpio_chip *chip)
> +{
> + return false;
> +}
> +#endif
> +
> extern struct spinlock gpio_lock;
> extern struct list_head gpio_chips;
>
> diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
> index d1baebf..727ae9e 100644
> --- a/include/linux/gpio/driver.h
> +++ b/include/linux/gpio/driver.h
> @@ -166,7 +166,15 @@ extern const char *gpiochip_is_requested(struct gpio_chip *chip,
> unsigned offset);
>
> /* add/remove chips */
> -extern int gpiochip_add(struct gpio_chip *chip);
> +int gpiochip_add_with_ranges(struct gpio_chip *chip, const char *pinctl_name,
> + const struct pinctrl_gpio_range *ranges,
> + unsigned int nranges);
> +
> +static inline int gpiochip_add(struct gpio_chip *chip)
> +{
> + return gpiochip_add_with_ranges(chip, NULL, NULL, 0);
> +}
> +
> extern void gpiochip_remove(struct gpio_chip *chip);
> extern struct gpio_chip *gpiochip_find(void *data,
> int (*match)(struct gpio_chip *chip, void *data));
>
next prev parent reply other threads:[~2015-10-13 20:33 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-11 15:48 [PATCH RFC/RFT 0/2] gpio: allow auto population of request/free Jonas Gorski
2015-10-11 15:48 ` [PATCH RFC/RFT 1/2] gpio: allow atomic registration of gpio chip with pin ranges Jonas Gorski
2015-10-13 20:32 ` Ray Jui [this message]
2015-10-16 21:10 ` Linus Walleij
2015-10-11 15:48 ` [PATCH RFC/RFT 2/2] pinctrl-cygnus-gpio: convert to use gpiochip_add_with_ranges Jonas Gorski
2015-10-13 20:34 ` Ray Jui
2015-10-13 20:31 ` [PATCH RFC/RFT 0/2] gpio: allow auto population of request/free Ray Jui
2015-10-16 21:04 ` Linus Walleij
2015-10-16 21:10 ` Ray Jui
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=561D6A6F.2080009@broadcom.com \
--to=rjui@broadcom.com \
--cc=f.fainelli@gmail.com \
--cc=gnurou@gmail.com \
--cc=jogo@openwrt.org \
--cc=linus.walleij@linaro.org \
--cc=linux-gpio@vger.kernel.org \
--cc=pramodku@broadcom.com \
--cc=sbranden@broadcom.com \
--cc=vikramp@broadcom.com \
--cc=yrdreddy@broadcom.com \
/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.