From cc6aa80dd1b75ee9f4661b4aa0719c13c66f1fde Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Sat, 28 Nov 2020 13:13:08 +0000 Subject: [PATCH 1/3] pinctrl: renesas: Make sure the pin type is updated after setting the MUX By default on startup all the pin types are configured to PINMUX_TYPE_NONE (in sh_pfc_map_pins()), when pin is set as GPIO the pin type is updated to PINMUX_TYPE_GPIO. But the type is not updated when the pin is set as a function in sh_pfc_pinctrl_pin_set() or sh_pfc_pinctrl_group_set() calls (these calls only set the MUX if the pin type is PINMUX_TYPE_NONE ie unused). So with the current implementation pin functionality could be overwritten silently, for example if the same pin is added for SPI and serial. This patch makes sure of updating pin type after every successful call to sh_pfc_config_mux() and thus fixing from pin functionality to be overwritten. Also a warning message is printed if the current pin is being overwritten before abort. This also avoids pin re-muxing to same type that is for example from command line device is asked to re-probe/select (mmc dev x) we return early with success in this case as the pin is already muxed. Signed-off-by: Lad Prabhakar Reviewed-by: Biju Das --- drivers/pinctrl/renesas/pfc.c | 52 +++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/drivers/pinctrl/renesas/pfc.c b/drivers/pinctrl/renesas/pfc.c index 8bb7e16f94..b9238d032c 100644 --- a/drivers/pinctrl/renesas/pfc.c +++ b/drivers/pinctrl/renesas/pfc.c @@ -44,6 +44,7 @@ enum sh_pfc_model { struct sh_pfc_pin_config { u32 type; + const char *name; }; struct sh_pfc_pinctrl { @@ -487,14 +488,21 @@ static int sh_pfc_gpio_request_enable(struct udevice *dev, idx = sh_pfc_get_pin_index(pfc, pin->pin); cfg = &pmx->configs[idx]; - if (cfg->type != PINMUX_TYPE_NONE) + if (cfg->type != PINMUX_TYPE_NONE) { + if (!strcmp(cfg->name, pin->name)) + return 0; + + dev_err(pfc->dev, "Pin already used as %s\n", + cfg->name); return -EBUSY; + } ret = sh_pfc_config_mux(pfc, pin->enum_id, PINMUX_TYPE_GPIO); if (ret) return ret; cfg->type = PINMUX_TYPE_GPIO; + cfg->name = "gpio"; return 0; } @@ -524,6 +532,7 @@ static int sh_pfc_gpio_disable_free(struct udevice *dev, cfg = &pmx->configs[idx]; cfg->type = PINMUX_TYPE_NONE; + cfg->name = "none"; return 0; } @@ -537,11 +546,25 @@ static int sh_pfc_pinctrl_pin_set(struct udevice *dev, unsigned pin_selector, const struct sh_pfc_pin *pin = &priv->pfc.info->pins[pin_selector]; int idx = sh_pfc_get_pin_index(pfc, pin->pin); struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; + int ret; - if (cfg->type != PINMUX_TYPE_NONE) + if (cfg->type != PINMUX_TYPE_NONE) { + if (!strcmp(cfg->name, pin->name)) + return 0; + + dev_err(pfc->dev, "Pin already used as %s\n", + cfg->name); return -EBUSY; + } - return sh_pfc_config_mux(pfc, pin->enum_id, PINMUX_TYPE_FUNCTION); + ret = sh_pfc_config_mux(pfc, pin->enum_id, PINMUX_TYPE_FUNCTION); + if (ret) + return ret; + + cfg->type = PINMUX_TYPE_FUNCTION; + cfg->name = "function"; + + return 0; } static int sh_pfc_pinctrl_group_set(struct udevice *dev, unsigned group_selector, @@ -551,23 +574,41 @@ static int sh_pfc_pinctrl_group_set(struct udevice *dev, unsigned group_selector struct sh_pfc_pinctrl *pmx = &priv->pmx; struct sh_pfc *pfc = &priv->pfc; const struct sh_pfc_pin_group *grp = &priv->pfc.info->groups[group_selector]; + bool grp_pins_configured = true; + struct sh_pfc_pin_config *cfg; unsigned int i; int ret = 0; + int idx; for (i = 0; i < grp->nr_pins; ++i) { - int idx = sh_pfc_get_pin_index(pfc, grp->pins[i]); - struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; + idx = sh_pfc_get_pin_index(pfc, grp->pins[i]); + cfg = &pmx->configs[idx]; if (cfg->type != PINMUX_TYPE_NONE) { + if (!strcmp(cfg->name, grp->name)) + continue; + + dev_err(pfc->dev, "Pin already used as %s\n", + cfg->name); ret = -EBUSY; goto done; + } else { + grp_pins_configured = false; } } + if (grp_pins_configured) + return 0; + for (i = 0; i < grp->nr_pins; ++i) { ret = sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION); if (ret < 0) break; + + idx = sh_pfc_get_pin_index(pfc, grp->pins[i]); + cfg = &pmx->configs[idx]; + cfg->type = PINMUX_TYPE_FUNCTION; + cfg->name = priv->pfc.info->groups[group_selector].name; } done: @@ -804,6 +845,7 @@ static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) for (i = 0; i < pfc->info->nr_pins; ++i) { struct sh_pfc_pin_config *cfg = &pmx->configs[i]; cfg->type = PINMUX_TYPE_NONE; + cfg->name = "none"; } return 0; From 8096e2426d4d61e3a41139b99db5cc554d45b87a Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Sat, 28 Nov 2020 13:13:09 +0000 Subject: [PATCH 2/3] pinctrl: renesas: Implement get_pin_muxing() callback Implement get_pin_muxing() callback so that pinmux status command can be used on Renesas platforms. Signed-off-by: Lad Prabhakar Reviewed-by: Biju Das --- drivers/pinctrl/renesas/pfc.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/pinctrl/renesas/pfc.c b/drivers/pinctrl/renesas/pfc.c index b9238d032c..6ff948420c 100644 --- a/drivers/pinctrl/renesas/pfc.c +++ b/drivers/pinctrl/renesas/pfc.c @@ -449,6 +449,30 @@ static const char *sh_pfc_pinctrl_get_group_name(struct udevice *dev, return priv->pfc.info->groups[selector].name; } +static int sh_pfc_pinctrl_get_pin_muxing(struct udevice *dev, + unsigned int selector, + char *buf, int size) +{ + struct sh_pfc_pinctrl_priv *priv = dev_get_priv(dev); + struct sh_pfc_pinctrl *pmx = &priv->pmx; + struct sh_pfc *pfc = &priv->pfc; + struct sh_pfc_pin_config *cfg; + const struct sh_pfc_pin *pin; + int idx; + + pin = &priv->pfc.info->pins[selector]; + if (!pin) { + snprintf(buf, size, "Unknown"); + return -EINVAL; + } + + idx = sh_pfc_get_pin_index(pfc, pin->pin); + cfg = &pmx->configs[idx]; + snprintf(buf, size, "%s", cfg->name); + + return 0; +} + static int sh_pfc_pinctrl_get_functions_count(struct udevice *dev) { struct sh_pfc_pinctrl_priv *priv = dev_get_priv(dev); @@ -815,6 +839,7 @@ static struct pinctrl_ops sh_pfc_pinctrl_ops = { .get_pin_name = sh_pfc_pinctrl_get_pin_name, .get_groups_count = sh_pfc_pinctrl_get_groups_count, .get_group_name = sh_pfc_pinctrl_get_group_name, + .get_pin_muxing = sh_pfc_pinctrl_get_pin_muxing, .get_functions_count = sh_pfc_pinctrl_get_functions_count, .get_function_name = sh_pfc_pinctrl_get_function_name, From 67704d6dfba5dcb3c33b0eb91e10f908c3dbbdcd Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Sun, 29 Nov 2020 13:21:53 +0000 Subject: [PATCH 3/3] ARM: dts: renesas: Remove leading 0x from rpc node Remove the leading "0x" from rpc node to fix the below dtc warning: Warning (simple_bus_reg): Node /soc/rpc@0xee200000 simple-bus unit address format error, expected "ee200000" Signed-off-by: Lad Prabhakar --- arch/arm/dts/r7s72100-gr-peach-u-boot.dts | 2 +- arch/arm/dts/r8a77950-u-boot.dtsi | 2 +- arch/arm/dts/r8a77960-u-boot.dtsi | 2 +- arch/arm/dts/r8a77965-u-boot.dtsi | 2 +- arch/arm/dts/r8a77970-u-boot.dtsi | 2 +- arch/arm/dts/r8a77980-u-boot.dtsi | 2 +- arch/arm/dts/r8a77990-u-boot.dtsi | 2 +- arch/arm/dts/r8a77995-u-boot.dtsi | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/arm/dts/r7s72100-gr-peach-u-boot.dts b/arch/arm/dts/r7s72100-gr-peach-u-boot.dts index 30e35e47d6..f48121a9a8 100644 --- a/arch/arm/dts/r7s72100-gr-peach-u-boot.dts +++ b/arch/arm/dts/r7s72100-gr-peach-u-boot.dts @@ -46,7 +46,7 @@ }; - rpc: rpc@0xee200000 { + rpc: rpc@ee200000 { compatible = "renesas,rpc-r7s72100", "renesas,rpc"; reg = <0x3fefa000 0x100>, <0x18000000 0x08000000>; bank-width = <2>; diff --git a/arch/arm/dts/r8a77950-u-boot.dtsi b/arch/arm/dts/r8a77950-u-boot.dtsi index 0317f47f0f..5a11651464 100644 --- a/arch/arm/dts/r8a77950-u-boot.dtsi +++ b/arch/arm/dts/r8a77950-u-boot.dtsi @@ -13,7 +13,7 @@ / { soc { - rpc: rpc@0xee200000 { + rpc: rpc@ee200000 { compatible = "renesas,rpc-r8a7795", "renesas,rpc"; reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>; clocks = <&cpg CPG_MOD 917>; diff --git a/arch/arm/dts/r8a77960-u-boot.dtsi b/arch/arm/dts/r8a77960-u-boot.dtsi index 826c2384bc..f1cae1c359 100644 --- a/arch/arm/dts/r8a77960-u-boot.dtsi +++ b/arch/arm/dts/r8a77960-u-boot.dtsi @@ -13,7 +13,7 @@ / { soc { - rpc: rpc@0xee200000 { + rpc: rpc@ee200000 { compatible = "renesas,rpc-r8a7796", "renesas,rpc"; reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>; clocks = <&cpg CPG_MOD 917>; diff --git a/arch/arm/dts/r8a77965-u-boot.dtsi b/arch/arm/dts/r8a77965-u-boot.dtsi index 33ff5b148b..9cc6f20537 100644 --- a/arch/arm/dts/r8a77965-u-boot.dtsi +++ b/arch/arm/dts/r8a77965-u-boot.dtsi @@ -13,7 +13,7 @@ / { soc { - rpc: rpc@0xee200000 { + rpc: rpc@ee200000 { compatible = "renesas,rpc-r8a77965", "renesas,rpc"; reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>; clocks = <&cpg CPG_MOD 917>; diff --git a/arch/arm/dts/r8a77970-u-boot.dtsi b/arch/arm/dts/r8a77970-u-boot.dtsi index eabab7ce58..ac3c6be4ad 100644 --- a/arch/arm/dts/r8a77970-u-boot.dtsi +++ b/arch/arm/dts/r8a77970-u-boot.dtsi @@ -13,7 +13,7 @@ / { soc { - rpc: rpc@0xee200000 { + rpc: rpc@ee200000 { compatible = "renesas,rpc-r8a77970", "renesas,rpc"; reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>; clocks = <&cpg CPG_MOD 917>; diff --git a/arch/arm/dts/r8a77980-u-boot.dtsi b/arch/arm/dts/r8a77980-u-boot.dtsi index 1050f6e991..365d40ac49 100644 --- a/arch/arm/dts/r8a77980-u-boot.dtsi +++ b/arch/arm/dts/r8a77980-u-boot.dtsi @@ -13,7 +13,7 @@ / { soc { - rpc: rpc@0xee200000 { + rpc: rpc@ee200000 { compatible = "renesas,rpc-r8a77980", "renesas,rpc"; reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>; clocks = <&cpg CPG_MOD 917>; diff --git a/arch/arm/dts/r8a77990-u-boot.dtsi b/arch/arm/dts/r8a77990-u-boot.dtsi index ddf8b62627..6655abe875 100644 --- a/arch/arm/dts/r8a77990-u-boot.dtsi +++ b/arch/arm/dts/r8a77990-u-boot.dtsi @@ -9,7 +9,7 @@ / { soc { - rpc: rpc@0xee200000 { + rpc: rpc@ee200000 { compatible = "renesas,rpc-r8a77990", "renesas,rpc"; reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>; clocks = <&cpg CPG_MOD 917>; diff --git a/arch/arm/dts/r8a77995-u-boot.dtsi b/arch/arm/dts/r8a77995-u-boot.dtsi index 8e9f6b7a7d..0917a80f09 100644 --- a/arch/arm/dts/r8a77995-u-boot.dtsi +++ b/arch/arm/dts/r8a77995-u-boot.dtsi @@ -9,7 +9,7 @@ / { soc { - rpc: rpc@0xee200000 { + rpc: rpc@ee200000 { compatible = "renesas,rpc-r8a77995", "renesas,rpc"; reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>; clocks = <&cpg CPG_MOD 917>;