From fa76a3db7093a527333c380df82a0f158d9b8299 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Thu, 9 Apr 2015 11:13:07 +0800 Subject: pinctrl: allow exlusive GPIO/mux pin allocation Disallow simultaneous use of the the GPIO and peripheral mux functions by setting a flag "strict" in struct pinctrl_desc. The blackfin pinmux and gpio controller doesn't allow user to set up a pin for both GPIO and peripheral function. So, add flag strict in struct pinctrl_desc to check both gpio_owner and mux_owner before approving the pin request. v2-changes: - if strict flag is set, check gpio_owner and mux_onwer in if and else clause v3-changes: - add kerneldoc for this struct - augment Documentation/pinctrl.txt Signed-off-by: Sonic Zhang Signed-off-by: Linus Walleij --- Documentation/pinctrl.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'Documentation/pinctrl.txt') diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index a9b47163bb5d..d6b2bed94c43 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -73,6 +73,7 @@ static struct pinctrl_desc foo_desc = { .pins = foo_pins, .npins = ARRAY_SIZE(foo_pins), .owner = THIS_MODULE, + .strict = true, }; int __init foo_probe(void) @@ -830,6 +831,11 @@ separate memory range only intended for GPIO driving, and the register range dealing with pin config and pin multiplexing get placed into a different memory range and a separate section of the data sheet. +A flag "strict" in struct pinctrl_desc is available to check and deny +simultaneous access to the same pin from GPIO and pin multiplexing +consumers on hardware of this type. The pinctrl driver should set this flag +accordingly. + (B) pin config @@ -850,6 +856,11 @@ possible that the GPIO, pin config and pin multiplex registers are placed into the same memory range and the same section of the data sheet, although that need not be the case. +In some pin controllers, although the physical pins are designed in the same +way as (B), the GPIO function still can't be enabled at the same time as the +peripheral functions. So again the "strict" flag should be set, denying +simultaneous activation by GPIO and other muxed in devices. + From a kernel point of view, however, these are different aspects of the hardware and shall be put into different subsystems: -- cgit v1.2.3 From 8c4c2016345feefcd289ce2479eb70286d30825a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 6 May 2015 14:19:13 +0200 Subject: pinctrl: move strict option to pinmux_ops While the pinmux_ops are ideally just a vtable for pin mux calls, the "strict" setting belongs so intuitively with the pin multiplexing that we should move it here anyway. Putting it in the top pinctrl_desc makes no sense. Cc: Sonic Zhang Signed-off-by: Linus Walleij --- Documentation/pinctrl.txt | 2 +- drivers/pinctrl/pinctrl-adi2.c | 2 +- drivers/pinctrl/pinmux.c | 4 ++-- include/linux/pinctrl/pinctrl.h | 3 --- include/linux/pinctrl/pinmux.h | 4 ++++ 5 files changed, 8 insertions(+), 7 deletions(-) (limited to 'Documentation/pinctrl.txt') diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index d6b2bed94c43..4976389e432d 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -73,7 +73,6 @@ static struct pinctrl_desc foo_desc = { .pins = foo_pins, .npins = ARRAY_SIZE(foo_pins), .owner = THIS_MODULE, - .strict = true, }; int __init foo_probe(void) @@ -715,6 +714,7 @@ static struct pinmux_ops foo_pmxops = { .get_function_name = foo_get_fname, .get_function_groups = foo_get_groups, .set_mux = foo_set_mux, + .strict = true, }; /* Pinmux operations are handled by some pin controller */ diff --git a/drivers/pinctrl/pinctrl-adi2.c b/drivers/pinctrl/pinctrl-adi2.c index fbd492668da1..49df9037b41e 100644 --- a/drivers/pinctrl/pinctrl-adi2.c +++ b/drivers/pinctrl/pinctrl-adi2.c @@ -703,6 +703,7 @@ static struct pinmux_ops adi_pinmux_ops = { .get_function_name = adi_pinmux_get_func_name, .get_function_groups = adi_pinmux_get_groups, .gpio_request_enable = adi_pinmux_request_gpio, + .strict = true, }; @@ -710,7 +711,6 @@ static struct pinctrl_desc adi_pinmux_desc = { .name = DRIVER_NAME, .pctlops = &adi_pctrl_ops, .pmxops = &adi_pinmux_ops, - .strict = true, .owner = THIS_MODULE, }; diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 2546fa783464..c58c168b06c2 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -107,7 +107,7 @@ static int pin_request(struct pinctrl_dev *pctldev, desc->name, desc->gpio_owner, owner); goto out; } - if (pctldev->desc->strict && desc->mux_usecount && + if (ops->strict && desc->mux_usecount && strcmp(desc->mux_owner, owner)) { dev_err(pctldev->dev, "pin %s already requested by %s; cannot claim for %s\n", @@ -123,7 +123,7 @@ static int pin_request(struct pinctrl_dev *pctldev, desc->name, desc->mux_owner, owner); goto out; } - if (pctldev->desc->strict && desc->gpio_owner) { + if (ops->strict && desc->gpio_owner) { dev_err(pctldev->dev, "pin %s already requested by %s; cannot claim for %s\n", desc->name, desc->gpio_owner, owner); diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h index fc6b0348c375..66e4697516de 100644 --- a/include/linux/pinctrl/pinctrl.h +++ b/include/linux/pinctrl/pinctrl.h @@ -114,8 +114,6 @@ struct pinctrl_ops { * of the pins field above * @pctlops: pin control operation vtable, to support global concepts like * grouping of pins, this is optional. - * @strict: check both gpio_owner and mux_owner strictly before approving - the pin request * @pmxops: pinmux operations vtable, if you support pinmuxing in your driver * @confops: pin config operations vtable, if you support pin configuration in * your driver @@ -134,7 +132,6 @@ struct pinctrl_desc { const struct pinctrl_ops *pctlops; const struct pinmux_ops *pmxops; const struct pinconf_ops *confops; - bool strict; struct module *owner; #ifdef CONFIG_GENERIC_PINCONF unsigned int num_custom_params; diff --git a/include/linux/pinctrl/pinmux.h b/include/linux/pinctrl/pinmux.h index 511bda9ed4bf..d3740fa7073f 100644 --- a/include/linux/pinctrl/pinmux.h +++ b/include/linux/pinctrl/pinmux.h @@ -56,6 +56,9 @@ struct pinctrl_dev; * depending on whether the GPIO is configured as input or output, * a direction selector function may be implemented as a backing * to the GPIO controllers that need pin muxing. + * @strict: do not allow simultaneous use of the same pin for GPIO and another + * function. Check both gpio_owner and mux_owner strictly before approving + * the pin request. */ struct pinmux_ops { int (*request) (struct pinctrl_dev *pctldev, unsigned offset); @@ -79,6 +82,7 @@ struct pinmux_ops { struct pinctrl_gpio_range *range, unsigned offset, bool input); + bool strict; }; #endif /* CONFIG_PINMUX */ -- cgit v1.2.3