Commit b544927d authored by Jialu Xu's avatar Jialu Xu Committed by Bartosz Golaszewski
Browse files

nfc: s3fwrn5: convert to gpio descriptors



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: default avatarJialu Xu <xujialu@vimux.org>
Reviewed-by: default avatarLinus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/94FF47746A92BD6B+20260307030623.3495092-2-xujialu@vimux.org


Signed-off-by: default avatarBartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
parent 6de23f81
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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" },
+7 −47
Original line number Diff line number Diff line
@@ -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.
+5 −6
Original line number Diff line number Diff line
@@ -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);
	}

+3 −2
Original line number Diff line number Diff line
@@ -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;

+10 −33
Original line number Diff line number Diff line
@@ -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);