sh-pfc: Configure pins as GPIOs at request time when handled externally
When a GPIO is handled by a separate driver the pinmux
gpio_set_direction() handler won't be called. The pin mux type then need
to be configured to GPIO at request time.
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c
index 97e6ea3..ced9a95 100644
--- a/drivers/pinctrl/sh-pfc/core.c
+++ b/drivers/pinctrl/sh-pfc/core.c
@@ -268,7 +268,7 @@
int ret;
switch (pinmux_type) {
-
+ case PINMUX_TYPE_GPIO:
case PINMUX_TYPE_FUNCTION:
range = NULL;
break;
@@ -297,6 +297,8 @@
enum_id = 0;
field = 0;
value = 0;
+
+ /* Iterate over all the configuration fields we need to update. */
while (1) {
pos = sh_pfc_mark_to_enum(pfc, mark, pos, &enum_id);
if (pos < 0)
@@ -305,18 +307,20 @@
if (!enum_id)
break;
- /* first check if this is a function enum */
+ /* Check if the configuration field selects a function. If it
+ * doesn't, skip the field if it's not applicable to the
+ * requested pinmux type.
+ */
in_range = sh_pfc_enum_in_range(enum_id, &pfc->info->function);
if (!in_range) {
- /* not a function enum */
- if (range) {
- /*
- * other range exists, so this pin is
- * a regular GPIO pin that now is being
- * bound to a specific direction.
- *
- * for this case we only allow function enums
- * and the enums that match the other range.
+ if (pinmux_type == PINMUX_TYPE_FUNCTION) {
+ /* Functions are allowed to modify all
+ * fields.
+ */
+ in_range = 1;
+ } else if (pinmux_type != PINMUX_TYPE_GPIO) {
+ /* Input/output types can only modify fields
+ * that correspond to their respective ranges.
*/
in_range = sh_pfc_enum_in_range(enum_id, range);
@@ -327,17 +331,8 @@
*/
if (in_range && enum_id == range->force)
continue;
- } else {
- /*
- * no other range exists, so this pin
- * must then be of the function type.
- *
- * allow function type pins to select
- * any combination of function/in/out
- * in their MARK lists.
- */
- in_range = 1;
}
+ /* GPIOs are only allowed to modify function fields. */
}
if (!in_range)