From: Bartosz Golaszewski <brgl@bgdev.pl>
To: Linus Walleij <linus.walleij@linaro.org>,
Bjorn Andersson <andersson@kernel.org>,
Konrad Dybcio <konradybcio@kernel.org>,
Alexey Klimov <alexey.klimov@linaro.org>,
Lorenzo Bianconi <lorenzo@kernel.org>,
Sean Wang <sean.wang@kernel.org>,
Matthias Brugger <matthias.bgg@gmail.com>,
AngeloGioacchino Del Regno
<angelogioacchino.delregno@collabora.com>,
Paul Cercueil <paul@crapouillou.net>,
Kees Cook <kees@kernel.org>, Andy Shevchenko <andy@kernel.org>,
Andrew Morton <akpm@linux-foundation.org>,
David Hildenbrand <david@redhat.com>,
Lorenzo Stoakes <lorenzo.stoakes@oracle.com>,
"Liam R. Howlett" <Liam.Howlett@oracle.com>,
Vlastimil Babka <vbabka@suse.cz>,
Mike Rapoport <rppt@kernel.org>,
Suren Baghdasaryan <surenb@google.com>,
Michal Hocko <mhocko@suse.com>,
Dong Aisheng <aisheng.dong@nxp.com>,
Fabio Estevam <festevam@gmail.com>,
Shawn Guo <shawnguo@kernel.org>, Jacky Bai <ping.bai@nxp.com>,
Pengutronix Kernel Team <kernel@pengutronix.de>,
NXP S32 Linux Team <s32@nxp.com>,
Sascha Hauer <s.hauer@pengutronix.de>,
Tony Lindgren <tony@atomide.com>,
Haojian Zhuang <haojian.zhuang@linaro.org>,
Geert Uytterhoeven <geert+renesas@glider.be>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
"Rafael J. Wysocki" <rafael@kernel.org>,
Danilo Krummrich <dakr@kernel.org>
Cc: linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arm-msm@vger.kernel.org,
linux-mediatek@lists.infradead.org,
linux-arm-kernel@lists.infradead.org,
linux-mips@vger.kernel.org, linux-hardening@vger.kernel.org,
linux-mm@kvack.org, imx@lists.linux.dev,
linux-omap@vger.kernel.org, linux-renesas-soc@vger.kernel.org,
Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Subject: [PATCH v5 12/15] pinctrl: allow to mark pin functions as requestable GPIOs
Date: Fri, 15 Aug 2025 11:09:14 +0200 [thread overview]
Message-ID: <20250815-pinctrl-gpio-pinfuncs-v5-12-955de9fd91db@linaro.org> (raw)
In-Reply-To: <20250815-pinctrl-gpio-pinfuncs-v5-0-955de9fd91db@linaro.org>
From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
The name of the pin function has no real meaning to pinctrl core and is
there only for human readability of device properties. Some pins are
muxed as GPIOs but for "strict" pinmuxers it's impossible to request
them as GPIOs if they're bound to a devide - even if their function name
explicitly says "gpio". Add a new field to struct pinfunction that
allows to pass additional flags to pinctrl core. While we could go with
a boolean "is_gpio" field, a flags field is more future-proof.
If the PINFUNCTION_FLAG_GPIO is set for a given function, the pin muxed
to it can be requested as GPIO even on strict pin controllers. Add a new
callback to struct pinmux_ops - function_is_gpio() - that allows pinmux
core to inspect a function and see if it's a GPIO one. Provide a generic
implementation of this callback.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
drivers/pinctrl/pinmux.c | 39 +++++++++++++++++++++++++++++++++++++--
drivers/pinctrl/pinmux.h | 3 +++
include/linux/pinctrl/pinctrl.h | 14 ++++++++++++++
include/linux/pinctrl/pinmux.h | 2 ++
4 files changed, 56 insertions(+), 2 deletions(-)
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
index 6f5e3ede972bbfa78e279790df359632e2d63485..730108467bcc226622185b53a1590c683ff19afc 100644
--- a/drivers/pinctrl/pinmux.c
+++ b/drivers/pinctrl/pinmux.c
@@ -89,13 +89,20 @@ bool pinmux_can_be_used_for_gpio(struct pinctrl_dev *pctldev, unsigned int pin)
{
struct pin_desc *desc = pin_desc_get(pctldev, pin);
const struct pinmux_ops *ops = pctldev->desc->pmxops;
+ const struct pinctrl_setting_mux *mux_setting;
+ bool func_is_gpio = false;
/* Can't inspect pin, assume it can be used */
if (!desc || !ops)
return true;
+ mux_setting = desc->mux_setting;
+
guard(mutex)(&desc->mux_lock);
- if (ops->strict && desc->mux_usecount)
+ if (mux_setting && ops->function_is_gpio)
+ func_is_gpio = ops->function_is_gpio(pctldev, mux_setting->func);
+
+ if (ops->strict && desc->mux_usecount && !func_is_gpio)
return false;
return !(ops->strict && !!desc->gpio_owner);
@@ -116,7 +123,9 @@ static int pin_request(struct pinctrl_dev *pctldev,
{
struct pin_desc *desc;
const struct pinmux_ops *ops = pctldev->desc->pmxops;
+ const struct pinctrl_setting_mux *mux_setting;
int status = -EINVAL;
+ bool func_is_gpio = false;
desc = pin_desc_get(pctldev, pin);
if (desc == NULL) {
@@ -126,11 +135,16 @@ static int pin_request(struct pinctrl_dev *pctldev,
goto out;
}
+ mux_setting = desc->mux_setting;
+
dev_dbg(pctldev->dev, "request pin %d (%s) for %s\n",
pin, desc->name, owner);
scoped_guard(mutex, &desc->mux_lock) {
- if ((!gpio_range || ops->strict) &&
+ if (ops->function_is_gpio && mux_setting)
+ func_is_gpio = ops->function_is_gpio(pctldev,
+ mux_setting->func);
+ if ((!gpio_range || ops->strict) && !func_is_gpio &&
desc->mux_usecount && strcmp(desc->mux_owner, owner)) {
dev_err(pctldev->dev,
"pin %s already requested by %s; cannot claim for %s\n",
@@ -861,6 +875,27 @@ pinmux_generic_get_function(struct pinctrl_dev *pctldev, unsigned int selector)
}
EXPORT_SYMBOL_GPL(pinmux_generic_get_function);
+/**
+ * pinmux_generic_function_is_gpio() - returns true if given function is a GPIO
+ * @pctldev: pin controller device
+ * @selector: function number
+ *
+ * Returns:
+ * True if given function is a GPIO, false otherwise.
+ */
+bool pinmux_generic_function_is_gpio(struct pinctrl_dev *pctldev,
+ unsigned int selector)
+{
+ struct function_desc *function;
+
+ function = radix_tree_lookup(&pctldev->pin_function_tree, selector);
+ if (!function)
+ return false;
+
+ return function->func->flags & PINFUNCTION_FLAG_GPIO;
+}
+EXPORT_SYMBOL_GPL(pinmux_generic_function_is_gpio);
+
/**
* pinmux_generic_add_function() - adds a function group
* @pctldev: pin controller device
diff --git a/drivers/pinctrl/pinmux.h b/drivers/pinctrl/pinmux.h
index 653684290666d78fd725febb5f8bc987b66a1afb..4e826c1a5246cf8b1ac814c8c0df24c4e036edd2 100644
--- a/drivers/pinctrl/pinmux.h
+++ b/drivers/pinctrl/pinmux.h
@@ -169,6 +169,9 @@ int pinmux_generic_remove_function(struct pinctrl_dev *pctldev,
void pinmux_generic_free_functions(struct pinctrl_dev *pctldev);
+bool pinmux_generic_function_is_gpio(struct pinctrl_dev *pctldev,
+ unsigned int selector);
+
#else
static inline void pinmux_generic_free_functions(struct pinctrl_dev *pctldev)
diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h
index d138e18156452e008f24ca06358fcab45135632f..1a8084e2940537f8f0862761d3e47c56c8783193 100644
--- a/include/linux/pinctrl/pinctrl.h
+++ b/include/linux/pinctrl/pinctrl.h
@@ -11,6 +11,7 @@
#ifndef __LINUX_PINCTRL_PINCTRL_H
#define __LINUX_PINCTRL_PINCTRL_H
+#include <linux/bits.h>
#include <linux/types.h>
struct device;
@@ -206,16 +207,20 @@ extern int pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
const char *pin_group, const unsigned int **pins,
unsigned int *num_pins);
+#define PINFUNCTION_FLAG_GPIO BIT(0)
+
/**
* struct pinfunction - Description about a function
* @name: Name of the function
* @groups: An array of groups for this function
* @ngroups: Number of groups in @groups
+ * @flags: Additional pin function flags
*/
struct pinfunction {
const char *name;
const char * const *groups;
size_t ngroups;
+ unsigned long flags;
};
/* Convenience macro to define a single named pinfunction */
@@ -226,6 +231,15 @@ struct pinfunction {
.ngroups = (_ngroups), \
}
+/* Same as PINCTRL_PINFUNCTION() but for the GPIO category of functions */
+#define PINCTRL_GPIO_PINFUNCTION(_name, _groups, _ngroups) \
+(struct pinfunction) { \
+ .name = (_name), \
+ .groups = (_groups), \
+ .ngroups = (_ngroups), \
+ .flags = PINFUNCTION_FLAG_GPIO, \
+ }
+
#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_PINCTRL)
extern struct pinctrl_dev *of_pinctrl_get(struct device_node *np);
#else
diff --git a/include/linux/pinctrl/pinmux.h b/include/linux/pinctrl/pinmux.h
index d6f7b58d6ad0cce421aad80463529c9ccc65d68e..6db6c3e1ccc2249d4b4204e6fc19bf7b4397cc81 100644
--- a/include/linux/pinctrl/pinmux.h
+++ b/include/linux/pinctrl/pinmux.h
@@ -66,6 +66,8 @@ struct pinmux_ops {
unsigned int selector,
const char * const **groups,
unsigned int *num_groups);
+ bool (*function_is_gpio) (struct pinctrl_dev *pctldev,
+ unsigned int selector);
int (*set_mux) (struct pinctrl_dev *pctldev, unsigned int func_selector,
unsigned int group_selector);
int (*gpio_request_enable) (struct pinctrl_dev *pctldev,
--
2.48.1
next prev parent reply other threads:[~2025-08-15 9:09 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-15 9:09 [PATCH v5 00/15] pinctrl: introduce the concept of a GPIO pin function category Bartosz Golaszewski
2025-08-15 9:09 ` [PATCH v5 01/15] devres: provide devm_kmemdup_const() Bartosz Golaszewski
2025-08-15 9:09 ` [PATCH v5 02/15] pinctrl: ingenic: use struct pinfunction instead of struct function_desc Bartosz Golaszewski
2025-08-15 9:09 ` [PATCH v5 03/15] pinctrl: airoha: replace struct function_desc with struct pinfunction Bartosz Golaszewski
2025-08-15 9:09 ` [PATCH v5 04/15] pinctrl: mediatek: mt7988: use PINCTRL_PIN_FUNCTION() Bartosz Golaszewski
2025-08-15 9:09 ` [PATCH v5 05/15] pinctrl: mediatek: moore: replace struct function_desc with struct pinfunction Bartosz Golaszewski
2025-08-15 9:09 ` [PATCH v5 06/15] pinctrl: imx: don't access the pin function radix tree directly Bartosz Golaszewski
2025-08-15 9:09 ` [PATCH v5 07/15] pinctrl: keembay: release allocated memory in detach path Bartosz Golaszewski
2025-08-15 9:09 ` [PATCH v5 08/15] pinctrl: keembay: use a dedicated structure for the pinfunction description Bartosz Golaszewski
2025-08-15 9:09 ` [PATCH v5 09/15] pinctrl: constify pinmux_generic_get_function() Bartosz Golaszewski
2025-08-15 9:09 ` [PATCH v5 10/15] pinctrl: make struct pinfunction a pointer in struct function_desc Bartosz Golaszewski
2025-08-15 9:09 ` [PATCH v5 11/15] pinctrl: qcom: use generic pin function helpers Bartosz Golaszewski
2025-08-15 9:09 ` Bartosz Golaszewski [this message]
2025-08-15 9:09 ` [PATCH v5 13/15] pinctrl: qcom: add infrastructure for marking pin functions as GPIOs Bartosz Golaszewski
2025-08-15 9:09 ` [PATCH v5 14/15] pinctrl: qcom: mark the `gpio` and `egpio` pins function as non-strict functions Bartosz Golaszewski
2025-08-15 9:09 ` [PATCH v5 15/15] pinctrl: qcom: make the pinmuxing strict Bartosz Golaszewski
2025-08-19 9:43 ` Neil Armstrong
2025-08-19 13:01 ` [PATCH v5 00/15] pinctrl: introduce the concept of a GPIO pin function category Linus Walleij
2025-08-19 18:31 ` Andy Shevchenko
2025-08-20 7:12 ` Linus Walleij
2025-08-20 9:59 ` Andy Shevchenko
2025-08-20 18:41 ` Mark Brown
2025-08-26 18:19 ` Bartosz Golaszewski
2025-08-27 10:21 ` Mark Brown
2025-08-27 16:46 ` Bartosz Golaszewski
2025-08-28 8:51 ` Mark Brown
2025-08-28 13:36 ` Bartosz Golaszewski
2025-08-28 13:58 ` Mark Brown
2025-08-28 15:05 ` Bartosz Golaszewski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250815-pinctrl-gpio-pinfuncs-v5-12-955de9fd91db@linaro.org \
--to=brgl@bgdev.pl \
--cc=Liam.Howlett@oracle.com \
--cc=aisheng.dong@nxp.com \
--cc=akpm@linux-foundation.org \
--cc=alexey.klimov@linaro.org \
--cc=andersson@kernel.org \
--cc=andy@kernel.org \
--cc=angelogioacchino.delregno@collabora.com \
--cc=bartosz.golaszewski@linaro.org \
--cc=dakr@kernel.org \
--cc=david@redhat.com \
--cc=festevam@gmail.com \
--cc=geert+renesas@glider.be \
--cc=gregkh@linuxfoundation.org \
--cc=haojian.zhuang@linaro.org \
--cc=imx@lists.linux.dev \
--cc=kees@kernel.org \
--cc=kernel@pengutronix.de \
--cc=konradybcio@kernel.org \
--cc=linus.walleij@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mediatek@lists.infradead.org \
--cc=linux-mips@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-omap@vger.kernel.org \
--cc=linux-renesas-soc@vger.kernel.org \
--cc=lorenzo.stoakes@oracle.com \
--cc=lorenzo@kernel.org \
--cc=matthias.bgg@gmail.com \
--cc=mhocko@suse.com \
--cc=paul@crapouillou.net \
--cc=ping.bai@nxp.com \
--cc=rafael@kernel.org \
--cc=rppt@kernel.org \
--cc=s.hauer@pengutronix.de \
--cc=s32@nxp.com \
--cc=sean.wang@kernel.org \
--cc=shawnguo@kernel.org \
--cc=surenb@google.com \
--cc=tony@atomide.com \
--cc=vbabka@suse.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).