pinctrl: allow exlusive GPIO/mux pin allocation
authorSonic Zhang <sonic.zhang@analog.com>
Thu, 9 Apr 2015 03:13:07 +0000 (11:13 +0800)
committerLinus Walleij <linus.walleij@linaro.org>
Wed, 6 May 2015 12:45:19 +0000 (14:45 +0200)
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 <sonic.zhang@analog.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Documentation/pinctrl.txt
drivers/pinctrl/pinctrl-adi2.c
drivers/pinctrl/pinmux.c
include/linux/pinctrl/pinctrl.h

index a9b47163bb5d6903f4c8f6fa436fca5977e4556d..d6b2bed94c43ff4b004faec7269d32d54a438984 100644 (file)
@@ -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:
 
index 8434439c5017ac67fe6496bf446081ce73c35a92..fbd492668da182d6193b7552373170f597963958 100644 (file)
@@ -710,6 +710,7 @@ static struct pinctrl_desc adi_pinmux_desc = {
        .name = DRIVER_NAME,
        .pctlops = &adi_pctrl_ops,
        .pmxops = &adi_pinmux_ops,
+       .strict = true,
        .owner = THIS_MODULE,
 };
 
index b874458dcb885445b067a5711ffbe9ecef180c22..2546fa783464366ab4bbd31129b9f6343faf9601 100644 (file)
@@ -107,6 +107,13 @@ static int pin_request(struct pinctrl_dev *pctldev,
                                desc->name, desc->gpio_owner, owner);
                        goto out;
                }
+               if (pctldev->desc->strict && desc->mux_usecount &&
+                   strcmp(desc->mux_owner, owner)) {
+                       dev_err(pctldev->dev,
+                               "pin %s already requested by %s; cannot claim for %s\n",
+                               desc->name, desc->mux_owner, owner);
+                       goto out;
+               }
 
                desc->gpio_owner = owner;
        } else {
@@ -116,6 +123,12 @@ static int pin_request(struct pinctrl_dev *pctldev,
                                desc->name, desc->mux_owner, owner);
                        goto out;
                }
+               if (pctldev->desc->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);
+                       goto out;
+               }
 
                desc->mux_usecount++;
                if (desc->mux_usecount > 1)
index 66e4697516dea286fe403cff2fa0074c053824ba..fc6b0348c375de4aa0c4f260c49b2e6a6eb76743 100644 (file)
@@ -114,6 +114,8 @@ 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
@@ -132,6 +134,7 @@ 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;