Linux GPIO subsystem development
 help / color / mirror / Atom feed
* [PATCH v2 0/4] generic pinmux dt_node_to_map implementation/spacemit driver converted to use it
@ 2026-05-19  9:37 Conor Dooley
  2026-05-19  9:37 ` [PATCH v2 1/4] pinctrl: generic: change signature of pinctrl_generic_to_map() to pass void data Conor Dooley
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Conor Dooley @ 2026-05-19  9:37 UTC (permalink / raw)
  To: Linus Walleij
  Cc: conor, Conor Dooley, Yixun Lan, Troy Mitchell, linux-gpio,
	linux-kernel, linux-riscv, spacemit

From: Conor Dooley <conor.dooley@microchip.com>

Hey folks,

Here's a real version of my generic pinmux dt_node_to_map
implementation. I tested this on my bpif3 but the dts in mainline is
very limited in terms of pinctrl use so I would really appreciate any
testing that could be done with a more complete setup.

If you try to apply this, it's on top of Frank's mux series. It's also
here if any of the spacemit-ters want to look at what I did to their
driver:
https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/log/?h=spacemit-pinctrl

Cheers,
Conor.

CC: Linus Walleij <linusw@kernel.org>
CC: Yixun Lan <dlan@kernel.org>
CC: Conor Dooley <conor.dooley@microchip.com>
CC: Troy Mitchell <troy.mitchell@linux.spacemit.com>
CC: linux-gpio@vger.kernel.org
CC: linux-kernel@vger.kernel.org
CC: linux-riscv@lists.infradead.org
CC: spacemit@lists.linux.dev

Conor Dooley (4):
  pinctrl: generic: change signature of pinctrl_generic_to_map() to pass
    void data
  pinctrl: add new generic groups/function creation function for pinmux
  pinctrl: spacemit: delete spacemit_pctrl_check_power()
  pinctrl: spacemit: move over to generic pinmux dt_node_to_map
    implementation

 drivers/pinctrl/pinconf.h             |  20 ++-
 drivers/pinctrl/pinctrl-generic.c     | 124 ++++++++++++++----
 drivers/pinctrl/spacemit/Kconfig      |   4 +-
 drivers/pinctrl/spacemit/pinctrl-k1.c | 177 ++------------------------
 4 files changed, 128 insertions(+), 197 deletions(-)

-- 
2.53.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2 1/4] pinctrl: generic: change signature of pinctrl_generic_to_map() to pass void data
  2026-05-19  9:37 [PATCH v2 0/4] generic pinmux dt_node_to_map implementation/spacemit driver converted to use it Conor Dooley
@ 2026-05-19  9:37 ` Conor Dooley
  2026-05-19  9:37 ` [PATCH v2 2/4] pinctrl: add new generic groups/function creation function for pinmux Conor Dooley
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Conor Dooley @ 2026-05-19  9:37 UTC (permalink / raw)
  To: Linus Walleij
  Cc: conor, Conor Dooley, Yixun Lan, Troy Mitchell, linux-gpio,
	linux-kernel, linux-riscv, spacemit

From: Conor Dooley <conor.dooley@microchip.com>

In order to make pinctrl_generic_to_map() usable for controllers that
use pinmux, change the functions char array pointer that it passes to
pinctrl_generic_add_group() to a void pointer. In the pinmux case this
property will contain the mux setting as a number rather than as strings
in the pins + functions case.

Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
 drivers/pinctrl/pinconf.h         | 6 ++----
 drivers/pinctrl/pinctrl-generic.c | 5 ++---
 2 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/pinctrl/pinconf.h b/drivers/pinctrl/pinconf.h
index 9711d16c38b62..b2fb757cc6ecb 100644
--- a/drivers/pinctrl/pinconf.h
+++ b/drivers/pinctrl/pinconf.h
@@ -177,8 +177,7 @@ int pinctrl_generic_to_map(struct pinctrl_dev *pctldev, struct device_node *pare
 			   struct device_node *np, struct pinctrl_map **maps,
 			   unsigned int *num_maps, unsigned int *num_reserved_maps,
 			   const char **group_name, unsigned int ngroups,
-			   const char **functions, unsigned int *pins,
-			   unsigned int npins);
+			   void *data, unsigned int *pins, unsigned int npins);
 #else
 static inline int
 pinctrl_generic_pins_function_dt_node_to_map(struct pinctrl_dev *pctldev,
@@ -194,8 +193,7 @@ pinctrl_generic_to_map(struct pinctrl_dev *pctldev, struct device_node *parent,
 		       struct device_node *np, struct pinctrl_map **maps,
 		       unsigned int *num_maps, unsigned int *num_reserved_maps,
 		       const char **group_name, unsigned int ngroups,
-		       const char **functions, unsigned int *pins,
-		       unsigned int npins)
+		       void *data, unsigned int *pins, unsigned int npins)
 {
 	return -ENOTSUPP;
 }
diff --git a/drivers/pinctrl/pinctrl-generic.c b/drivers/pinctrl/pinctrl-generic.c
index e4cd16ce2bda3..a3faad7911cbf 100644
--- a/drivers/pinctrl/pinctrl-generic.c
+++ b/drivers/pinctrl/pinctrl-generic.c
@@ -21,8 +21,7 @@ int pinctrl_generic_to_map(struct pinctrl_dev *pctldev, struct device_node *pare
 			   struct device_node *np, struct pinctrl_map **maps,
 			   unsigned int *num_maps, unsigned int *num_reserved_maps,
 			   const char **group_names, unsigned int ngroups,
-			   const char **functions, unsigned int *pins,
-			   unsigned int npins)
+			   void *data, unsigned int *pins, unsigned int npins)
 {
 	struct device *dev = pctldev->dev;
 	unsigned int num_configs;
@@ -45,7 +44,7 @@ int pinctrl_generic_to_map(struct pinctrl_dev *pctldev, struct device_node *pare
 	if (ret < 0)
 		return ret;
 
-	ret = pinctrl_generic_add_group(pctldev, group_name, pins, npins, functions);
+	ret = pinctrl_generic_add_group(pctldev, group_name, pins, npins, data);
 	if (ret < 0)
 		return dev_err_probe(dev, ret, "failed to add group %s: %d\n",
 				     group_name, ret);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 2/4] pinctrl: add new generic groups/function creation function for pinmux
  2026-05-19  9:37 [PATCH v2 0/4] generic pinmux dt_node_to_map implementation/spacemit driver converted to use it Conor Dooley
  2026-05-19  9:37 ` [PATCH v2 1/4] pinctrl: generic: change signature of pinctrl_generic_to_map() to pass void data Conor Dooley
