{"id":2233368,"url":"http://patchwork.ozlabs.org/api/1.1/patches/2233368/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-gpio/patch/20260506-matted-prominent-6352c26a65a6@spud/","project":{"id":42,"url":"http://patchwork.ozlabs.org/api/1.1/projects/42/?format=json","name":"Linux GPIO development","link_name":"linux-gpio","list_id":"linux-gpio.vger.kernel.org","list_email":"linux-gpio@vger.kernel.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20260506-matted-prominent-6352c26a65a6@spud>","date":"2026-05-06T09:57:40","name":"[RFC,v1,2/4] pinctrl: add new generic groups/function creation function for pinmux","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"43fe97030ba2df2c9898558a4e4e9805a338c509","submitter":{"id":84372,"url":"http://patchwork.ozlabs.org/api/1.1/people/84372/?format=json","name":"Conor Dooley","email":"conor@kernel.org"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linux-gpio/patch/20260506-matted-prominent-6352c26a65a6@spud/mbox/","series":[{"id":502949,"url":"http://patchwork.ozlabs.org/api/1.1/series/502949/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-gpio/list/?series=502949","date":"2026-05-06T09:57:38","name":"generic pinmux dt_node_to_map implementation","version":1,"mbox":"http://patchwork.ozlabs.org/series/502949/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2233368/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2233368/checks/","tags":{},"headers":{"Return-Path":"\n <linux-gpio+bounces-36276-incoming=patchwork.ozlabs.org@vger.kernel.org>","X-Original-To":["incoming@patchwork.ozlabs.org","linux-gpio@vger.kernel.org"],"Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256\n header.s=k20201202 header.b=Cw6BHAn2;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c04:e001:36c::12fc:5321; helo=tor.lore.kernel.org;\n envelope-from=linux-gpio+bounces-36276-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=\"Cw6BHAn2\"","smtp.subspace.kernel.org;\n arc=none smtp.client-ip=10.30.226.201"],"Received":["from tor.lore.kernel.org (tor.lore.kernel.org\n [IPv6:2600:3c04:e001:36c::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g9WPc5kBLz1yJq\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 06 May 2026 20:11:32 +1000 (AEST)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby tor.lore.kernel.org (Postfix) with ESMTP id 7F27530D0739\n\tfor <incoming@patchwork.ozlabs.org>; Wed,  6 May 2026 09:59:37 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 2B3C63F7895;\n\tWed,  6 May 2026 09:58:16 +0000 (UTC)","from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org\n [10.30.226.201])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id 9678231D375;\n\tWed,  6 May 2026 09:58:13 +0000 (UTC)","by smtp.kernel.org (Postfix) with ESMTPSA id 05979C2BCC4;\n\tWed,  6 May 2026 09:58:10 +0000 (UTC)"],"ARC-Seal":"i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1778061493; cv=none;\n b=eVeDEiHJb6MWmwd4krPURWHvOrVFX6sNv3FVBPBLBj5mWrs3/BnQY30ByfqXdfkF04PVNpt8qPUg6fXUpB7zhQjn72Cowr0dz4Ze0W2iJSe2DAlYSYZSwGz/9ENHsNIrO+YH/Fo3I4IGGl6J2yAcNClyF/GBOjNHcOEIGWi7Caw=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1778061493; c=relaxed/simple;\n\tbh=TVBXqFY3A1biRCKkk5PCThVDRBq0+hrygrveT6A+Tc8=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=j9Fegx7jmyEfecKkhZeDEVW9fZhOgo7I4SC4XDym3L/qkP5+0ZXmgdz7NC6E8Su2oifCcvVsZI2ZBoZ072vJpksves9M3aGwHj11s3OCaMyemfla3CWUkD0oAW5vG8gKmcFD3nwiAY/OFf4iGkU+1DK0dop/J4naa8N3Rt/umL8=","ARC-Authentication-Results":"i=1; smtp.subspace.kernel.org;\n dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=Cw6BHAn2; arc=none smtp.client-ip=10.30.226.201","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org;\n\ts=k20201202; t=1778061492;\n\tbh=TVBXqFY3A1biRCKkk5PCThVDRBq0+hrygrveT6A+Tc8=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=Cw6BHAn2KmedwdcWVbFXyvNcRPQEIRONAyjCBbZ+epA5/Sa7T/Ud1NCNhWle/9UHx\n\t jfpgSRECQquqSvlIA4GW+QdRpHLHLSGyC2K+fgaLI+ANLYDYltVxEC+bHRKVYsFMuw\n\t 3q+lH+i4aruIE3OIvHDNUs5eFcL3WctXZd6MKbJ6iOfMnDnc8dpSBldIUByhKmz2Wp\n\t hQydrlJrIHnKguASji1EU9DHOgI/CxHSCEl09PrTWXFe1yUpvjpA9AuMGnJ98aH0Mk\n\t 1AKWaJNIs8AEkeqfU/S7B/opRpgv/aGx1fuRnbLihUaiKtKBJutorUf8jBZjnrjdfc\n\t AjxRXWJA2Eypg==","From":"Conor Dooley <conor@kernel.org>","To":"Linus Walleij <linusw@kernel.org>","Cc":"conor@kernel.org,\n\tConor Dooley <conor.dooley@microchip.com>,\n\tYixun Lan <dlan@kernel.org>,\n\tTroy Mitchell <troy.mitchell@linux.spacemit.com>,\n\tlinux-gpio@vger.kernel.org,\n\tlinux-kernel@vger.kernel.org,\n\tlinux-riscv@lists.infradead.org,\n\tspacemit@lists.linux.dev","Subject":"[RFC v1 2/4] pinctrl: add new generic groups/function creation\n function for pinmux","Date":"Wed,  6 May 2026 10:57:40 +0100","Message-ID":"<20260506-matted-prominent-6352c26a65a6@spud>","X-Mailer":"git-send-email 2.53.0","In-Reply-To":"<20260506-energize-dramatize-051909e54256@spud>","References":"<20260506-energize-dramatize-051909e54256@spud>","Precedence":"bulk","X-Mailing-List":"linux-gpio@vger.kernel.org","List-Id":"<linux-gpio.vger.kernel.org>","List-Subscribe":"<mailto:linux-gpio+subscribe@vger.kernel.org>","List-Unsubscribe":"<mailto:linux-gpio+unsubscribe@vger.kernel.org>","MIME-Version":"1.0","X-Developer-Signature":"v=1; a=openpgp-sha256; l=5876;\n i=conor.dooley@microchip.com; h=from:subject:message-id;\n bh=IAVHCqBTU/I3FABmI0dhZe5pmDWDVP85YHHq0Hd5uPY=;\n b=owGbwMvMwCVWscWwfUFT0iXG02pJDJm/BSazdPHMnDO9p/DhFo6FG3kW7/d03HzCUur7NR85/\n 50eJ/Vfd5SyMIhxMciKKbIk3u5rkVr/x2WHc89bmDmsTCBDGLg4BWAiZ6UY/pk5BU3UcHJ8XKv+\n +Od6bc1NDYpNV/Mre58flTEp7gvfc5vhr7TJSa7G52+PuUxQ5Yh+tEjmpcqam1mKrSvzuyx+RFb\n +5AMA","X-Developer-Key":"i=conor.dooley@microchip.com; a=openpgp;\n fpr=F9ECA03CF54F12CD01F1655722E2C55B37CF380C","Content-Transfer-Encoding":"8bit"},"content":"From: Conor Dooley <conor.dooley@microchip.com>\n\nSigned-off-by: Conor Dooley <conor.dooley@microchip.com>\n---\n drivers/pinctrl/pinconf.h         |  14 ++++\n drivers/pinctrl/pinctrl-generic.c | 134 ++++++++++++++++++++++++++++++\n 2 files changed, 148 insertions(+)","diff":"diff --git a/drivers/pinctrl/pinconf.h b/drivers/pinctrl/pinconf.h\nindex 5d99fef27657f..30c42d81e8829 100644\n--- a/drivers/pinctrl/pinconf.h\n+++ b/drivers/pinctrl/pinconf.h\n@@ -167,6 +167,11 @@ int pinctrl_generic_pins_function_dt_node_to_map(struct pinctrl_dev *pctldev,\n \t\t\t\t\t\t struct pinctrl_map **maps,\n \t\t\t\t\t\t unsigned int *num_maps);\n \n+int pinctrl_generic_pinmux_dt_node_to_map(struct pinctrl_dev *pctldev,\n+\t\t\t\t\t  struct device_node *np,\n+\t\t\t\t\t  struct pinctrl_map **maps,\n+\t\t\t\t\t  unsigned int *num_maps);\n+\n int pinctrl_generic_to_map(struct pinctrl_dev *pctldev, struct device_node *parent,\n \t\t\t   struct device_node *np, struct pinctrl_map **maps,\n \t\t\t   unsigned int *num_maps, unsigned int *num_reserved_maps,\n@@ -182,6 +187,15 @@ pinctrl_generic_pins_function_dt_node_to_map(struct pinctrl_dev *pctldev,\n \treturn -ENOTSUPP;\n }\n \n+static inline int\n+pinctrl_generic_pinmux_dt_node_to_map(struct pinctrl_dev *pctldev,\n+\t\t\t\t      struct device_node *np,\n+\t\t\t\t      struct pinctrl_map **maps,\n+\t\t\t\t      unsigned int *num_maps)\n+{\n+\treturn -ENOTSUPP;\n+}\n+\n static inline int\n pinctrl_generic_to_map(struct pinctrl_dev *pctldev, struct device_node *parent,\n \t\t       struct device_node *np, struct pinctrl_map **maps,\ndiff --git a/drivers/pinctrl/pinctrl-generic.c b/drivers/pinctrl/pinctrl-generic.c\nindex 6a13fd4eea65b..69df211f6b964 100644\n--- a/drivers/pinctrl/pinctrl-generic.c\n+++ b/drivers/pinctrl/pinctrl-generic.c\n@@ -202,3 +202,137 @@ int pinctrl_generic_pins_function_dt_node_to_map(struct pinctrl_dev *pctldev,\n \treturn 0;\n }\n EXPORT_SYMBOL_GPL(pinctrl_generic_pins_function_dt_node_to_map);\n+\n+\n+static int pinctrl_generic_pinmux_dt_subnode_to_map(struct pinctrl_dev *pctldev,\n+\t\t\t\t\t\t    struct device_node *parent,\n+\t\t\t\t\t\t    struct device_node *np,\n+\t\t\t\t\t\t    struct pinctrl_map **maps,\n+\t\t\t\t\t\t    unsigned int *num_maps,\n+\t\t\t\t\t\t    unsigned int *num_reserved_maps,\n+\t\t\t\t\t\t    const char **group_names,\n+\t\t\t\t\t\t    unsigned int ngroups)\n+{\n+\tstruct device *dev = pctldev->dev;\n+\tunsigned int *pins, *muxes;\n+\tint npins, ret;\n+\n+\tnpins = of_property_count_u32_elems(np, \"pinmux\");\n+\n+\tif (npins < 1) {\n+\t\tdev_err(dev, \"invalid pinctrl group %pOFn.%pOFn %d\\n\",\n+\t\t\tparent, np, npins);\n+\t\treturn npins;\n+\t}\n+\n+\tpins = devm_kcalloc(dev, npins, sizeof(*pins), GFP_KERNEL);\n+\tif (!pins)\n+\t\treturn -ENOMEM;\n+\n+\tmuxes = devm_kcalloc(dev, npins, sizeof(*muxes), GFP_KERNEL);\n+\tif (!muxes)\n+\t\treturn -ENOMEM;\n+\n+\tfor (int i = 0; i < npins; i++) {\n+\t\tunsigned int pinmux;\n+\n+\t\tret = of_property_read_u32_index(np, \"pinmux\", i, &pinmux);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\n+\t\tpins[i] = pinmux >> 16;\n+\t\tmuxes[i] = pinmux & GENMASK(15, 0);\n+\t}\n+\n+\treturn pinctrl_generic_to_map(pctldev, parent, np, maps, num_maps,\n+\t\t\t\t      num_reserved_maps, group_names, ngroups,\n+\t\t\t\t      muxes, pins, npins);\n+}\n+\n+/*\n+ * For platforms that do not define groups or functions in the driver, but\n+ * instead use the devicetree to describe them. This function will, unlike\n+ * pinconf_generic_dt_node_to_map() etc which rely on driver defined groups\n+ * and functions, create them in addition to parsing pinconf properties and\n+ * adding mappings.\n+ *\n+ * It assumes that the upper 16 bits of the pinmux items contain the pin\n+ * and the lower 16 the mux setting.\n+ */\n+int pinctrl_generic_pinmux_dt_node_to_map(struct pinctrl_dev *pctldev,\n+\t\t\t\t\t  struct device_node *np,\n+\t\t\t\t\t  struct pinctrl_map **maps,\n+\t\t\t\t\t  unsigned int *num_maps)\n+{\n+\tstruct device *dev = pctldev->dev;\n+\tstruct device_node *child_np;\n+\tconst char **group_names;\n+\tunsigned int num_reserved_maps = 0;\n+\tint ngroups = 0;\n+\tint ret;\n+\n+\t*maps = NULL;\n+\t*num_maps = 0;\n+\n+\t/*\n+\t * Check if this is actually the pinmux node, or a parent containing\n+\t * multiple pinmux nodes.\n+\t */\n+\tif (!of_property_present(np, \"pinmux\"))\n+\t\tgoto parent;\n+\n+\tgroup_names = devm_kcalloc(dev, 1, sizeof(*group_names), GFP_KERNEL);\n+\tif (!group_names)\n+\t\treturn -ENOMEM;\n+\n+\tret = pinctrl_generic_pinmux_dt_subnode_to_map(pctldev, np, np,\n+\t\t\t\t\t\t       maps, num_maps,\n+\t\t\t\t\t\t       &num_reserved_maps,\n+\t\t\t\t\t\t       group_names,\n+\t\t\t\t\t\t       ngroups);\n+\tif (ret) {\n+\t\tpinctrl_utils_free_map(pctldev, *maps, *num_maps);\n+\t\treturn dev_err_probe(dev, ret, \"error figuring out mappings for %s\\n\", np->name);\n+\t}\n+\n+\tret = pinmux_generic_add_function(pctldev, np->name, group_names, 1, NULL);\n+\tif (ret < 0) {\n+\t\tpinctrl_utils_free_map(pctldev, *maps, *num_maps);\n+\t\treturn dev_err_probe(dev, ret, \"error adding function %s\\n\", np->name);\n+\t}\n+\n+\treturn 0;\n+\n+parent:\n+\tfor_each_available_child_of_node(np, child_np)\n+\t\tngroups += 1;\n+\n+\tgroup_names = devm_kcalloc(dev, ngroups, sizeof(*group_names), GFP_KERNEL);\n+\tif (!group_names)\n+\t\treturn -ENOMEM;\n+\n+\tngroups = 0;\n+\tfor_each_available_child_of_node_scoped(np, child_np) {\n+\t\tret = pinctrl_generic_pinmux_dt_subnode_to_map(pctldev, np, child_np,\n+\t\t\t\t\t\t\t       maps, num_maps,\n+\t\t\t\t\t\t\t       &num_reserved_maps,\n+\t\t\t\t\t\t\t       group_names,\n+\t\t\t\t\t\t\t       ngroups);\n+\t\tif (ret) {\n+\t\t\tpinctrl_utils_free_map(pctldev, *maps, *num_maps);\n+\t\t\treturn dev_err_probe(dev, ret, \"error figuring out mappings for %s\\n\",\n+\t\t\t\t\t     np->name);\n+\t\t}\n+\n+\t\tngroups++;\n+\t}\n+\n+\tret = pinmux_generic_add_function(pctldev, np->name, group_names, ngroups, NULL);\n+\tif (ret < 0) {\n+\t\tpinctrl_utils_free_map(pctldev, *maps, *num_maps);\n+\t\treturn dev_err_probe(dev, ret, \"error adding function %s\\n\", np->name);\n+\t}\n+\n+\treturn 0;\n+}\n+EXPORT_SYMBOL_GPL(pinctrl_generic_pinmux_dt_node_to_map);\n","prefixes":["RFC","v1","2/4"]}