Merge tag 'ib-gpio-remove-of-gpio-h-for-v7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git into gpio/for-next

Immutable branch between GPIO and net

Convert remaining users of of_gpio.h to using GPIO descriptors and
remove the header.
This commit is contained in:
Bartosz Golaszewski
2026-03-09 10:32:41 +01:00
12 changed files with 65 additions and 222 deletions

View File

@@ -10959,7 +10959,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

View File

@@ -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

View File

@@ -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)
{
@@ -542,6 +515,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" },

View File

@@ -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;

View File

@@ -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;

View File

@@ -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.");

View File

@@ -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);

View File

@@ -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;
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_en,
GPIOF_OUT_INIT_HIGH, "s3fwrn5_en");
if (ret < 0)
return ret;
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.

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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)
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_en,
GPIOF_OUT_INIT_HIGH, "s3fwrn82_en");
if (ret < 0)
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);

View File

@@ -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 */