@ 2026-05-19  9:37 ` Conor Dooley
  2026-05-19  9:37 ` [PATCH v2 3/4] pinctrl: spacemit: delete spacemit_pctrl_check_power() Conor Dooley
  2026-05-19  9:37 ` [PATCH v2 4/4] pinctrl: spacemit: move over to generic pinmux dt_node_to_map implementation Conor Dooley
  3 siblings, 0 replies; 5+ messages in thread
From: Conor Dooley @ 2026-05-19  9:37 UTC (permalink / raw)
  To: Linus Walleij
  Cc: conor, Conor Dooley, Yixun Lan, Troy Mitchell, linux-gpio,
	linux-kernel, linux-riscv, spacemit

From: Conor Dooley <conor.dooley@microchip.com>

Akin to my recently added pinctrl_generic_pins_functions_dt_node_to_map(),
create an analogue that performs the same role of dynamically creating
groups at runtime for controllers using the pinmux property.
The pinmux property is freeform, so this function mandates that the
upper 16 bits contain the pin and the lower 16 bits contains the mux
setting. The group's data pointer is populated with an array of the mux
settings for each pin it contains.

Since the node parsing and subsequent pinctrl core function calls are
practically identical to the pins + functions case, other than which
properties are examined, it makes sense to extract the common code from
pinctrl_generic_pins_function_dt_node_to_map() into a generic function
that takes the case-specific devicetree parsing function as an argument.

Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
 drivers/pinctrl/pinconf.h         |  14 ++++
 drivers/pinctrl/pinctrl-generic.c | 119 ++++++++++++++++++++++++------
 2 files changed, 112 insertions(+), 21 deletions(-)

diff --git a/drivers/pinctrl/pinconf.h b/drivers/pinctrl/pinconf.h
index b2fb757cc6ecb..2e40512fed776 100644
--- a/drivers/pinctrl/pinconf.h
+++ b/drivers/pinctrl/pinconf.h
@@ -173,6 +173,11 @@ int pinctrl_generic_pins_function_dt_node_to_map(struct pinctrl_dev *pctldev,
 						 struct pinctrl_map **maps,
 						 unsigned int *num_maps);
 
+int pinctrl_generic_pinmux_dt_node_to_map(struct pinctrl_dev *pctldev,
+					  struct device_node *np,
+					  struct pinctrl_map **maps,
+					  unsigned int *num_maps);
+
 int pinctrl_generic_to_map(struct pinctrl_dev *pctldev, struct device_node *parent,
 			   struct device_node *np, struct pinctrl_map **maps,
 			   unsigned int *num_maps, unsigned int *num_reserved_maps,
@@ -188,6 +193,15 @@ pinctrl_generic_pins_function_dt_node_to_map(struct pinctrl_dev *pctldev,
 	return -ENOTSUPP;
 }
 
+static inline int
+pinctrl_generic_pinmux_dt_node_to_map(struct pinctrl_dev *pctldev,
+				      struct device_node *np,
+				      struct pinctrl_map **maps,
+				      unsigned int *num_maps)
+{
+	return -ENOTSUPP;
+}
+
 static inline int
 pinctrl_generic_to_map(struct pinctrl_dev *pctldev, struct device_node *parent,
 		       struct device_node *np, struct pinctrl_map **maps,
diff --git a/drivers/pinctrl/pinctrl-generic.c b/drivers/pinctrl/pinctrl-generic.c
index a3faad7911cbf..9759b0186bcc2 100644
--- a/drivers/pinctrl/pinctrl-generic.c
+++ b/drivers/pinctrl/pinctrl-generic.c
@@ -119,17 +119,64 @@ static int pinctrl_generic_pins_function_dt_subnode_to_map(struct pinctrl_dev *p
 				      functions, pins, npins);
 }
 
-/*
- * For platforms that do not define groups or functions in the driver, but
- * instead use the devicetree to describe them. This function will, unlike
- * pinconf_generic_dt_node_to_map() etc which rely on driver defined groups
- * and functions, create them in addition to parsing pinconf properties and
- * adding mappings.
- */
-int pinctrl_generic_pins_function_dt_node_to_map(struct pinctrl_dev *pctldev,
-						 struct device_node *np,
-						 struct pinctrl_map **maps,
-						 unsigned int *num_maps)
+static int pinctrl_generic_pinmux_dt_subnode_to_map(struct pinctrl_dev *pctldev,
+						    struct device_node *parent,
+						    struct device_node *np,
+						    struct pinctrl_map **maps,
+						    unsigned int *num_maps,
+						    unsigned int *num_reserved_maps,
+						    const char **group_names,
+						    unsigned int ngroups)
+{
+	struct device *dev = pctldev->dev;
+	unsigned int *pins, *muxes;
+	int npins, ret;
+
+	npins = of_property_count_u32_elems(np, "pinmux");
+
+	if (npins < 1) {
+		dev_err(dev, "invalid pinctrl group %pOFn.%pOFn %d\n",
+			parent, np, npins);
+		return npins;
+	}
+
+	pins = devm_kcalloc(dev, npins, sizeof(*pins), GFP_KERNEL);
+	if (!pins)
+		return -ENOMEM;
+
+	muxes = devm_kcalloc(dev, npins, sizeof(*muxes), GFP_KERNEL);
+	if (!muxes)
+		return -ENOMEM;
+
+	for (int i = 0; i < npins; i++) {
+		unsigned int pinmux;
+
+		ret = of_property_read_u32_index(np, "pinmux", i, &pinmux);
+		if (ret)
+			return ret;
+
+		pins[i] = pinmux >> 16;
+		muxes[i] = pinmux & GENMASK(15, 0);
+	}
+
+	return pinctrl_generic_to_map(pctldev, parent, np, maps, num_maps,
+				      num_reserved_maps, group_names, ngroups,
+				      muxes, pins, npins);
+}
+
+static int pinctrl_generic_dt_node_to_map(struct pinctrl_dev *pctldev,
+					  struct device_node *np,
+					  struct pinctrl_map **maps,
+					  unsigned int *num_maps,
+					  int (dt_subnode_to_map)(
+						  struct pinctrl_dev *,
+						  struct device_node *,
+						  struct device_node *,
+						  struct pinctrl_map **,
+						  unsigned int *,
+						  unsigned int *,
+						  const char **,
+						  unsigned int))
 {
 	struct device *dev = pctldev->dev;
 	struct device_node *child_np;
@@ -152,11 +199,8 @@ int pinctrl_generic_pins_function_dt_node_to_map(struct pinctrl_dev *pctldev,
 	if (!group_names)
 		return -ENOMEM;
 
-	ret = pinctrl_generic_pins_function_dt_subnode_to_map(pctldev, np, np,
-							      maps, num_maps,
-							      &num_reserved_maps,
-							      group_names,
-							      ngroups);
+	ret = dt_subnode_to_map(pctldev, np, np, maps, num_maps,
+				&num_reserved_maps, group_names, ngroups);
 	if (ret) {
 		pinctrl_utils_free_map(pctldev, *maps, *num_maps);
 		return dev_err_probe(dev, ret, "error figuring out mappings for %s\n", np->name);
@@ -180,11 +224,8 @@ int pinctrl_generic_pins_function_dt_node_to_map(struct pinctrl_dev *pctldev,
 
 	ngroups = 0;
 	for_each_available_child_of_node_scoped(np, child_np) {
-		ret = pinctrl_generic_pins_function_dt_subnode_to_map(pctldev, np, child_np,
-								      maps, num_maps,
-								      &num_reserved_maps,
-								      group_names,
-								      ngroups);
+		ret = dt_subnode_to_map(pctldev, np, child_np, maps, num_maps,
+					&num_reserved_maps, group_names, ngroups);
 		if (ret) {
 			pinctrl_utils_free_map(pctldev, *maps, *num_maps);
 			return dev_err_probe(dev, ret, "error figuring out mappings for %s\n",
@@ -202,4 +243,40 @@ int pinctrl_generic_pins_function_dt_node_to_map(struct pinctrl_dev *pctldev,
 
 	return 0;
 }
+
+/*
+ * For platforms that do not define groups or functions in the driver, but
+ * instead use the devicetree to describe them. This function will, unlike
+ * pinconf_generic_dt_node_to_map() etc which rely on driver defined groups
+ * and functions, create them in addition to parsing pinconf properties and
+ * adding mappings.
+ */
+int pinctrl_generic_pins_function_dt_node_to_map(struct pinctrl_dev *pctldev,
+						 struct device_node *np,
+						 struct pinctrl_map **maps,
+						 unsigned int *num_maps)
+{
+	return pinctrl_generic_dt_node_to_map(pctldev, np, maps, num_maps,
+					      &pinctrl_generic_pins_function_dt_subnode_to_map);
+}
 EXPORT_SYMBOL_GPL(pinctrl_generic_pins_function_dt_node_to_map);
+
+/*
+ * For platforms that do not define groups or functions in the driver, but
+ * instead use the devicetree to describe them. This function will, unlike
+ * pinconf_generic_dt_node_to_map() etc which rely on driver defined groups
+ * and functions, create them in addition to parsing pinconf properties and
+ * adding mappings.
+ *
+ * It assumes that the upper 16 bits of the pinmux items contain the pin
+ * and the lower 16 the mux setting.
+ */
+int pinctrl_generic_pinmux_dt_node_to_map(struct pinctrl_dev *pctldev,
+					  struct device_node *np,
+					  struct pinctrl_map **maps,
+					  unsigned int *num_maps)
+{
+	return pinctrl_generic_dt_node_to_map(pctldev, np, maps, num_maps,
+					      &pinctrl_generic_pinmux_dt_subnode_to_map);
+};
+EXPORT_SYMBOL_GPL(pinctrl_generic_pinmux_dt_node_to_map);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 3/4] pinctrl: spacemit: delete spacemit_pctrl_check_power()
  2026-05-19  9:37 [PATCH v2 0/4] generic pinmux dt_node_to_map implementation/spacemit driver converted to use it Conor Dooley
  2026-05-19  9:37 ` [PATCH v2 1/4] pinctrl: generic: change signature of pinctrl_generic_to_map() to pass void data Conor Dooley
  2026-05-19  9:37 ` [PATCH v2 2/4] pinctrl: add new generic groups/function creation function for pinmux Conor Dooley
@ 2026-05-19  9:37 ` Conor Dooley
  2026-05-19  9:37 ` [PATCH v2 4/4] pinctrl: spacemit: move over to generic pinmux dt_node_to_map implementation Conor Dooley
  3 siblings, 0 replies; 5+ messages in thread
From: Conor Dooley @ 2026-05-19  9:37 UTC (permalink / raw)
  To: Linus Walleij
  Cc: conor, Conor Dooley, Yixun Lan, Troy Mitchell, linux-gpio,
	linux-kernel, linux-riscv, spacemit

From: Conor Dooley <conor.dooley@microchip.com>

As far as I can tell spacemit_pctrl_check_power(), called during the
custom implementation of dt_node_to_map, is redundant because
the driver's implementation generate_config performs the check too.
Removing this would allow the driver to use the newly added common
function pinctrl_generic_pinmux_dt_node_to_map().

Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
 drivers/pinctrl/spacemit/pinctrl-k1.c | 37 ---------------------------
 1 file changed, 37 deletions(-)

diff --git a/drivers/pinctrl/spacemit/pinctrl-k1.c b/drivers/pinctrl/spacemit/pinctrl-k1.c
index b0be62b1c8161..95c891c4c8fb4 100644
--- a/drivers/pinctrl/spacemit/pinctrl-k1.c
+++ b/drivers/pinctrl/spacemit/pinctrl-k1.c
@@ -409,38 +409,6 @@ static inline u32 spacemit_get_drive_strength_mA(enum spacemit_pin_io_type type,
 	}
 }
 
-static int spacemit_pctrl_check_power(struct pinctrl_dev *pctldev,
-				      struct device_node *dn,
-				      struct spacemit_pin_mux_config *pinmuxs,
-				      int num_pins, const char *grpname)
-{
-	struct spacemit_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
-	struct device *dev = pctrl->dev;
-	enum spacemit_pin_io_type type;
-	u32 power = 0, i;
-
-	of_property_read_u32(dn, "power-source", &power);
-
-	for (i = 0; i < num_pins; i++) {
-		type = spacemit_to_pin_io_type(pinmuxs[i].pin);
-
-		if (type != IO_TYPE_EXTERNAL)
-			continue;
-
-		switch (power) {
-		case PIN_POWER_STATE_1V8:
-		case PIN_POWER_STATE_3V3:
-			break;
-		default:
-			dev_err(dev, "group %s has unsupported power\n",
-				grpname);
-			return -ENOTSUPP;
-		}
-	}
-
-	return 0;
-}
-
 static void spacemit_set_io_pwr_domain(struct spacemit_pinctrl *pctrl,
 				      const struct spacemit_pin *spin,
 				      const enum spacemit_pin_io_type type)
@@ -548,11 +516,6 @@ static int spacemit_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
 				return dev_err_probe(dev, -ENODEV, "failed to get pin %d\n", pins[i]);
 		}
 
-		ret = spacemit_pctrl_check_power(pctldev, child, pinmuxs,
-						 npins, grpname);
-		if (ret < 0)
-			return ret;
-
 		map[nmaps].type = PIN_MAP_TYPE_MUX_GROUP;
 		map[nmaps].data.mux.function = np->name;
 		map[nmaps].data.mux.group = grpname;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 4/4] pinctrl: spacemit: move over to generic pinmux dt_node_to_map implementation
  2026-05-19  9:37 [PATCH v2 0/4] generic pinmux dt_node_to_map implementation/spacemit driver converted to use it Conor Dooley
                   ` (2 preceding siblings ...)
  2026-05-19  9:37 ` [PATCH v2 3/4] pinctrl: spacemit: delete spacemit_pctrl_check_power() Conor Dooley
@ 2026-05-19  9:37 ` Conor Dooley
  3 siblings, 0 replies; 5+ messages in thread
