[PATCH v3 0/3] Remove <linux/of_gpio.h>

Jialu Xu posted 3 patches 1 month ago
There is a newer version of this series
MAINTAINERS                      |  1 -
drivers/gpio/TODO                | 28 ----------------------------
drivers/gpio/gpiolib-of.c        | 31 ++++---------------------------
drivers/nfc/nfcmrvl/main.c       | 46 +++++++++++++++-------------------------------
drivers/nfc/nfcmrvl/nfcmrvl.h    |  4 +++-
drivers/nfc/nfcmrvl/uart.c       | 23 ++++++++++++++++-------
drivers/nfc/nfcmrvl/usb.c        |  2 +-
drivers/nfc/s3fwrn5/i2c.c        | 55 ++++++++-----------------------------------------------
drivers/nfc/s3fwrn5/phy_common.c | 11 +++++------
drivers/nfc/s3fwrn5/phy_common.h |  5 +++--
drivers/nfc/s3fwrn5/uart.c       | 45 ++++++++++++---------------------------------
include/linux/of_gpio.h          | 38 --------------------------------------
12 files changed, 67 insertions(+), 222 deletions(-)
[PATCH v3 0/3] Remove <linux/of_gpio.h>
Posted by Jialu Xu 1 month ago
Convert the last three NFC consumers of <linux/of_gpio.h> to the
GPIO descriptor API, then remove the deprecated header entirely.

Changes in v3:
- Expand commit messages with more detail. (Linus Walleij)
- Add missing Signed-off-by. (Linus Walleij)
- Remove include/linux/of_gpio.h entry from MAINTAINERS. (Linus Walleij)

Changes in v2:
- Add rename quirks in gpiolib-of.c for s3fwrn5 legacy DT properties
  (s3fwrn5,en-gpios -> en, s3fwrn5,fw-gpios -> wake) to preserve
  backward compatibility with old device trees. (Linus Walleij)

[PATCH v3 1/3] nfc: s3fwrn5: convert to gpio descriptors
[PATCH v3 2/3] nfc: nfcmrvl: convert to gpio descriptors
[PATCH v3 3/3] gpio: remove of_get_named_gpio() and <linux/of_gpio.h>

 MAINTAINERS                      |  1 -
 drivers/gpio/TODO                | 28 ----------------------------
 drivers/gpio/gpiolib-of.c        | 31 ++++---------------------------
 drivers/nfc/nfcmrvl/main.c       | 46 +++++++++++++++-------------------------------
 drivers/nfc/nfcmrvl/nfcmrvl.h    |  4 +++-
 drivers/nfc/nfcmrvl/uart.c       | 23 ++++++++++++++++-------
 drivers/nfc/nfcmrvl/usb.c        |  2 +-
 drivers/nfc/s3fwrn5/i2c.c        | 55 ++++++++-----------------------------------------------
 drivers/nfc/s3fwrn5/phy_common.c | 11 +++++------
 drivers/nfc/s3fwrn5/phy_common.h |  5 +++--
 drivers/nfc/s3fwrn5/uart.c       | 45 ++++++++++++---------------------------------
 include/linux/of_gpio.h          | 38 --------------------------------------
 12 files changed, 67 insertions(+), 222 deletions(-)
[PATCH v4 0/3] Remove <linux/of_gpio.h>
Posted by Jialu Xu 1 month ago
Convert the last three NFC consumers of <linux/of_gpio.h> to the
GPIO descriptor API, then remove the deprecated header entirely.

Changes in v4:
- Fix uninitialized reset_gpio in I2C/SPI paths by initializing it
  to NULL in nfcmrvl_parse_dt(). (Jakub Kicinski)
- Fix GPIO polarity for nfcmrvl: use GPIOD_OUT_HIGH and invert
  gpiod_set_value() arguments to match active-low reset line
  documented in marvell,nci.yaml. (Jakub Kicinski)
- Fix continuation line alignment in s3fwrn5. (Jakub Kicinski)

Changes in v3:
- Expand commit messages with more detail. (Linus Walleij)
- Add missing Signed-off-by. (Linus Walleij)
- Remove include/linux/of_gpio.h entry from MAINTAINERS. (Linus Walleij)

Changes in v2:
- Add rename quirks in gpiolib-of.c for s3fwrn5 legacy DT properties
  (s3fwrn5,en-gpios -> en, s3fwrn5,fw-gpios -> wake) to preserve
  backward compatibility with old device trees. (Linus Walleij)

[PATCH v4 1/3] nfc: s3fwrn5: convert to gpio descriptors
[PATCH v4 2/3] nfc: nfcmrvl: convert to gpio descriptors
[PATCH v4 3/3] gpio: remove of_get_named_gpio() and <linux/of_gpio.h>

 MAINTAINERS                      |  1 -
 drivers/gpio/TODO                | 28 ----------------------------
 drivers/gpio/gpiolib-of.c        | 31 ++++---------------------------
 drivers/nfc/nfcmrvl/main.c       | 47 ++++++++++++++++-------------------------------
 drivers/nfc/nfcmrvl/nfcmrvl.h    |  4 +++-
 drivers/nfc/nfcmrvl/uart.c       | 23 ++++++++++++++++-------
 drivers/nfc/nfcmrvl/usb.c        |  2 +-
 drivers/nfc/s3fwrn5/i2c.c        | 54 +++++++-----------------------------------------------
 drivers/nfc/s3fwrn5/phy_common.c | 11 +++++------
 drivers/nfc/s3fwrn5/phy_common.h |  5 +++--
 drivers/nfc/s3fwrn5/uart.c       | 43 ++++++++++---------------------------------
 include/linux/of_gpio.h          | 38 --------------------------------------
 12 files changed, 65 insertions(+), 222 deletions(-)
Re: [PATCH v4 0/3] Remove <linux/of_gpio.h>
Posted by Bartosz Golaszewski 1 month ago
On Sat, 07 Mar 2026 11:00:56 +0800, Jialu Xu wrote:
> Convert the last three NFC consumers of <linux/of_gpio.h> to the
> GPIO descriptor API, then remove the deprecated header entirely.
> 
> Changes in v4:
> - Fix uninitialized reset_gpio in I2C/SPI paths by initializing it
>   to NULL in nfcmrvl_parse_dt(). (Jakub Kicinski)
> - Fix GPIO polarity for nfcmrvl: use GPIOD_OUT_HIGH and invert
>   gpiod_set_value() arguments to match active-low reset line
>   documented in marvell,nci.yaml. (Jakub Kicinski)
> - Fix continuation line alignment in s3fwrn5. (Jakub Kicinski)
> 
> [...]

Applied, thanks!

[1/3] nfc: s3fwrn5: convert to gpio descriptors
      https://git.kernel.org/brgl/c/b544927d75574330b0a8a33c113556b67df56f39
[2/3] nfc: nfcmrvl: convert to gpio descriptors
      https://git.kernel.org/brgl/c/253350dbf3e7fbd136905c98bd9f800fddb4fead
[3/3] gpio: remove of_get_named_gpio() and <linux/of_gpio.h>
      https://git.kernel.org/brgl/c/b6420bd5aa0c374331bad6c0fa2eb5f0f87cf5a0

Best regards,
-- 
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Re: [PATCH v4 0/3] Remove <linux/of_gpio.h>
Posted by Linus Walleij 1 month ago
On Tue, Mar 10, 2026 at 10:10 AM Bartosz Golaszewski
<bartosz.golaszewski@oss.qualcomm.com> wrote:
> On Sat, 07 Mar 2026 11:00:56 +0800, Jialu Xu wrote:
> > Convert the last three NFC consumers of <linux/of_gpio.h> to the
> > GPIO descriptor API, then remove the deprecated header entirely.
> >
> > Changes in v4:
> > - Fix uninitialized reset_gpio in I2C/SPI paths by initializing it
> >   to NULL in nfcmrvl_parse_dt(). (Jakub Kicinski)
> > - Fix GPIO polarity for nfcmrvl: use GPIOD_OUT_HIGH and invert
> >   gpiod_set_value() arguments to match active-low reset line
> >   documented in marvell,nci.yaml. (Jakub Kicinski)
> > - Fix continuation line alignment in s3fwrn5. (Jakub Kicinski)
> >
> > [...]
>
> Applied, thanks!
>
> [1/3] nfc: s3fwrn5: convert to gpio descriptors
>       https://git.kernel.org/brgl/c/b544927d75574330b0a8a33c113556b67df56f39
> [2/3] nfc: nfcmrvl: convert to gpio descriptors
>       https://git.kernel.org/brgl/c/253350dbf3e7fbd136905c98bd9f800fddb4fead
> [3/3] gpio: remove of_get_named_gpio() and <linux/of_gpio.h>
>       https://git.kernel.org/brgl/c/b6420bd5aa0c374331bad6c0fa2eb5f0f87cf5a0

Did you put that on an immutable branch based on v7.0-rc1 so that
Jakub can pull it in?

Yours,
Linus Walleij
Re: [PATCH v4 0/3] Remove <linux/of_gpio.h>
Posted by Linus Walleij 1 month ago
On Tue, Mar 10, 2026 at 12:38 PM Linus Walleij <linusw@kernel.org> wrote:

> Did you put that on an immutable branch based on v7.0-rc1 so that
> Jakub can pull it in?

Ah there is a separate mail about that, thanks.
Sorry for my ignorance.

Yours,
Linus Walleij
[PATCH v4 1/3] nfc: s3fwrn5: convert to gpio descriptors
Posted by Jialu Xu 1 month ago
Replace the legacy of_get_named_gpio() / gpio_request_one() /
gpio_set_value() API with the descriptor-based devm_gpiod_get() /
gpiod_set_value() API from <linux/gpio/consumer.h>, removing the
dependency on <linux/of_gpio.h>.

This removes the s3fwrn5_i2c_parse_dt() and s3fwrn82_uart_parse_dt()
functions since devm_gpiod_get() handles both DT lookup and resource
management. The gpio_en and gpio_fw_wake fields in struct phy_common
are changed from int to struct gpio_desc *.

Add rename quirks in gpiolib-of.c for the deprecated "s3fwrn5,en-gpios"
and "s3fwrn5,fw-gpios" properties to maintain backward compatibility
with old device trees.

Signed-off-by: Jialu Xu <xujialu@vimux.org>
Reviewed-by: Linus Walleij <linusw@kernel.org>
---
 drivers/gpio/gpiolib-of.c        |  4 +++
 drivers/nfc/s3fwrn5/i2c.c        | 54 +++++---------------------------
 drivers/nfc/s3fwrn5/phy_common.c | 11 +++----
 drivers/nfc/s3fwrn5/phy_common.h |  5 +--
 drivers/nfc/s3fwrn5/uart.c       | 43 ++++++-------------------
 5 files changed, 29 insertions(+), 88 deletions(-)

diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index ef1ac68b94b78..3bdd9af674474 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -542,6 +542,10 @@ static struct gpio_desc *of_find_gpio_rename(struct device_node *np,
 		{ "reset",	"reset-n-io",	"marvell,nfc-uart" },
 		{ "reset",	"reset-n-io",	"mrvl,nfc-uart" },
 #endif
+#if IS_ENABLED(CONFIG_NFC_S3FWRN5_I2C)
+		{ "en",		"s3fwrn5,en-gpios",	"samsung,s3fwrn5-i2c" },
+		{ "wake",	"s3fwrn5,fw-gpios",	"samsung,s3fwrn5-i2c" },
+#endif
 #if IS_ENABLED(CONFIG_PCI_LANTIQ)
 		/* MIPS Lantiq PCI */
 		{ "reset",	"gpio-reset",	"lantiq,pci-xway" },
diff --git a/drivers/nfc/s3fwrn5/i2c.c b/drivers/nfc/s3fwrn5/i2c.c
index 110d086cfe5ba..91b8d1445efd4 100644
--- a/drivers/nfc/s3fwrn5/i2c.c
+++ b/drivers/nfc/s3fwrn5/i2c.c
@@ -8,10 +8,8 @@
 
 #include <linux/clk.h>
 #include <linux/i2c.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/delay.h>
-#include <linux/of_gpio.h>
-#include <linux/of_irq.h>
 #include <linux/module.h>
 
 #include <net/nfc/nfc.h>
@@ -146,37 +144,6 @@ static irqreturn_t s3fwrn5_i2c_irq_thread_fn(int irq, void *phy_id)
 	return IRQ_HANDLED;
 }
 
-static int s3fwrn5_i2c_parse_dt(struct i2c_client *client)
-{
-	struct s3fwrn5_i2c_phy *phy = i2c_get_clientdata(client);
-	struct device_node *np = client->dev.of_node;
-
-	if (!np)
-		return -ENODEV;
-
-	phy->common.gpio_en = of_get_named_gpio(np, "en-gpios", 0);
-	if (!gpio_is_valid(phy->common.gpio_en)) {
-		/* Support also deprecated property */
-		phy->common.gpio_en = of_get_named_gpio(np,
-							"s3fwrn5,en-gpios",
-							0);
-		if (!gpio_is_valid(phy->common.gpio_en))
-			return -ENODEV;
-	}
-
-	phy->common.gpio_fw_wake = of_get_named_gpio(np, "wake-gpios", 0);
-	if (!gpio_is_valid(phy->common.gpio_fw_wake)) {
-		/* Support also deprecated property */
-		phy->common.gpio_fw_wake = of_get_named_gpio(np,
-							     "s3fwrn5,fw-gpios",
-							     0);
-		if (!gpio_is_valid(phy->common.gpio_fw_wake))
-			return -ENODEV;
-	}
-
-	return 0;
-}
-
 static int s3fwrn5_i2c_probe(struct i2c_client *client)
 {
 	struct s3fwrn5_i2c_phy *phy;
@@ -193,20 +160,13 @@ static int s3fwrn5_i2c_probe(struct i2c_client *client)
 	phy->i2c_dev = client;
 	i2c_set_clientdata(client, phy);
 
-	ret = s3fwrn5_i2c_parse_dt(client);
-	if (ret < 0)
-		return ret;
-
-	ret = devm_gpio_request_one(&phy->i2c_dev->dev, phy->common.gpio_en,
-				    GPIOF_OUT_INIT_HIGH, "s3fwrn5_en");
-	if (ret < 0)
-		return ret;
+	phy->common.gpio_en = devm_gpiod_get(&client->dev, "en", GPIOD_OUT_HIGH);
+	if (IS_ERR(phy->common.gpio_en))
+		return PTR_ERR(phy->common.gpio_en);
 
-	ret = devm_gpio_request_one(&phy->i2c_dev->dev,
-				    phy->common.gpio_fw_wake,
-				    GPIOF_OUT_INIT_LOW, "s3fwrn5_fw_wake");
-	if (ret < 0)
-		return ret;
+	phy->common.gpio_fw_wake = devm_gpiod_get(&client->dev, "wake", GPIOD_OUT_LOW);
+	if (IS_ERR(phy->common.gpio_fw_wake))
+		return PTR_ERR(phy->common.gpio_fw_wake);
 
 	/*
 	 * S3FWRN5 depends on a clock input ("XI" pin) to function properly.
diff --git a/drivers/nfc/s3fwrn5/phy_common.c b/drivers/nfc/s3fwrn5/phy_common.c
index deb2c039f0fd6..39a60e34136c5 100644
--- a/drivers/nfc/s3fwrn5/phy_common.c
+++ b/drivers/nfc/s3fwrn5/phy_common.c
@@ -8,7 +8,6 @@
  * Bongsu Jeon <bongsu.jeon@samsung.com>
  */
 
-#include <linux/gpio.h>
 #include <linux/delay.h>
 #include <linux/module.h>
 
@@ -19,7 +18,7 @@ void s3fwrn5_phy_set_wake(void *phy_id, bool wake)
 	struct phy_common *phy = phy_id;
 
 	mutex_lock(&phy->mutex);
-	gpio_set_value(phy->gpio_fw_wake, wake);
+	gpiod_set_value(phy->gpio_fw_wake, wake);
 	if (wake)
 		msleep(S3FWRN5_EN_WAIT_TIME);
 	mutex_unlock(&phy->mutex);
@@ -33,14 +32,14 @@ bool s3fwrn5_phy_power_ctrl(struct phy_common *phy, enum s3fwrn5_mode mode)
 
 	phy->mode = mode;
 
-	gpio_set_value(phy->gpio_en, 1);
-	gpio_set_value(phy->gpio_fw_wake, 0);
+	gpiod_set_value(phy->gpio_en, 1);
+	gpiod_set_value(phy->gpio_fw_wake, 0);
 	if (mode == S3FWRN5_MODE_FW)
-		gpio_set_value(phy->gpio_fw_wake, 1);
+		gpiod_set_value(phy->gpio_fw_wake, 1);
 
 	if (mode != S3FWRN5_MODE_COLD) {
 		msleep(S3FWRN5_EN_WAIT_TIME);
-		gpio_set_value(phy->gpio_en, 0);
+		gpiod_set_value(phy->gpio_en, 0);
 		msleep(S3FWRN5_EN_WAIT_TIME);
 	}
 
diff --git a/drivers/nfc/s3fwrn5/phy_common.h b/drivers/nfc/s3fwrn5/phy_common.h
index 9cef25436bf90..871bec53dd0a9 100644
--- a/drivers/nfc/s3fwrn5/phy_common.h
+++ b/drivers/nfc/s3fwrn5/phy_common.h
@@ -12,6 +12,7 @@
 #define __NFC_S3FWRN5_PHY_COMMON_H
 
 #include <linux/mutex.h>
+#include <linux/gpio/consumer.h>
 #include <net/nfc/nci_core.h>
 
 #include "s3fwrn5.h"
@@ -21,8 +22,8 @@
 struct phy_common {
 	struct nci_dev *ndev;
 
-	int gpio_en;
-	int gpio_fw_wake;
+	struct gpio_desc *gpio_en;
+	struct gpio_desc *gpio_fw_wake;
 
 	struct mutex mutex;
 
diff --git a/drivers/nfc/s3fwrn5/uart.c b/drivers/nfc/s3fwrn5/uart.c
index 9c09c10c2a464..ccfcee06ee774 100644
--- a/drivers/nfc/s3fwrn5/uart.c
+++ b/drivers/nfc/s3fwrn5/uart.c
@@ -10,13 +10,12 @@
 
 #include <linux/device.h>
 #include <linux/kernel.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/nfc.h>
 #include <linux/netdevice.h>
-#include <linux/of.h>
 #include <linux/serdev.h>
-#include <linux/gpio.h>
-#include <linux/of_gpio.h>
+#include <linux/gpio/consumer.h>
 
 #include "phy_common.h"
 
@@ -88,25 +87,6 @@ static const struct of_device_id s3fwrn82_uart_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, s3fwrn82_uart_of_match);
 
-static int s3fwrn82_uart_parse_dt(struct serdev_device *serdev)
-{
-	struct s3fwrn82_uart_phy *phy = serdev_device_get_drvdata(serdev);
-	struct device_node *np = serdev->dev.of_node;
-
-	if (!np)
-		return -ENODEV;
-
-	phy->common.gpio_en = of_get_named_gpio(np, "en-gpios", 0);
-	if (!gpio_is_valid(phy->common.gpio_en))
-		return -ENODEV;
-
-	phy->common.gpio_fw_wake = of_get_named_gpio(np, "wake-gpios", 0);
-	if (!gpio_is_valid(phy->common.gpio_fw_wake))
-		return -ENODEV;
-
-	return 0;
-}
-
 static int s3fwrn82_uart_probe(struct serdev_device *serdev)
 {
 	struct s3fwrn82_uart_phy *phy;
@@ -140,20 +120,17 @@ static int s3fwrn82_uart_probe(struct serdev_device *serdev)
 
 	serdev_device_set_flow_control(serdev, false);
 
-	ret = s3fwrn82_uart_parse_dt(serdev);
-	if (ret < 0)
-		goto err_serdev;
-
-	ret = devm_gpio_request_one(&phy->ser_dev->dev, phy->common.gpio_en,
-				    GPIOF_OUT_INIT_HIGH, "s3fwrn82_en");
-	if (ret < 0)
+	phy->common.gpio_en = devm_gpiod_get(&serdev->dev, "en", GPIOD_OUT_HIGH);
+	if (IS_ERR(phy->common.gpio_en)) {
+		ret = PTR_ERR(phy->common.gpio_en);
 		goto err_serdev;
+	}
 
-	ret = devm_gpio_request_one(&phy->ser_dev->dev,
-				    phy->common.gpio_fw_wake,
-				    GPIOF_OUT_INIT_LOW, "s3fwrn82_fw_wake");
-	if (ret < 0)
+	phy->common.gpio_fw_wake = devm_gpiod_get(&serdev->dev, "wake", GPIOD_OUT_LOW);
+	if (IS_ERR(phy->common.gpio_fw_wake)) {
+		ret = PTR_ERR(phy->common.gpio_fw_wake);
 		goto err_serdev;
+	}
 
 	ret = s3fwrn5_probe(&phy->common.ndev, phy, &phy->ser_dev->dev,
 			    &uart_phy_ops);
-- 
2.47.3
[PATCH v4 2/3] nfc: nfcmrvl: convert to gpio descriptors
Posted by Jialu Xu 1 month ago
Replace the legacy of_get_named_gpio() / gpio_request_one() /
gpio_set_value() API with the descriptor-based devm_gpiod_get_optional() /
gpiod_set_value() API from <linux/gpio/consumer.h>, removing the
dependency on <linux/of_gpio.h>.

The "reset-n-io" property rename quirk already exists in gpiolib-of.c
(added in commit 9c2cc7171e08), so no additional quirk is needed.

Signed-off-by: Jialu Xu <xujialu@vimux.org>
Reviewed-by: Linus Walleij <linusw@kernel.org>
---
 drivers/nfc/nfcmrvl/main.c    | 47 ++++++++++++-----------------------
 drivers/nfc/nfcmrvl/nfcmrvl.h |  4 ++-
 drivers/nfc/nfcmrvl/uart.c    | 23 +++++++++++------
 drivers/nfc/nfcmrvl/usb.c     |  2 +-
 4 files changed, 36 insertions(+), 40 deletions(-)

diff --git a/drivers/nfc/nfcmrvl/main.c b/drivers/nfc/nfcmrvl/main.c
index c51d22e4579c1..6efa832191172 100644
--- a/drivers/nfc/nfcmrvl/main.c
+++ b/drivers/nfc/nfcmrvl/main.c
@@ -6,9 +6,9 @@
  */
 
 #include <linux/module.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/delay.h>
-#include <linux/of_gpio.h>
+#include <linux/of.h>
 #include <linux/nfc.h>
 #include <net/nfc/nci.h>
 #include <net/nfc/nci_core.h>
@@ -112,13 +112,12 @@ struct nfcmrvl_private *nfcmrvl_nci_register_dev(enum nfcmrvl_phy phy,
 
 	memcpy(&priv->config, pdata, sizeof(*pdata));
 
-	if (gpio_is_valid(priv->config.reset_n_io)) {
-		rc = gpio_request_one(priv->config.reset_n_io,
-				      GPIOF_OUT_INIT_LOW,
-				      "nfcmrvl_reset_n");
-		if (rc < 0) {
-			priv->config.reset_n_io = -EINVAL;
-			nfc_err(dev, "failed to request reset_n io\n");
+	if (!priv->config.reset_gpio) {
+		priv->config.reset_gpio =
+			devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
+		if (IS_ERR(priv->config.reset_gpio)) {
+			priv->config.reset_gpio = NULL;
+			nfc_err(dev, "failed to get reset gpio\n");
 		}
 	}
 
@@ -144,7 +143,7 @@ struct nfcmrvl_private *nfcmrvl_nci_register_dev(enum nfcmrvl_phy phy,
 	if (!priv->ndev) {
 		nfc_err(dev, "nci_allocate_device failed\n");
 		rc = -ENOMEM;
-		goto error_free_gpio;
+		goto error_free;
 	}
 
 	rc = nfcmrvl_fw_dnld_init(priv);
@@ -171,9 +170,7 @@ struct nfcmrvl_private *nfcmrvl_nci_register_dev(enum nfcmrvl_phy phy,
 	nfcmrvl_fw_dnld_deinit(priv);
 error_free_dev:
 	nci_free_device(priv->ndev);
-error_free_gpio:
-	if (gpio_is_valid(priv->config.reset_n_io))
-		gpio_free(priv->config.reset_n_io);
+error_free:
 	kfree(priv);
 	return ERR_PTR(rc);
 }
@@ -189,9 +186,6 @@ void nfcmrvl_nci_unregister_dev(struct nfcmrvl_private *priv)
 
 	nfcmrvl_fw_dnld_deinit(priv);
 
-	if (gpio_is_valid(priv->config.reset_n_io))
-		gpio_free(priv->config.reset_n_io);
-
 	nci_free_device(ndev);
 	kfree(priv);
 }
@@ -233,34 +227,25 @@ void nfcmrvl_chip_reset(struct nfcmrvl_private *priv)
 	/* Reset possible fault of previous session */
 	clear_bit(NFCMRVL_PHY_ERROR, &priv->flags);
 
-	if (gpio_is_valid(priv->config.reset_n_io)) {
+	if (priv->config.reset_gpio) {
 		nfc_info(priv->dev, "reset the chip\n");
-		gpio_set_value(priv->config.reset_n_io, 0);
+		gpiod_set_value(priv->config.reset_gpio, 1);
 		usleep_range(5000, 10000);
-		gpio_set_value(priv->config.reset_n_io, 1);
+		gpiod_set_value(priv->config.reset_gpio, 0);
 	} else
 		nfc_info(priv->dev, "no reset available on this interface\n");
 }
 
 void nfcmrvl_chip_halt(struct nfcmrvl_private *priv)
 {
-	if (gpio_is_valid(priv->config.reset_n_io))
-		gpio_set_value(priv->config.reset_n_io, 0);
+	if (priv->config.reset_gpio)
+		gpiod_set_value(priv->config.reset_gpio, 1);
 }
 
 int nfcmrvl_parse_dt(struct device_node *node,
 		     struct nfcmrvl_platform_data *pdata)
 {
-	int reset_n_io;
-
-	reset_n_io = of_get_named_gpio(node, "reset-n-io", 0);
-	if (reset_n_io < 0) {
-		pr_info("no reset-n-io config\n");
-	} else if (!gpio_is_valid(reset_n_io)) {
-		pr_err("invalid reset-n-io GPIO\n");
-		return reset_n_io;
-	}
-	pdata->reset_n_io = reset_n_io;
+	pdata->reset_gpio = NULL;
 	pdata->hci_muxed = of_property_read_bool(node, "hci-muxed");
 
 	return 0;
diff --git a/drivers/nfc/nfcmrvl/nfcmrvl.h b/drivers/nfc/nfcmrvl/nfcmrvl.h
index f61a99e553db0..62fa77d587b2b 100644
--- a/drivers/nfc/nfcmrvl/nfcmrvl.h
+++ b/drivers/nfc/nfcmrvl/nfcmrvl.h
@@ -10,6 +10,8 @@
 
 #include "fw_dnld.h"
 
+struct gpio_desc;
+
 /* Define private flags: */
 #define NFCMRVL_NCI_RUNNING			1
 #define NFCMRVL_PHY_ERROR			2
@@ -54,7 +56,7 @@ struct nfcmrvl_platform_data {
 	 */
 
 	/* GPIO that is wired to RESET_N signal */
-	int reset_n_io;
+	struct gpio_desc *reset_gpio;
 	/* Tell if transport is muxed in HCI one */
 	bool hci_muxed;
 
diff --git a/drivers/nfc/nfcmrvl/uart.c b/drivers/nfc/nfcmrvl/uart.c
index 2037cd6d4f4f4..9aedd168759c7 100644
--- a/drivers/nfc/nfcmrvl/uart.c
+++ b/drivers/nfc/nfcmrvl/uart.c
@@ -8,6 +8,7 @@
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/err.h>
+#include <linux/gpio/consumer.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/printk.h>
@@ -20,7 +21,6 @@
 static unsigned int hci_muxed;
 static unsigned int flow_control;
 static unsigned int break_control;
-static int reset_n_io = -EINVAL;
 
 /*
  * NFCMRVL NCI OPS
@@ -62,9 +62,11 @@ static const struct nfcmrvl_if_ops uart_ops = {
 };
 
 static int nfcmrvl_uart_parse_dt(struct device_node *node,
-				 struct nfcmrvl_platform_data *pdata)
+				 struct nfcmrvl_platform_data *pdata,
+				 struct device *dev)
 {
 	struct device_node *matched_node;
+	struct gpio_desc *reset_gpio;
 	int ret;
 
 	matched_node = of_get_compatible_child(node, "marvell,nfc-uart");
@@ -84,6 +86,16 @@ static int nfcmrvl_uart_parse_dt(struct device_node *node,
 	pdata->flow_control = of_property_read_bool(matched_node, "flow-control");
 	pdata->break_control = of_property_read_bool(matched_node, "break-control");
 
+	reset_gpio = devm_fwnode_gpiod_get_optional(dev,
+						    of_fwnode_handle(matched_node),
+						    "reset", GPIOD_OUT_HIGH,
+						    "nfcmrvl_reset_n");
+	if (IS_ERR(reset_gpio)) {
+		of_node_put(matched_node);
+		return PTR_ERR(reset_gpio);
+	}
+	pdata->reset_gpio = reset_gpio;
+
 	of_node_put(matched_node);
 
 	return 0;
@@ -107,13 +119,13 @@ static int nfcmrvl_nci_uart_open(struct nci_uart *nu)
 	 */
 
 	if (dev && dev->parent && dev->parent->of_node)
-		if (nfcmrvl_uart_parse_dt(dev->parent->of_node, &config) == 0)
+		if (nfcmrvl_uart_parse_dt(dev->parent->of_node, &config, dev) == 0)
 			pdata = &config;
 
 	if (!pdata) {
 		pr_info("No platform data / DT -> fallback to module params\n");
 		config.hci_muxed = hci_muxed;
-		config.reset_n_io = reset_n_io;
+		config.reset_gpio = NULL;
 		config.flow_control = flow_control;
 		config.break_control = break_control;
 		pdata = &config;
@@ -201,6 +213,3 @@ MODULE_PARM_DESC(break_control, "Tell if UART driver must drive break signal.");
 
 module_param(hci_muxed, uint, 0);
 MODULE_PARM_DESC(hci_muxed, "Tell if transport is muxed in HCI one.");
-
-module_param(reset_n_io, int, 0);
-MODULE_PARM_DESC(reset_n_io, "GPIO that is wired to RESET_N signal.");
diff --git a/drivers/nfc/nfcmrvl/usb.c b/drivers/nfc/nfcmrvl/usb.c
index ea73094530968..ac62358445bf8 100644
--- a/drivers/nfc/nfcmrvl/usb.c
+++ b/drivers/nfc/nfcmrvl/usb.c
@@ -294,7 +294,7 @@ static int nfcmrvl_probe(struct usb_interface *intf,
 
 	/* No configuration for USB */
 	memset(&config, 0, sizeof(config));
-	config.reset_n_io = -EINVAL;
+	config.reset_gpio = NULL;
 
 	nfc_info(&udev->dev, "intf %p id %p\n", intf, id);
 
-- 
2.47.3
[PATCH v4 3/3] gpio: remove of_get_named_gpio() and <linux/of_gpio.h>
Posted by Jialu Xu 1 month ago
All in-tree consumers have been converted to the descriptor-based API.
Remove the deprecated of_get_named_gpio() helper, delete the
<linux/of_gpio.h> header, and drop the corresponding entry from
MAINTAINERS.

Also remove the completed TODO item for this cleanup.

Signed-off-by: Jialu Xu <xujialu@vimux.org>
Reviewed-by: Linus Walleij <linusw@kernel.org>
---
 MAINTAINERS               |  1 -
 drivers/gpio/TODO         | 28 ----------------------------
 drivers/gpio/gpiolib-of.c | 27 ---------------------------
 include/linux/of_gpio.h   | 38 --------------------------------------
 4 files changed, 94 deletions(-)
 delete mode 100644 include/linux/of_gpio.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 61bf550fd37c2..8152fa2158295 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10958,7 +10958,6 @@ F:	drivers/gpio/
 F:	include/dt-bindings/gpio/
 F:	include/linux/gpio.h
 F:	include/linux/gpio/
-F:	include/linux/of_gpio.h
 K:	(devm_)?gpio_(request|free|direction|get|set)
 K:	GPIOD_FLAGS_BIT_NONEXCLUSIVE
 K:	devm_gpiod_unhinge
diff --git a/drivers/gpio/TODO b/drivers/gpio/TODO
index 5acaeab029ec6..7ce80fde1f17e 100644
--- a/drivers/gpio/TODO
+++ b/drivers/gpio/TODO
@@ -58,34 +58,6 @@ Work items:
 
 -------------------------------------------------------------------------------
 
-Get rid of <linux/of_gpio.h>
-
-This header and helpers appeared at one point when there was no proper
-driver infrastructure for doing simpler MMIO GPIO devices and there was
-no core support for parsing device tree GPIOs from the core library with
-the [devm_]gpiod_get() calls we have today that will implicitly go into
-the device tree back-end. It is legacy and should not be used in new code.
-
-Work items:
-
-- Change all consumer drivers that #include <linux/of_gpio.h> to
-  #include <linux/gpio/consumer.h> and stop doing custom parsing of the
-  GPIO lines from the device tree. This can be tricky and often involves
-  changing board files, etc.
-
-- Pull semantics for legacy device tree (OF) GPIO lookups into
-  gpiolib-of.c: in some cases subsystems are doing custom flags and
-  lookups for polarity inversion, open drain and what not. As we now
-  handle this with generic OF bindings, pull all legacy handling into
-  gpiolib so the library API becomes narrow and deep and handle all
-  legacy bindings internally. (See e.g. commits 6953c57ab172,
-  6a537d48461d etc)
-
-- Delete <linux/of_gpio.h> when all the above is complete and everything
-  uses <linux/gpio/consumer.h> or <linux/gpio/driver.h> instead.
-
--------------------------------------------------------------------------------
-
 Collect drivers
 
 Collect GPIO drivers from arch/* and other places that should be placed
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index 3bdd9af674474..c512d735e85ff 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -14,7 +14,6 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/of_gpio.h>
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/slab.h>
 #include <linux/string.h>
@@ -446,32 +445,6 @@ static struct gpio_desc *of_get_named_gpiod_flags(const struct device_node *np,
 	return desc;
 }
 
-/**
- * of_get_named_gpio() - Get a GPIO number to use with GPIO API
- * @np:		device node to get GPIO from
- * @propname:	Name of property containing gpio specifier(s)
- * @index:	index of the GPIO
- *
- * **DEPRECATED** This function is deprecated and must not be used in new code.
- *
- * Returns:
- * GPIO number to use with Linux generic GPIO API, or one of the errno
- * value on the error condition.
- */
-int of_get_named_gpio(const struct device_node *np, const char *propname,
-		      int index)
-{
-	struct gpio_desc *desc;
-
-	desc = of_get_named_gpiod_flags(np, propname, index, NULL);
-
-	if (IS_ERR(desc))
-		return PTR_ERR(desc);
-	else
-		return desc_to_gpio(desc);
-}
-EXPORT_SYMBOL_GPL(of_get_named_gpio);
-
 /* Converts gpio_lookup_flags into bitmask of GPIO_* values */
 static unsigned long of_convert_gpio_flags(enum of_gpio_flags flags)
 {
diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h
deleted file mode 100644
index d0f66a5e1b2a7..0000000000000
--- a/include/linux/of_gpio.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * OF helpers for the GPIO API
- *
- * Copyright (c) 2007-2008  MontaVista Software, Inc.
- *
- * Author: Anton Vorontsov <avorontsov@ru.mvista.com>
- */
-
-#ifndef __LINUX_OF_GPIO_H
-#define __LINUX_OF_GPIO_H
-
-#include <linux/compiler.h>
-#include <linux/gpio/driver.h>
-#include <linux/gpio.h>		/* FIXME: Shouldn't be here */
-#include <linux/of.h>
-
-struct device_node;
-
-#ifdef CONFIG_OF_GPIO
-
-extern int of_get_named_gpio(const struct device_node *np,
-			     const char *list_name, int index);
-
-#else /* CONFIG_OF_GPIO */
-
-#include <linux/errno.h>
-
-/* Drivers may not strictly depend on the GPIO support, so let them link. */
-static inline int of_get_named_gpio(const struct device_node *np,
-                                   const char *propname, int index)
-{
-	return -ENOSYS;
-}
-
-#endif /* CONFIG_OF_GPIO */
-
-#endif /* __LINUX_OF_GPIO_H */
-- 
2.47.3
Re: [PATCH v3 0/3] Remove <linux/of_gpio.h>
Posted by Linus Walleij 1 month ago
n Fri, Mar 6, 2026 at 4:56 AM Jialu Xu <xujialu@vimux.org> wrote:

> Convert the last three NFC consumers of <linux/of_gpio.h> to the
> GPIO descriptor API, then remove the deprecated header entirely.
>
> Changes in v3:

v3 looks great to me.

The NFC subsystem is orphaned, so I suggest Bartosz simply
merge this to the GPIO tree at his earliest convenicence.

Yours,
Linus Walleij
Re: [PATCH v3 0/3] Remove <linux/of_gpio.h>
Posted by Krzysztof Kozlowski 1 month ago
On 06/03/2026 10:38, Linus Walleij wrote:
> n Fri, Mar 6, 2026 at 4:56 AM Jialu Xu <xujialu@vimux.org> wrote:
> 
>> Convert the last three NFC consumers of <linux/of_gpio.h> to the
>> GPIO descriptor API, then remove the deprecated header entirely.
>>
>> Changes in v3:
> 
> v3 looks great to me.
> 
> The NFC subsystem is orphaned, so I suggest Bartosz simply
> merge this to the GPIO tree at his earliest convenicence.

This should be sent same way it was before it got orphaned - nothing
changed in this regard, I just don't do reviews - via net-next.

Best regards,
Krzysztof
Re: [PATCH v3 0/3] Remove <linux/of_gpio.h>
Posted by Linus Walleij 1 month ago
On Fri, Mar 6, 2026 at 11:25 AM Krzysztof Kozlowski <krzk@kernel.org> wrote:
> On 06/03/2026 10:38, Linus Walleij wrote:
> > n Fri, Mar 6, 2026 at 4:56 AM Jialu Xu <xujialu@vimux.org> wrote:
> >
> >> Convert the last three NFC consumers of <linux/of_gpio.h> to the
> >> GPIO descriptor API, then remove the deprecated header entirely.
> >>
> >> Changes in v3:
> >
> > v3 looks great to me.
> >
> > The NFC subsystem is orphaned, so I suggest Bartosz simply
> > merge this to the GPIO tree at his earliest convenicence.
>
> This should be sent same way it was before it got orphaned - nothing
> changed in this regard, I just don't do reviews - via net-next.

Fair enough, either this or the network maintainer can give an
ACK to take it into the GPIO tree.

Jakub, what do you prefer?

Yours,
Linus Walleij
Re: [PATCH v3 0/3] Remove <linux/of_gpio.h>
Posted by Jakub Kicinski 1 month ago
On Fri, 6 Mar 2026 14:27:59 +0100 Linus Walleij wrote:
> > > The NFC subsystem is orphaned, so I suggest Bartosz simply
> > > merge this to the GPIO tree at his earliest convenicence.  
> >
> > This should be sent same way it was before it got orphaned - nothing
> > changed in this regard, I just don't do reviews - via net-next.  
> 
> Fair enough, either this or the network maintainer can give an
> ACK to take it into the GPIO tree.
> 
> Jakub, what do you prefer?

The whole thing seems to apply on 7.0-rc1 so let's do that and both
trees can pull the hashes in? I can cook up appropriate state in
net-next or Bartosz can.. no preference in that regard.

It looks like the code may still need some love tho
Re: [PATCH v3 0/3] Remove <linux/of_gpio.h>
Posted by Jialu Xu 1 month ago
Thanks. The issues you pointed out have been fixed in v4:

- Initialized reset_gpio to NULL in nfcmrvl_parse_dt() to avoid
  using uninitialized stack garbage in I2C/SPI paths.
- Used GPIOD_OUT_HIGH and inverted gpiod_set_value() arguments to
  match the active-low reset line documented in marvell,nci.yaml.
- Fixed continuation line alignment in s3fwrn5.

Best regards,
Jialu