[PATCH v3 7/7] gpio: add pinctrl based generic gpio driver

Dan Carpenter posted 7 patches 3 weeks, 6 days ago
There is a newer version of this series
[PATCH v3 7/7] gpio: add pinctrl based generic gpio driver
Posted by Dan Carpenter 3 weeks, 6 days ago
From: AKASHI Takahiro <takahiro.akashi@linaro.org>

The ARM SCMI pinctrl protocol allows GPIO access.  Instead of creating
a new SCMI gpio driver, this driver is a generic GPIO driver that uses
standard pinctrl interfaces.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
---
 drivers/gpio/Kconfig           |   7 ++
 drivers/gpio/Makefile          |   1 +
 drivers/gpio/gpio-by-pinctrl.c | 124 +++++++++++++++++++++++++++++++++
 3 files changed, 132 insertions(+)
 create mode 100644 drivers/gpio/gpio-by-pinctrl.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index b45fb799e36c..4c8d2589c412 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -246,6 +246,13 @@ config GPIO_BRCMSTB
 	help
 	  Say yes here to enable GPIO support for Broadcom STB (BCM7XXX) SoCs.
 
+config GPIO_BY_PINCTRL
+	tristate "GPIO support based on a pure pin control backend"
+	depends on GPIOLIB
+	help
+	  Select this option to support GPIO devices based solely on pin
+	  control.  This is used to do GPIO over the ARM SCMI protocol.
+
 config GPIO_CADENCE
 	tristate "Cadence GPIO support"
 	depends on OF_GPIO
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index c05f7d795c43..20d4a57afdaa 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_GPIO_BD9571MWV)		+= gpio-bd9571mwv.o
 obj-$(CONFIG_GPIO_BLZP1600)		+= gpio-blzp1600.o
 obj-$(CONFIG_GPIO_BRCMSTB)		+= gpio-brcmstb.o
 obj-$(CONFIG_GPIO_BT8XX)		+= gpio-bt8xx.o
+obj-$(CONFIG_GPIO_BY_PINCTRL)		+= gpio-by-pinctrl.o
 obj-$(CONFIG_GPIO_CADENCE)		+= gpio-cadence.o
 obj-$(CONFIG_GPIO_CGBC)			+= gpio-cgbc.o
 obj-$(CONFIG_GPIO_CLPS711X)		+= gpio-clps711x.o