From: Conor Dooley @ 2026-05-19  9:37 UTC (permalink / raw)
  To: Linus Walleij
  Cc: conor, Conor Dooley, Yixun Lan, Troy Mitchell, linux-gpio,
	linux-kernel, linux-riscv, spacemit

From: Conor Dooley <conor.dooley@microchip.com>

Replace the custom implementation of dt_node_to_map with
pinctrl_generic_dt_node_to_map() to demonstrate its use.
spacemit_pin_mux_config didn't provide much value in the first place,
because the group contains the information required to look up the
spacemit_pin struct corresponding to a pin, so there's no loss in
functionality as a result of the generic function carrying only the mux
data in the group's data pointer rather than having an array of
spacemit_pin_mux_config structs.

Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
 drivers/pinctrl/spacemit/Kconfig      |   4 +-
 drivers/pinctrl/spacemit/pinctrl-k1.c | 140 ++------------------------
 2 files changed, 12 insertions(+), 132 deletions(-)

diff --git a/drivers/pinctrl/spacemit/Kconfig b/drivers/pinctrl/spacemit/Kconfig
index c021d51033d16..b2365deffe1be 100644
--- a/drivers/pinctrl/spacemit/Kconfig
+++ b/drivers/pinctrl/spacemit/Kconfig
@@ -8,9 +8,7 @@ config PINCTRL_SPACEMIT_K1
 	depends on ARCH_SPACEMIT || COMPILE_TEST
 	depends on OF
 	default ARCH_SPACEMIT
