diff options
| -rw-r--r-- | drivers/pinctrl/core.h | 13 | ||||
| -rw-r--r-- | drivers/pinctrl/pinmux.c | 72 |
2 files changed, 56 insertions, 29 deletions
diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index efbfb62ab147..17ecf651b123 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h | |||
| @@ -119,15 +119,15 @@ struct pinctrl_setting { | |||
| 119 | * @name: a name for the pin, e.g. the name of the pin/pad/finger on a | 119 | * @name: a name for the pin, e.g. the name of the pin/pad/finger on a |
| 120 | * datasheet or such | 120 | * datasheet or such |
| 121 | * @dynamic_name: if the name of this pin was dynamically allocated | 121 | * @dynamic_name: if the name of this pin was dynamically allocated |
| 122 | * @usecount: If zero, the pin is not claimed, and @owner should be NULL. | 122 | * @mux_usecount: If zero, the pin is not claimed, and @owner should be NULL. |
| 123 | * If non-zero, this pin is claimed by @owner. This field is an integer | 123 | * If non-zero, this pin is claimed by @owner. This field is an integer |
| 124 | * rather than a boolean, since pinctrl_get() might process multiple | 124 | * rather than a boolean, since pinctrl_get() might process multiple |
| 125 | * mapping table entries that refer to, and hence claim, the same group | 125 | * mapping table entries that refer to, and hence claim, the same group |
| 126 | * or pin, and each of these will increment the @usecount. | 126 | * or pin, and each of these will increment the @usecount. |
| 127 | * @owner: The name of the entity owning the pin. Typically, this is the name | 127 | * @mux_owner: The name of device that called pinctrl_get(). |
| 128 | * of the device that called pinctrl_get(). Alternatively, it may be the | ||
| 129 | * name of the GPIO passed to pinctrl_request_gpio(). | ||
| 130 | * @mux_setting: The most recent selected mux setting for this pin, if any. | 128 | * @mux_setting: The most recent selected mux setting for this pin, if any. |
| 129 | * @gpio_owner: If pinctrl_request_gpio() was called for this pin, this is | ||
| 130 | * the name of the GPIO that "owns" this pin. | ||
| 131 | */ | 131 | */ |
| 132 | struct pin_desc { | 132 | struct pin_desc { |
| 133 | struct pinctrl_dev *pctldev; | 133 | struct pinctrl_dev *pctldev; |
| @@ -135,9 +135,10 @@ struct pin_desc { | |||
| 135 | bool dynamic_name; | 135 | bool dynamic_name; |
| 136 | /* These fields only added when supporting pinmux drivers */ | 136 | /* These fields only added when supporting pinmux drivers */ |
| 137 | #ifdef CONFIG_PINMUX | 137 | #ifdef CONFIG_PINMUX |
| 138 | unsigned usecount; | 138 | unsigned mux_usecount; |
| 139 | const char *owner; | 139 | const char *mux_owner; |
| 140 | const struct pinctrl_setting_mux *mux_setting; | 140 | const struct pinctrl_setting_mux *mux_setting; |
| 141 | const char *gpio_owner; | ||
| 141 | #endif | 142 | #endif |
| 142 | }; | 143 | }; |
| 143 | 144 | ||
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 86e401754116..4e62783a573a 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c | |||
| @@ -94,17 +94,28 @@ static int pin_request(struct pinctrl_dev *pctldev, | |||
| 94 | goto out; | 94 | goto out; |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | if (desc->usecount && strcmp(desc->owner, owner)) { | 97 | if (gpio_range) { |
| 98 | dev_err(pctldev->dev, | 98 | /* There's no need to support multiple GPIO requests */ |
| 99 | "pin already requested\n"); | 99 | if (desc->gpio_owner) { |
| 100 | goto out; | 100 | dev_err(pctldev->dev, |
| 101 | } | 101 | "pin already requested\n"); |
| 102 | goto out; | ||
| 103 | } | ||
| 102 | 104 | ||
| 103 | desc->usecount++; | 105 | desc->gpio_owner = owner; |
| 104 | if (desc->usecount > 1) | 106 | } else { |
| 105 | return 0; | 107 | if (desc->mux_usecount && strcmp(desc->mux_owner, owner)) { |
| 108 | dev_err(pctldev->dev, | ||
| 109 | "pin already requested\n"); | ||
| 110 | goto out; | ||
| 111 | } | ||
| 106 | 112 | ||
| 107 | desc->owner = owner; | 113 | desc->mux_usecount++; |
| 114 | if (desc->mux_usecount > 1) | ||
| 115 | return 0; | ||
| 116 | |||
| 117 | desc->mux_owner = owner; | ||
| 118 | } | ||
| 108 | 119 | ||
| 109 | /* Let each pin increase references to this module */ | 120 | /* Let each pin increase references to this module */ |
| 110 | if (!try_module_get(pctldev->owner)) { | 121 | if (!try_module_get(pctldev->owner)) { |
| @@ -135,9 +146,13 @@ static int pin_request(struct pinctrl_dev *pctldev, | |||
| 135 | 146 | ||
| 136 | out_free_pin: | 147 | out_free_pin: |
| 137 | if (status) { | 148 | if (status) { |
| 138 | desc->usecount--; | 149 | if (gpio_range) { |
| 139 | if (!desc->usecount) | 150 | desc->gpio_owner = NULL; |
| 140 | desc->owner = NULL; | 151 | } else { |
| 152 | desc->mux_usecount--; | ||
| 153 | if (!desc->mux_usecount) | ||
| 154 | desc->mux_owner = NULL; | ||
| 155 | } | ||
| 141 | } | 156 | } |
| 142 | out: | 157 | out: |
| 143 | if (status) | 158 | if (status) |
| @@ -172,9 +187,11 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, | |||
| 172 | return NULL; | 187 | return NULL; |
| 173 | } | 188 | } |
| 174 | 189 | ||
| 175 | desc->usecount--; | 190 | if (!gpio_range) { |
| 176 | if (desc->usecount) | 191 | desc->mux_usecount--; |
| 177 | return NULL; | 192 | if (desc->mux_usecount) |
| 193 | return NULL; | ||
| 194 | } | ||
| 178 | 195 | ||
| 179 | /* | 196 | /* |
| 180 | * If there is no kind of request function for the pin we just assume | 197 | * If there is no kind of request function for the pin we just assume |
| @@ -185,9 +202,15 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, | |||
| 185 | else if (ops->free) | 202 | else if (ops->free) |
| 186 | ops->free(pctldev, pin); | 203 | ops->free(pctldev, pin); |
| 187 | 204 | ||
| 188 | owner = desc->owner; | 205 | if (gpio_range) { |
| 189 | desc->owner = NULL; | 206 | owner = desc->gpio_owner; |
| 190 | desc->mux_setting = NULL; | 207 | desc->gpio_owner = NULL; |
| 208 | } else { | ||
| 209 | owner = desc->mux_owner; | ||
| 210 | desc->mux_owner = NULL; | ||
| 211 | desc->mux_setting = NULL; | ||
| 212 | } | ||
| 213 | |||
| 191 | module_put(pctldev->owner); | 214 | module_put(pctldev->owner); |
| 192 | 215 | ||
| 193 | return owner; | 216 | return owner; |
| @@ -493,7 +516,7 @@ static int pinmux_pins_show(struct seq_file *s, void *what) | |||
| 493 | unsigned i, pin; | 516 | unsigned i, pin; |
| 494 | 517 | ||
| 495 | seq_puts(s, "Pinmux settings per pin\n"); | 518 | seq_puts(s, "Pinmux settings per pin\n"); |
| 496 | seq_puts(s, "Format: pin (name): owner\n"); | 519 | seq_puts(s, "Format: pin (name): mux_owner gpio_owner hog?\n"); |
| 497 | 520 | ||
| 498 | mutex_lock(&pinctrl_mutex); | 521 | mutex_lock(&pinctrl_mutex); |
| 499 | 522 | ||
| @@ -508,13 +531,16 @@ static int pinmux_pins_show(struct seq_file *s, void *what) | |||
| 508 | if (desc == NULL) | 531 | if (desc == NULL) |
| 509 | continue; | 532 | continue; |
| 510 | 533 | ||
| 511 | if (desc->owner && | 534 | if (desc->mux_owner && |
| 512 | !strcmp(desc->owner, pinctrl_dev_get_name(pctldev))) | 535 | !strcmp(desc->mux_owner, pinctrl_dev_get_name(pctldev))) |
| 513 | is_hog = true; | 536 | is_hog = true; |
| 514 | 537 | ||
| 515 | seq_printf(s, "pin %d (%s): %s%s", pin, | 538 | seq_printf(s, "pin %d (%s): %s %s%s", pin, |
| 516 | desc->name ? desc->name : "unnamed", | 539 | desc->name ? desc->name : "unnamed", |
| 517 | desc->owner ? desc->owner : "UNCLAIMED", | 540 | desc->mux_owner ? desc->mux_owner |
| 541 | : "(MUX UNCLAIMED)", | ||
| 542 | desc->gpio_owner ? desc->gpio_owner | ||
| 543 | : "(GPIO UNCLAIMED)", | ||
| 518 | is_hog ? " (HOG)" : ""); | 544 | is_hog ? " (HOG)" : ""); |
| 519 | 545 | ||
| 520 | if (desc->mux_setting) | 546 | if (desc->mux_setting) |