diff --git a/drivers/gpio/gpio-by-pinctrl.c b/drivers/gpio/gpio-by-pinctrl.c
new file mode 100644
index 000000000000..c1fed14c9d01
--- /dev/null
+++ b/drivers/gpio/gpio-by-pinctrl.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (C) 2023 Linaro Inc.
+//   Author: AKASHI takahiro <takahiro.akashi@linaro.org>
+
+#include <linux/gpio/driver.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include "gpiolib.h"
+
+struct pin_control_gpio_priv {
+	struct gpio_chip chip;
+};
+
+static int pin_control_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
+{
+	unsigned long config;
+	bool in, out;
+	int ret;
+
+	config = PIN_CONFIG_INPUT_ENABLE;
+	ret = pinctrl_gpio_get_config(gc, offset, &config);
+	if (ret)
+		return ret;
+	in = config;
+
+	config = PIN_CONFIG_OUTPUT_ENABLE;
+	ret = pinctrl_gpio_get_config(gc, offset, &config);
+	if (ret)
+		return ret;
+	out = config;
+
+	/* Consistency check - in theory both can be enabled! */
+	if (in && !out)
+		return GPIO_LINE_DIRECTION_IN;
+	if (!in && out)
+		return GPIO_LINE_DIRECTION_OUT;
+
+	return -EINVAL;
+}
+
+static int pin_control_gpio_direction_output(struct gpio_chip *chip,
+					     unsigned int offset, int val)
+{
+	return pinctrl_gpio_direction_output(chip, offset);
+}
+
+static int pin_control_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+	unsigned long config;
+	int ret;
+
+	config = PIN_CONFIG_LEVEL;
+	ret = pinctrl_gpio_get_config(chip, offset, &config);
+	if (ret)
+		return ret;
+
+	return !!config;
+}
+
+static int pin_control_gpio_set(struct gpio_chip *chip, unsigned int offset,
+				 int val)
+{
+	unsigned long config;
+
+	config = PIN_CONF_PACKED(PIN_CONFIG_LEVEL, val);
+	return pinctrl_gpio_set_config(chip, offset, config);
+}
+
+static int pin_control_gpio_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct pin_control_gpio_priv *priv;
+	struct gpio_chip *chip;
+	int ret;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	chip = &priv->chip;
+	chip->label = dev_name(dev);
+	chip->parent = dev;
+	chip->base = -1;
+
+	chip->request = gpiochip_generic_request;
+	chip->free = gpiochip_generic_free;
+	chip->get_direction = pin_control_gpio_get_direction;
+	chip->direction_input = pinctrl_gpio_direction_input;
+	chip->direction_output = pin_control_gpio_direction_output;
+	chip->get = pin_control_gpio_get;
+	chip->set = pin_control_gpio_set;
+	chip->set_config = gpiochip_generic_config;
+
+	ret = devm_gpiochip_add_data(dev, chip, priv);
+	if (ret)
+		return ret;
+
+	platform_set_drvdata(pdev, priv);
+
+	return 0;
+}
+
+static const struct of_device_id pin_control_gpio_match[] = {
+	{ .compatible = "scmi-pinctrl-gpio" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, pin_control_gpio_match);
+
+static struct platform_driver pin_control_gpio_driver = {
+	.probe = pin_control_gpio_probe,
+	.driver = {
+		.name = "pin-control-gpio",
+		.of_match_table = pin_control_gpio_match,
+	},
+};
+module_platform_driver(pin_control_gpio_driver);
+
+MODULE_AUTHOR("AKASHI Takahiro <takahiro.akashi@linaro.org>");
+MODULE_DESCRIPTION("Pinctrl based GPIO driver");
+MODULE_LICENSE("GPL");
-- 
2.51.0
Re: [PATCH v3 7/7] gpio: add pinctrl based generic gpio driver
Posted by Bartosz Golaszewski 3 weeks, 1 day ago
On Wed, 11 Mar 2026 20:39:24 +0100, Dan Carpenter
<dan.carpenter@linaro.org> said:
> From: AKASHI Takahiro <takahiro.akashi@linaro.org>
>
> The ARM SCMI pinctrl protocol allows GPIO access.  Instead of creating
> a new SCMI gpio driver, this driver is a generic GPIO driver that uses
> standard pinctrl interfaces.
>
> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
> ---

That is actually pretty neat.

Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Re: [PATCH v3 7/7] gpio: add pinctrl based generic gpio driver
Posted by Linus Walleij 3 weeks, 5 days ago
On Wed, Mar 11, 2026 at 8:39 PM Dan Carpenter <dan.carpenter@linaro.org> wrote:

> From: AKASHI Takahiro <takahiro.akashi@linaro.org>
>
> The ARM SCMI pinctrl protocol allows GPIO access.  Instead of creating
> a new SCMI gpio driver, this driver is a generic GPIO driver that uses
> standard pinctrl interfaces.
>
> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>

To me this is as pure as a GPIO-on-pinctrl can get.
Reviewed-by: Linus Walleij <linusw@kernel.org>

Yours,
Linus Walleij
Re: [PATCH v3 7/7] gpio: add pinctrl based generic gpio driver
Posted by Andy Shevchenko 3 weeks, 5 days ago
On Wed, Mar 11, 2026 at 10:39:24PM +0300, Dan Carpenter wrote:

> The ARM SCMI pinctrl protocol allows GPIO access.  Instead of creating
> a new SCMI gpio driver, this driver is a generic GPIO driver that uses
> standard pinctrl interfaces.

Similar wondering here... Can't this code be integrated with one of
the existing generic things, like gpio-aggregator?

I really don't want to see yet another generic code in this folder.

-- 
With Best Regards,
Andy Shevchenko
Re: [PATCH v3 7/7] gpio: add pinctrl based generic gpio driver
Posted by Linus Walleij 3 weeks, 5 days ago
On Wed, Mar 11, 2026 at 9:34 PM Andy Shevchenko
<andriy.shevchenko@intel.com> wrote:
> On Wed, Mar 11, 2026 at 10:39:24PM +0300, Dan Carpenter wrote:
>
> > The ARM SCMI pinctrl protocol allows GPIO access.  Instead of creating
> > a new SCMI gpio driver, this driver is a generic GPIO driver that uses
> > standard pinctrl interfaces.
>
> Similar wondering here... Can't this code be integrated with one of
> the existing generic things, like gpio-aggregator?

The aggregator is very different, it takes existing GPIOs and
creates a new GPIOchip from them.

What this does is essentially take the gpio-ranges, find the
backing pins on the pin controller, and creates a GPIOchip
from them.

I don't see anything that can be shared by the other generic
business sadly, but I think maybe another back-end using just
pin control can re-use this. In this case it is SCMI but any other
firmware API just exposing pin control and no explicit GPIO
could use this. (Not that I can think of any.)

Yours,
Linus Walleij
Re: [PATCH v3 7/7] gpio: add pinctrl based generic gpio driver
Posted by Andy Shevchenko 3 weeks, 5 days ago
On Wed, Mar 11, 2026 at 11:00:02PM +0100, Linus Walleij wrote:
> On Wed, Mar 11, 2026 at 9:34 PM Andy Shevchenko
> <andriy.shevchenko@intel.com> wrote:
> > On Wed, Mar 11, 2026 at 10:39:24PM +0300, Dan Carpenter wrote:
> >
> > > The ARM SCMI pinctrl protocol allows GPIO access.  Instead of creating
> > > a new SCMI gpio driver, this driver is a generic GPIO driver that uses
> > > standard pinctrl interfaces.
> >
> > Similar wondering here... Can't this code be integrated with one of
> > the existing generic things, like gpio-aggregator?
> 
> The aggregator is very different, it takes existing GPIOs and
> creates a new GPIOchip from them.
> 
> What this does is essentially take the gpio-ranges, find the
> backing pins on the pin controller, and creates a GPIOchip
> from them.

Thanks for elaboration! But why is it done this way? It doesn't sound
like a usual (generic) problem to solve.

> I don't see anything that can be shared by the other generic
> business sadly, but I think maybe another back-end using just
> pin control can re-use this. In this case it is SCMI but any other
> firmware API just exposing pin control and no explicit GPIO
> could use this. (Not that I can think of any.)

-- 
With Best Regards,
Andy Shevchenko


Re: [PATCH v3 7/7] gpio: add pinctrl based generic gpio driver
Posted by Linus Walleij 3 weeks ago
On Thu, Mar 12, 2026 at 11:41 AM Andy Shevchenko
<andriy.shevchenko@intel.com> wrote:
> On Wed, Mar 11, 2026 at 11:00:02PM +0100, Linus Walleij wrote:

> > What this does is essentially take the gpio-ranges, find the
> > backing pins on the pin controller, and creates a GPIOchip
> > from them.
>
> Thanks for elaboration! But why is it done this way? It doesn't sound
> like a usual (generic) problem to solve.

The experts can confirm, but I think this was done to simplify
the SCMI firmware, both the specification and the implementation.

It was identified that it was necessary to have a pin control
SCMI specification and implementation, but no separate GPIO
specification and implementation was defined, leading to just
one spec, and one single firmware service to
implement that will support both pin control and GPIO.

These days, if we were re-specifying ACPI we could do the
same there, but alas it already has legacy GPIO-only interfaces.
SCMI has the upside of being able to start from scratch
and upend a few traditions.

Yours,
Linus Walleij