-	select GENERIC_PINCTRL_GROUPS
-	select GENERIC_PINMUX_FUNCTIONS
-	select GENERIC_PINCONF
+	select GENERIC_PINCTRL
 	help
 	  Say Y to select the pinctrl driver for K1/K3 SoC.
 	  This pin controller allows selecting the mux function for
diff --git a/drivers/pinctrl/spacemit/pinctrl-k1.c b/drivers/pinctrl/spacemit/pinctrl-k1.c
index 95c891c4c8fb4..394ef0cd26bcc 100644
--- a/drivers/pinctrl/spacemit/pinctrl-k1.c
+++ b/drivers/pinctrl/spacemit/pinctrl-k1.c
@@ -114,11 +114,6 @@ struct spacemit_pinctrl_data {
 	const struct spacemit_pinctrl_dconf	*dconf;
 };
 
-struct spacemit_pin_mux_config {
-	const struct spacemit_pin	*pin;
-	u32				config;
-};
-
 /* map pin id to pinctrl register offset, refer MFPR definition */
 static unsigned int spacemit_k1_pin_to_offset(unsigned int pin)
 {
@@ -228,16 +223,6 @@ static inline void __iomem *spacemit_pin_to_reg(struct spacemit_pinctrl *pctrl,
 	return pctrl->regs + pctrl->data->pin_to_offset(pin);
 }
 
-static u16 spacemit_dt_get_pin(u32 value)
-{
-	return value >> 16;
-}
-
-static u16 spacemit_dt_get_pin_mux(u32 value)
-{
-	return value & GENMASK(15, 0);
-}
-
 static const struct spacemit_pin *spacemit_get_pin(struct spacemit_pinctrl *pctrl,
 						   unsigned long pin)
 {
@@ -445,121 +430,12 @@ static void spacemit_set_io_pwr_domain(struct spacemit_pinctrl *pctrl,
 	writel_relaxed(val, pctrl->regs + IO_PWR_DOMAIN_OFFSET + offset);
 }
 
-static int spacemit_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
-					 struct device_node *np,
-					 struct pinctrl_map **maps,
-					 unsigned int *num_maps)
-{
-	struct spacemit_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
-	struct device *dev = pctrl->dev;
-	struct device_node *child;
-	struct pinctrl_map *map;
-	const char **grpnames;
-	const char *grpname;
-	int ngroups = 0;
-	int nmaps = 0;
-	int ret;
-
-	for_each_available_child_of_node(np, child)
-		ngroups += 1;
-
-	grpnames = devm_kcalloc(dev, ngroups, sizeof(*grpnames), GFP_KERNEL);
-	if (!grpnames)
-		return -ENOMEM;
-
-	map = kzalloc_objs(*map, ngroups * 2);
-	if (!map)
-		return -ENOMEM;
-
-	ngroups = 0;
-	guard(mutex)(&pctrl->mutex);
-	for_each_available_child_of_node_scoped(np, child) {
-		struct spacemit_pin_mux_config *pinmuxs;
-		unsigned int config, *pins;
-		int i, npins;
-
-		npins = of_property_count_u32_elems(child, "pinmux");
-
-		if (npins < 1) {
-			dev_err(dev, "invalid pinctrl group %pOFn.%pOFn\n",
-				np, child);
-			return -EINVAL;
-		}
-
-		grpname = devm_kasprintf(dev, GFP_KERNEL, "%pOFn.%pOFn",
-					 np, child);
-		if (!grpname)
-			return -ENOMEM;
-
-		grpnames[ngroups++] = grpname;
-
-		pins = devm_kcalloc(dev, npins, sizeof(*pins), GFP_KERNEL);
-		if (!pins)
-			return -ENOMEM;
-
-		pinmuxs = devm_kcalloc(dev, npins, sizeof(*pinmuxs), GFP_KERNEL);
-		if (!pinmuxs)
-			return -ENOMEM;
-
-		for (i = 0; i < npins; i++) {
-			ret = of_property_read_u32_index(child, "pinmux",
-							 i, &config);
-
-			if (ret)
-				return -EINVAL;
-
-			pins[i] = spacemit_dt_get_pin(config);
-			pinmuxs[i].config = config;
-			pinmuxs[i].pin = spacemit_get_pin(pctrl, pins[i]);
-
-			if (!pinmuxs[i].pin)
-				return dev_err_probe(dev, -ENODEV, "failed to get pin %d\n", pins[i]);
-		}
-
-		map[nmaps].type = PIN_MAP_TYPE_MUX_GROUP;
-		map[nmaps].data.mux.function = np->name;
-		map[nmaps].data.mux.group = grpname;
-		nmaps += 1;
-
-		ret = pinctrl_generic_add_group(pctldev, grpname,
-						pins, npins, pinmuxs);
-		if (ret < 0)
-			return dev_err_probe(dev, ret, "failed to add group %s: %d\n", grpname, ret);
-
-		ret = pinconf_generic_parse_dt_config(child, pctldev,
-						      &map[nmaps].data.configs.configs,
-						      &map[nmaps].data.configs.num_configs);
-		if (ret)
-			return dev_err_probe(dev, ret, "failed to parse pin config of group %s\n",
-				grpname);
-
-		if (map[nmaps].data.configs.num_configs == 0)
-			continue;
-
-		map[nmaps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
-		map[nmaps].data.configs.group_or_pin = grpname;
-		nmaps += 1;
-	}
-
-	ret = pinmux_generic_add_function(pctldev, np->name,
-					  grpnames, ngroups, NULL);
-	if (ret < 0) {
-		pinctrl_utils_free_map(pctldev, map, nmaps);
-		return dev_err_probe(dev, ret, "error adding function %s\n", np->name);
-	}
-
-	*maps = map;
-	*num_maps = nmaps;
-
-	return 0;
-}
-
 static const struct pinctrl_ops spacemit_pctrl_ops = {
 	.get_groups_count	= pinctrl_generic_get_group_count,
 	.get_group_name		= pinctrl_generic_get_group_name,
 	.get_group_pins		= pinctrl_generic_get_group_pins,
 	.pin_dbg_show		= spacemit_pctrl_dbg_show,
-	.dt_node_to_map		= spacemit_pctrl_dt_node_to_map,
+	.dt_node_to_map		= pinctrl_generic_pinmux_dt_node_to_map,
 	.dt_free_map		= pinctrl_utils_free_map,
 };
 
@@ -568,8 +444,8 @@ static int spacemit_pmx_set_mux(struct pinctrl_dev *pctldev,
 {
 	struct spacemit_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
 	const struct group_desc *group;
-	const struct spacemit_pin_mux_config *configs;
 	unsigned int i, mux;
+	unsigned int *configs;
 	void __iomem *reg;
 
 	group = pinctrl_generic_get_group(pctldev, gsel);
@@ -579,11 +455,17 @@ static int spacemit_pmx_set_mux(struct pinctrl_dev *pctldev,
 	configs = group->data;
 
 	for (i = 0; i < group->grp.npins; i++) {
-		const struct spacemit_pin *spin = configs[i].pin;
-		u32 value = configs[i].config;
+		const struct spacemit_pin *spin;
+		u32 value = configs[i];
+
+		spin = spacemit_get_pin(pctrl, group->grp.pins[i]);
+		if (!spin) {
+			dev_err(pctrl->dev, "Invalid pin %u\n", group->grp.pins[i]);
+			return -EINVAL;
+		}
 
 		reg = spacemit_pin_to_reg(pctrl, spin->pin);
-		mux = spacemit_dt_get_pin_mux(value);
+		mux = value;
 
 		guard(raw_spinlock_irqsave)(&pctrl->lock);
 		value = readl_relaxed(reg) & ~PAD_MUX;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-05-19  9:37 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-19  9:37 [PATCH v2 0/4] generic pinmux dt_node_to_map implementation/spacemit driver converted to use it Conor Dooley
2026-05-19  9:37 ` [PATCH v2 1/4] pinctrl: generic: change signature of pinctrl_generic_to_map() to pass void data Conor Dooley
2026-05-19  9:37 ` [PATCH v2 2/4] pinctrl: add new generic groups/function creation function for pinmux Conor Dooley
2026-05-19  9:37 ` [PATCH v2 3/4] pinctrl: spacemit: delete spacemit_pctrl_check_power() Conor Dooley
2026-05-19  9:37 ` [PATCH v2 4/4] pinctrl: spacemit: move over to generic pinmux dt_node_to_map implementation Conor Dooley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox