From: tony@atomide.com (Tony Lindgren)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 2/9] pinctrl: single: support gpio request and free
Date: Mon, 22 Oct 2012 13:28:07 -0700 [thread overview]
Message-ID: <20121022202805.GG4730@atomide.com> (raw)
In-Reply-To: <1350922139-3693-3-git-send-email-haojian.zhuang@gmail.com>
* Haojian Zhuang <haojian.zhuang@gmail.com> [121022 09:11]:
> Marvell's PXA/MMP silicon also match the behavior of pinctrl-single.
> Each pin binds to one register. A lot of pins could be configured
> as gpio.
>
> Now add three properties in below.
> pinctrl-single,gpio-ranges: gpio range array
> pinctrl-single,gpio: <gpio base, npins in range, pin base in range>
> pinctrl-single,gpio-func: <gpio function value in mux>
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
> ---
> drivers/pinctrl/pinctrl-single.c | 94 +++++++++++++++++++++++++++++++++++++-
> 1 files changed, 92 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
> index 726a729..6a0b24b 100644
> --- a/drivers/pinctrl/pinctrl-single.c
> +++ b/drivers/pinctrl/pinctrl-single.c
> @@ -28,8 +28,10 @@
> #define DRIVER_NAME "pinctrl-single"
> #define PCS_MUX_PINS_NAME "pinctrl-single,pins"
> #define PCS_MUX_BITS_NAME "pinctrl-single,bits"
> +#define PCS_GPIO_FUNC_NAME "pinctrl-single,gpio-func"
I think we can now get rid of these defines, I initially added
them as we had a bit hard time finding a suitable name for the
driver. These are only used in one location, so let's not add
new ones here.
> static int pcs_request_gpio(struct pinctrl_dev *pctldev,
> - struct pinctrl_gpio_range *range, unsigned offset)
> + struct pinctrl_gpio_range *range, unsigned pin)
> {
> - return -ENOTSUPP;
> + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
> + struct pcs_gpio_range *gpio = NULL;
> + int end, mux_bytes;
> + unsigned data;
> +
> + gpio = container_of(range, struct pcs_gpio_range, range);
> + if (!gpio->func_en)
> + return 0;
> + end = range->pin_base + range->npins - 1;
> + if (pin < range->pin_base || pin > end) {
> + dev_err(pctldev->dev, "pin %d isn't in the range of "
> + "%d to %d\n", pin, range->pin_base, end);
> + return -EINVAL;
> + }
> + mux_bytes = pcs->width / BITS_PER_BYTE;
> + data = pcs_readl(pcs->base + pin * mux_bytes) & ~pcs->fmask;
> + data |= gpio->gpio_func;
> + pcs_writel(data, pcs->base + pin * mux_bytes);
> + return 0;
> }
I think I already commented on this one.. Is this safe if you don't
have GPIOs configured? Or should you return -ENODEV in that case?
> +static int __devinit pcs_add_gpio_range(struct device_node *node,
> + struct pcs_device *pcs)
> +{
> + struct pcs_gpio_range *gpio;
> + struct device_node *np;
> + const __be32 *list;
> + const char list_name[] = "pinctrl-single,gpio-ranges";
> + const char name[] = "pinctrl-single";
> + u32 gpiores[PCS_MAX_GPIO_VALUES];
> + int ret, size, i, mux_bytes = 0;
> +
> + list = of_get_property(node, list_name, &size);
> + if (!list)
> + return -ENOENT;
Here you should return 0 if not found, otherwise things go bad for
me at least as I don't have GPIOs configured. See more below.
> + gpio->range.name = kmemdup(name, sizeof(name), GFP_KERNEL);
> + pinctrl_add_gpio_range(pcs->pctl, &gpio->range);
Just checking.. These get released with pinctrl_unregister() when
unloading, right? And nothing else to free in pinctrl-single.c
either?
> @@ -975,6 +1061,10 @@ static int __devinit pcs_probe(struct platform_device *pdev)
> goto free;
> }
>
> + ret = pcs_add_gpio_range(np, pcs);
> + if (ret < 0)
> + return ret;
> +
Here you need to goto free on error. Maybe just fold in the
attached fix if that looks OK to you:
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -930,7 +930,7 @@ static int __devinit pcs_add_gpio_range(struct device_node *node,
list = of_get_property(node, list_name, &size);
if (!list)
- return -ENOENT;
+ return 0;
size = size / sizeof(*list);
for (i = 0; i < size; i++) {
np = of_parse_phandle(node, list_name, i);
@@ -1065,7 +1065,7 @@ static int __devinit pcs_probe(struct platform_device *pdev)
ret = pcs_add_gpio_range(np, pcs);
if (ret < 0)
- return ret;
+ goto free;
dev_info(pcs->dev, "%i pins at pa %p size %u\n",
pcs->desc.npins, pcs->base, pcs->size);
WARNING: multiple messages have this Message-ID (diff)
From: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
To: Haojian Zhuang <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Subject: Re: [PATCH v2 2/9] pinctrl: single: support gpio request and free
Date: Mon, 22 Oct 2012 13:28:07 -0700 [thread overview]
Message-ID: <20121022202805.GG4730@atomide.com> (raw)
In-Reply-To: <1350922139-3693-3-git-send-email-haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
* Haojian Zhuang <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> [121022 09:11]:
> Marvell's PXA/MMP silicon also match the behavior of pinctrl-single.
> Each pin binds to one register. A lot of pins could be configured
> as gpio.
>
> Now add three properties in below.
> pinctrl-single,gpio-ranges: gpio range array
> pinctrl-single,gpio: <gpio base, npins in range, pin base in range>
> pinctrl-single,gpio-func: <gpio function value in mux>
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
> drivers/pinctrl/pinctrl-single.c | 94 +++++++++++++++++++++++++++++++++++++-
> 1 files changed, 92 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
> index 726a729..6a0b24b 100644
> --- a/drivers/pinctrl/pinctrl-single.c
> +++ b/drivers/pinctrl/pinctrl-single.c
> @@ -28,8 +28,10 @@
> #define DRIVER_NAME "pinctrl-single"
> #define PCS_MUX_PINS_NAME "pinctrl-single,pins"
> #define PCS_MUX_BITS_NAME "pinctrl-single,bits"
> +#define PCS_GPIO_FUNC_NAME "pinctrl-single,gpio-func"
I think we can now get rid of these defines, I initially added
them as we had a bit hard time finding a suitable name for the
driver. These are only used in one location, so let's not add
new ones here.
> static int pcs_request_gpio(struct pinctrl_dev *pctldev,
> - struct pinctrl_gpio_range *range, unsigned offset)
> + struct pinctrl_gpio_range *range, unsigned pin)
> {
> - return -ENOTSUPP;
> + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
> + struct pcs_gpio_range *gpio = NULL;
> + int end, mux_bytes;
> + unsigned data;
> +
> + gpio = container_of(range, struct pcs_gpio_range, range);
> + if (!gpio->func_en)
> + return 0;
> + end = range->pin_base + range->npins - 1;
> + if (pin < range->pin_base || pin > end) {
> + dev_err(pctldev->dev, "pin %d isn't in the range of "
> + "%d to %d\n", pin, range->pin_base, end);
> + return -EINVAL;
> + }
> + mux_bytes = pcs->width / BITS_PER_BYTE;
> + data = pcs_readl(pcs->base + pin * mux_bytes) & ~pcs->fmask;
> + data |= gpio->gpio_func;
> + pcs_writel(data, pcs->base + pin * mux_bytes);
> + return 0;
> }
I think I already commented on this one.. Is this safe if you don't
have GPIOs configured? Or should you return -ENODEV in that case?
> +static int __devinit pcs_add_gpio_range(struct device_node *node,
> + struct pcs_device *pcs)
> +{
> + struct pcs_gpio_range *gpio;
> + struct device_node *np;
> + const __be32 *list;
> + const char list_name[] = "pinctrl-single,gpio-ranges";
> + const char name[] = "pinctrl-single";
> + u32 gpiores[PCS_MAX_GPIO_VALUES];
> + int ret, size, i, mux_bytes = 0;
> +
> + list = of_get_property(node, list_name, &size);
> + if (!list)
> + return -ENOENT;
Here you should return 0 if not found, otherwise things go bad for
me at least as I don't have GPIOs configured. See more below.
> + gpio->range.name = kmemdup(name, sizeof(name), GFP_KERNEL);
> + pinctrl_add_gpio_range(pcs->pctl, &gpio->range);
Just checking.. These get released with pinctrl_unregister() when
unloading, right? And nothing else to free in pinctrl-single.c
either?
> @@ -975,6 +1061,10 @@ static int __devinit pcs_probe(struct platform_device *pdev)
> goto free;
> }
>
> + ret = pcs_add_gpio_range(np, pcs);
> + if (ret < 0)
> + return ret;
> +
Here you need to goto free on error. Maybe just fold in the
attached fix if that looks OK to you:
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -930,7 +930,7 @@ static int __devinit pcs_add_gpio_range(struct device_node *node,
list = of_get_property(node, list_name, &size);
if (!list)
- return -ENOENT;
+ return 0;
size = size / sizeof(*list);
for (i = 0; i < size; i++) {
np = of_parse_phandle(node, list_name, i);
@@ -1065,7 +1065,7 @@ static int __devinit pcs_probe(struct platform_device *pdev)
ret = pcs_add_gpio_range(np, pcs);
if (ret < 0)
- return ret;
+ goto free;
dev_info(pcs->dev, "%i pins at pa %p size %u\n",
pcs->desc.npins, pcs->base, pcs->size);
next prev parent reply other threads:[~2012-10-22 20:28 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-22 16:08 [PATCH v2 0/9] support pinctrl single in arch pxa/mmp Haojian Zhuang
2012-10-22 16:08 ` Haojian Zhuang
2012-10-22 16:08 ` [PATCH v2 1/9] ARM: mmp: select pinctrl driver Haojian Zhuang
2012-10-22 16:08 ` Haojian Zhuang
2012-10-23 10:05 ` Linus Walleij
2012-10-23 10:05 ` Linus Walleij
2012-10-22 16:08 ` [PATCH v2 2/9] pinctrl: single: support gpio request and free Haojian Zhuang
2012-10-22 16:08 ` Haojian Zhuang
2012-10-22 20:28 ` Tony Lindgren [this message]
2012-10-22 20:28 ` Tony Lindgren
2012-10-22 21:37 ` Tony Lindgren
2012-10-22 21:37 ` Tony Lindgren
2012-10-29 1:55 ` Haojian Zhuang
2012-10-29 1:55 ` Haojian Zhuang
2012-10-29 1:58 ` Haojian Zhuang
2012-10-29 1:58 ` Haojian Zhuang
2012-10-22 16:08 ` [PATCH v2 3/9] pinctrl: single: support pinconf generic Haojian Zhuang
2012-10-22 16:08 ` Haojian Zhuang
2012-10-22 16:08 ` [PATCH v2 4/9] ARM: dts: support pinctrl single in pxa910 Haojian Zhuang
2012-10-22 16:08 ` Haojian Zhuang
2012-10-22 16:08 ` [PATCH v2 5/9] document: devicetree: bind pinconf with pin-single Haojian Zhuang
2012-10-22 16:08 ` Haojian Zhuang
2012-10-22 22:44 ` Stephen Warren
2012-10-22 22:44 ` Stephen Warren
2012-10-31 16:58 ` Haojian Zhuang
2012-10-31 16:58 ` Haojian Zhuang
2012-10-31 22:26 ` Stephen Warren
2012-10-31 22:26 ` Stephen Warren
2012-10-31 22:51 ` Haojian Zhuang
2012-10-31 22:51 ` Haojian Zhuang
2012-11-01 0:25 ` Tony Lindgren
2012-11-01 0:25 ` Tony Lindgren
2012-10-22 16:08 ` [PATCH v2 6/9] tty: pxa: configure pin Haojian Zhuang
2012-10-22 16:08 ` Haojian Zhuang
2012-10-23 10:07 ` Linus Walleij
2012-10-23 10:07 ` Linus Walleij
2012-10-22 16:08 ` [PATCH v2 7/9] i2c: pxa: use devm_kzalloc Haojian Zhuang
2012-10-22 16:08 ` Haojian Zhuang
2012-10-22 16:08 ` [PATCH v2 8/9] i2c: pxa: configure pinmux Haojian Zhuang
2012-10-22 16:08 ` Haojian Zhuang
2012-10-23 10:07 ` Linus Walleij
2012-10-23 10:07 ` Linus Walleij
2012-10-22 16:08 ` [PATCH v2 9/9] pinctrl: single: dump pinmux register value Haojian Zhuang
2012-10-22 16:08 ` Haojian Zhuang
2012-10-22 22:27 ` Tony Lindgren
2012-10-22 22:27 ` Tony Lindgren
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=20121022202805.GG4730@atomide.com \
--to=tony@atomide.com \
--cc=linux-arm-kernel@lists.infradead.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.