linux-acpi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/7] introduce fwnode in the I2C subsystem
@ 2022-03-23  9:18 Clément Léger
  2022-03-23  9:18 ` [PATCH v2 1/7] device property: add fwnode_property_read_string_index() Clément Léger
                   ` (6 more replies)
  0 siblings, 7 replies; 11+ messages in thread
From: Clément Léger @ 2022-03-23  9:18 UTC (permalink / raw)
  To: Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
	Greg Kroah-Hartman, Rafael J . Wysocki, Wolfram Sang,
	Peter Rosin, Rob Herring, Frank Rowand, Len Brown
  Cc: Hans de Goede, Thomas Petazzoni, Alexandre Belloni,
	Allan Nielsen, linux-kernel, linux-acpi, linux-i2c,
	Clément Léger

In order to allow the I2C subsystem to be usable with fwnode, add
some functions to retrieve an i2c_adapter from a fwnode and use
these functions in both i2c mux and sfp. ACPI and device-tree are
handled to allow these modifications to work with both descriptions.
I2C mux support has also been modified to support fwnode based
descriptions.

This series is a subset of the one that was first submitted as a larger
series to add swnode support [1]. In this one, it will be focused on
fwnode support only since it seems to have reach a consensus that
adding fwnode to subsystems makes sense.

[1] https://lore.kernel.org/netdev/YhPSkz8+BIcdb72R@smile.fi.intel.com/T/

---------------

Changes in V2:
 - Remove sfp modifications
 - Add property_read_string_index fwnode_operation callback
 - Implement .property_read_string_index for of and swnode
 - Renamed np variable to fwnode

Clément Léger (7):
  device property: add fwnode_property_read_string_index()
  of: property: implement .property_read_string_index callback
  software node: implement .property_read_string_index callback
  i2c: fwnode: add fwnode_find_i2c_adapter_by_node()
  i2c: of: use fwnode_get_i2c_adapter_by_node()
  i2c: mux: pinctrl: remove CONFIG_OF dependency and use fwnode API
  i2c: mux: add support for fwnode

 drivers/base/property.c             | 26 +++++++++++++++++
 drivers/base/swnode.c               | 40 +++++++++++++++++++++++++
 drivers/i2c/Makefile                |  1 +
 drivers/i2c/i2c-core-fwnode.c       | 45 +++++++++++++++++++++++++++++
 drivers/i2c/i2c-core-of.c           | 30 -------------------
 drivers/i2c/i2c-mux.c               | 39 ++++++++++++-------------
 drivers/i2c/muxes/Kconfig           |  1 -
 drivers/i2c/muxes/i2c-mux-pinctrl.c | 23 ++++++++-------
 drivers/of/property.c               | 11 +++++++
 include/linux/fwnode.h              |  6 ++++
 include/linux/i2c.h                 |  8 ++++-
 include/linux/property.h            |  3 ++
 12 files changed, 169 insertions(+), 64 deletions(-)
 create mode 100644 drivers/i2c/i2c-core-fwnode.c

-- 
2.34.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 1/7] device property: add fwnode_property_read_string_index()
  2022-03-23  9:18 [PATCH v2 0/7] introduce fwnode in the I2C subsystem Clément Léger
@ 2022-03-23  9:18 ` Clément Léger
  2022-03-23 11:34   ` Sakari Ailus
  2022-03-23  9:18 ` [PATCH v2 2/7] of: property: implement .property_read_string_index callback Clément Léger
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 11+ messages in thread
From: Clément Léger @ 2022-03-23  9:18 UTC (permalink / raw)
  To: Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
	Greg Kroah-Hartman, Rafael J . Wysocki, Wolfram Sang,
	Peter Rosin, Rob Herring, Frank Rowand, Len Brown
  Cc: Hans de Goede, Thomas Petazzoni, Alexandre Belloni,
	Allan Nielsen, linux-kernel, linux-acpi, linux-i2c,
	Clément Léger

Add fwnode_property_read_string_index() function which allows to
retrieve a string from an array by its index. This function is the
equivalent of of_property_read_string_index() but for fwnode support.
A .property_read_string_index callback is added to fwnode_ops to avoid
doing a full allocation of an array just to retrieve one value.

Signed-off-by: Clément Léger <clement.leger@bootlin.com>
---
 drivers/base/property.c  | 26 ++++++++++++++++++++++++++
 include/linux/fwnode.h   |  6 ++++++
 include/linux/property.h |  3 +++
 3 files changed, 35 insertions(+)

diff --git a/drivers/base/property.c b/drivers/base/property.c
index e6497f6877ee..a8dd6e496a1d 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -451,6 +451,32 @@ int fwnode_property_match_string(const struct fwnode_handle *fwnode,
 }
 EXPORT_SYMBOL_GPL(fwnode_property_match_string);
 
+/**
+ * fwnode_property_read_string_index - read a string in an array using an index
+ * @fwnode: Firmware node to get the property of
+ * @propname: Name of the property holding the array
+ * @index: Index of the string to look for
+ * @string: Pointer to the string if found
+ *
+ * Find a string by a given index in a string array and if it is found return
+ * the string value in @string.
+ *
+ * Return: %0 if the property was found (success),
+ *	   %-EINVAL if given arguments are not valid,
+ *	   %-ENODATA if the property does not have a value,
+ *	   %-EPROTO if the property is not an array of strings,
+ *	   %-ENXIO if no suitable firmware interface is present.
+ */
+int fwnode_property_read_string_index(const struct fwnode_handle *fwnode,
+				      const char *propname, int index,
+				      const char **string)
+{
+	return fwnode_call_int_op(fwnode, property_read_string_index, propname,
+				  index,
+				  string);
+}
+EXPORT_SYMBOL_GPL(fwnode_property_read_string_index);
+
 /**
  * fwnode_property_get_reference_args() - Find a reference with arguments
  * @fwnode:	Firmware node where to look for the reference
diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h
index 3a532ba66f6c..71ba8f53cf1e 100644
--- a/include/linux/fwnode.h
+++ b/include/linux/fwnode.h
@@ -93,6 +93,9 @@ struct fwnode_reference_args {
  *			     success, a negative error code otherwise.
  * @property_read_string_array: Read an array of string properties. Return zero
  *				on success, a negative error code otherwise.
+ * @property_read_string_index: Read a string from a string array using an
+ *				index. Return zero on success, a negative error
+ *				code otherwise.
  * @get_name: Return the name of an fwnode.
  * @get_name_prefix: Get a prefix for a node (for printing purposes).
  * @get_parent: Return the parent of an fwnode.
@@ -123,6 +126,9 @@ struct fwnode_operations {
 	(*property_read_string_array)(const struct fwnode_handle *fwnode_handle,
 				      const char *propname, const char **val,
 				      size_t nval);
+	int (*property_read_string_index)(const struct fwnode_handle *fwnode,
+					  const char *propname, int index,
+					  const char **string);
 	const char *(*get_name)(const struct fwnode_handle *fwnode);
 	const char *(*get_name_prefix)(const struct fwnode_handle *fwnode);
 	struct fwnode_handle *(*get_parent)(const struct fwnode_handle *fwnode);
diff --git a/include/linux/property.h b/include/linux/property.h
index 7399a0b45f98..a033920eb10a 100644
--- a/include/linux/property.h
+++ b/include/linux/property.h
@@ -70,6 +70,9 @@ int fwnode_property_read_string_array(const struct fwnode_handle *fwnode,
 				      size_t nval);
 int fwnode_property_read_string(const struct fwnode_handle *fwnode,
 				const char *propname, const char **val);
+int fwnode_property_read_string_index(const struct fwnode_handle *fwnode,
+				      const char *propname, int index,
+				      const char **string);
 int fwnode_property_match_string(const struct fwnode_handle *fwnode,
 				 const char *propname, const char *string);
 int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 2/7] of: property: implement .property_read_string_index callback
  2022-03-23  9:18 [PATCH v2 0/7] introduce fwnode in the I2C subsystem Clément Léger
  2022-03-23  9:18 ` [PATCH v2 1/7] device property: add fwnode_property_read_string_index() Clément Léger
@ 2022-03-23  9:18 ` Clément Léger
  2022-03-23  9:18 ` [PATCH v2 3/7] software node: " Clément Léger
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Clément Léger @ 2022-03-23  9:18 UTC (permalink / raw)
  To: Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
	Greg Kroah-Hartman, Rafael J . Wysocki, Wolfram Sang,
	Peter Rosin, Rob Herring, Frank Rowand, Len Brown
  Cc: Hans de Goede, Thomas Petazzoni, Alexandre Belloni,
	Allan Nielsen, linux-kernel, linux-acpi, linux-i2c,
	Clément Léger

Implement .property_read_string_index callback using
of_property_read_string_index().

Signed-off-by: Clément Léger <clement.leger@bootlin.com>
---
 drivers/of/property.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/of/property.c b/drivers/of/property.c
index 8e90071de6ed..573eea693bfa 100644
--- a/drivers/of/property.c
+++ b/drivers/of/property.c
@@ -915,6 +915,16 @@ of_fwnode_property_read_string_array(const struct fwnode_handle *fwnode,
 		of_property_count_strings(node, propname);
 }
 
+static int
+of_fwnode_property_read_string_index(const struct fwnode_handle *fwnode,
+				     const char *propname, int index,
+				     const char **string)
+{
+	const struct device_node *node = to_of_node(fwnode);
+
+	return of_property_read_string_index(node, propname, index, string);
+}
+
 static const char *of_fwnode_get_name(const struct fwnode_handle *fwnode)
 {
 	return kbasename(to_of_node(fwnode)->full_name);
@@ -1475,6 +1485,7 @@ const struct fwnode_operations of_fwnode_ops = {
 	.property_present = of_fwnode_property_present,
 	.property_read_int_array = of_fwnode_property_read_int_array,
 	.property_read_string_array = of_fwnode_property_read_string_array,
+	.property_read_string_index = of_fwnode_property_read_string_index,
 	.get_name = of_fwnode_get_name,
 	.get_name_prefix = of_fwnode_get_name_prefix,
 	.get_parent = of_fwnode_get_parent,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 3/7] software node: implement .property_read_string_index callback
  2022-03-23  9:18 [PATCH v2 0/7] introduce fwnode in the I2C subsystem Clément Léger
  2022-03-23  9:18 ` [PATCH v2 1/7] device property: add fwnode_property_read_string_index() Clément Léger
  2022-03-23  9:18 ` [PATCH v2 2/7] of: property: implement .property_read_string_index callback Clément Léger
@ 2022-03-23  9:18 ` Clément Léger
  2022-03-23  9:18 ` [PATCH v2 4/7] i2c: fwnode: add fwnode_find_i2c_adapter_by_node() Clément Léger
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Clément Léger @ 2022-03-23  9:18 UTC (permalink / raw)
  To: Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
	Greg Kroah-Hartman, Rafael J . Wysocki, Wolfram Sang,
	Peter Rosin, Rob Herring, Frank Rowand, Len Brown
  Cc: Hans de Goede, Thomas Petazzoni, Alexandre Belloni,
	Allan Nielsen, linux-kernel, linux-acpi, linux-i2c,
	Clément Léger

Implement .property_read_string_index callback by fetching the strings
pointers from the software node property and getting the one at the
requested index.

Signed-off-by: Clément Léger <clement.leger@bootlin.com>
---
 drivers/base/swnode.c | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
index 0a482212c7e8..91cefc62adb3 100644
--- a/drivers/base/swnode.c
+++ b/drivers/base/swnode.c
@@ -182,6 +182,34 @@ static int property_entry_read_int_array(const struct property_entry *props,
 	return 0;
 }
 
+static int property_entry_read_string_index(const struct property_entry *props,
+					    const char *propname, int index,
+					    const char **string)
+{
+	const char * const *strings;
+	size_t length;
+	int array_len;
+
+	/* Find out the array length. */
+	array_len = property_entry_count_elems_of_size(props, propname,
+						       sizeof(const char *));
+	if (array_len < 0)
+		return array_len;
+
+	if (index >= array_len)
+		return -EINVAL;
+
+	length = array_len * sizeof(const char *);
+
+	strings = property_entry_find(props, propname, length);
+	if (IS_ERR(strings))
+		return PTR_ERR(strings);
+
+	*string = strings[index];
+
+	return 0;
+}
+
 static int property_entry_read_string_array(const struct property_entry *props,
 					    const char *propname,
 					    const char **strings, size_t nval)
@@ -408,6 +436,17 @@ static int software_node_read_string_array(const struct fwnode_handle *fwnode,
 						propname, val, nval);
 }
 
+static int
+software_node_read_string_index(const struct fwnode_handle *fwnode,
+				const char *propname, int index,
+				const char **string)
+{
+	struct swnode *swnode = to_swnode(fwnode);
+
+	return property_entry_read_string_index(swnode->node->properties,
+						propname, index, string);
+}
+
 static const char *
 software_node_get_name(const struct fwnode_handle *fwnode)
 {
@@ -665,6 +704,7 @@ static const struct fwnode_operations software_node_ops = {
 	.property_present = software_node_property_present,
 	.property_read_int_array = software_node_read_int_array,
 	.property_read_string_array = software_node_read_string_array,
+	.property_read_string_index = software_node_read_string_index,
 	.get_name = software_node_get_name,
 	.get_name_prefix = software_node_get_name_prefix,
 	.get_parent = software_node_get_parent,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 4/7] i2c: fwnode: add fwnode_find_i2c_adapter_by_node()
  2022-03-23  9:18 [PATCH v2 0/7] introduce fwnode in the I2C subsystem Clément Léger
                   ` (2 preceding siblings ...)
  2022-03-23  9:18 ` [PATCH v2 3/7] software node: " Clément Léger
@ 2022-03-23  9:18 ` Clément Léger
  2022-03-23  9:18 ` [PATCH v2 5/7] i2c: of: use fwnode_get_i2c_adapter_by_node() Clément Léger
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Clément Léger @ 2022-03-23  9:18 UTC (permalink / raw)
  To: Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
	Greg Kroah-Hartman, Rafael J . Wysocki, Wolfram Sang,
	Peter Rosin, Rob Herring, Frank Rowand, Len Brown
  Cc: Hans de Goede, Thomas Petazzoni, Alexandre Belloni,
	Allan Nielsen, linux-kernel, linux-acpi, linux-i2c,
	Clément Léger

Add fwnode_find_i2c_adapter_by_node() which allows to retrieve a i2c
adapter using a fwnode. Since dev_fwnode() uses the fwnode provided by
the of_node member of the device, this will also work for devices were
the of_node has been set and not the fwnode field.
For acpi nodes, the check for parent node is skipped since
i2c_acpi_find_adapter_by_handle() does not check it and we don't want
to change this behavior.

Signed-off-by: Clément Léger <clement.leger@bootlin.com>
---
 drivers/i2c/Makefile          |  1 +
 drivers/i2c/i2c-core-fwnode.c | 45 +++++++++++++++++++++++++++++++++++
 include/linux/i2c.h           |  3 +++
 3 files changed, 49 insertions(+)
 create mode 100644 drivers/i2c/i2c-core-fwnode.c

diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index c1d493dc9bac..c9c97675163e 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -6,6 +6,7 @@
 obj-$(CONFIG_I2C_BOARDINFO)	+= i2c-boardinfo.o
 obj-$(CONFIG_I2C)		+= i2c-core.o
 i2c-core-objs 			:= i2c-core-base.o i2c-core-smbus.o
+i2c-core-objs			+= i2c-core-fwnode.o
 i2c-core-$(CONFIG_ACPI)		+= i2c-core-acpi.o
 i2c-core-$(CONFIG_I2C_SLAVE) 	+= i2c-core-slave.o
 i2c-core-$(CONFIG_OF) 		+= i2c-core-of.o
diff --git a/drivers/i2c/i2c-core-fwnode.c b/drivers/i2c/i2c-core-fwnode.c
new file mode 100644
index 000000000000..fb1c820b686e
--- /dev/null
+++ b/drivers/i2c/i2c-core-fwnode.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Linux I2C core fwnode support code
+ *
+ * Copyright (C) 2022 Microchip
+ */
+
+#include <linux/device.h>
+#include <linux/i2c.h>
+
+#include "i2c-core.h"
+
+static int fwnode_dev_or_parent_node_match(struct device *dev, const void *data)
+{
+	if (device_match_fwnode(dev, data))
+		return 1;
+
+	/*
+	 * For ACPI device node, the behavior is to not match the parent (see
+	 * i2c_acpi_find_adapter_by_handle())
+	 */
+	if (!is_acpi_device_node(dev_fwnode(dev)) && dev->parent)
+		return device_match_fwnode(dev->parent, data);
+
+	return 0;
+}
+
+struct i2c_adapter *
+fwnode_find_i2c_adapter_by_node(struct fwnode_handle *fwnode)
+{
+	struct device *dev;
+	struct i2c_adapter *adapter;
+
+	dev = bus_find_device(&i2c_bus_type, NULL, fwnode,
+			      fwnode_dev_or_parent_node_match);
+	if (!dev)
+		return NULL;
+
+	adapter = i2c_verify_adapter(dev);
+	if (!adapter)
+		put_device(dev);
+
+	return adapter;
+}
+EXPORT_SYMBOL(fwnode_find_i2c_adapter_by_node);
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 7d4f52ceb7b5..8dadf8c89fd9 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -967,6 +967,9 @@ int i2c_handle_smbus_host_notify(struct i2c_adapter *adap, unsigned short addr);
 
 #endif /* I2C */
 
+struct i2c_adapter *
+fwnode_find_i2c_adapter_by_node(struct fwnode_handle *fwnode);
+
 #if IS_ENABLED(CONFIG_OF)
 /* must call put_device() when done with returned i2c_client device */
 struct i2c_client *of_find_i2c_device_by_node(struct device_node *node);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 5/7] i2c: of: use fwnode_get_i2c_adapter_by_node()
  2022-03-23  9:18 [PATCH v2 0/7] introduce fwnode in the I2C subsystem Clément Léger
                   ` (3 preceding siblings ...)
  2022-03-23  9:18 ` [PATCH v2 4/7] i2c: fwnode: add fwnode_find_i2c_adapter_by_node() Clément Léger
@ 2022-03-23  9:18 ` Clément Léger
  2022-03-23  9:18 ` [PATCH v2 6/7] i2c: mux: pinctrl: remove CONFIG_OF dependency and use fwnode API Clément Léger
  2022-03-23  9:18 ` [PATCH v2 7/7] i2c: mux: add support for fwnode Clément Léger
  6 siblings, 0 replies; 11+ messages in thread
From: Clément Léger @ 2022-03-23  9:18 UTC (permalink / raw)
  To: Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
	Greg Kroah-Hartman, Rafael J . Wysocki, Wolfram Sang,
	Peter Rosin, Rob Herring, Frank Rowand, Len Brown
  Cc: Hans de Goede, Thomas Petazzoni, Alexandre Belloni,
	Allan Nielsen, linux-kernel, linux-acpi, linux-i2c,
	Clément Léger

Since the new fwnode based fwnode_find_i2c_adapter_by_node() function
has the same behavior than of_get_i2c_adapter_by_node(), call it to
avoid code duplication.

Signed-off-by: Clément Léger <clement.leger@bootlin.com>
---
 drivers/i2c/i2c-core-of.c | 30 ------------------------------
 include/linux/i2c.h       |  5 ++++-
 2 files changed, 4 insertions(+), 31 deletions(-)

diff --git a/drivers/i2c/i2c-core-of.c b/drivers/i2c/i2c-core-of.c
index 3ed74aa4b44b..be7d66aa0f49 100644
--- a/drivers/i2c/i2c-core-of.c
+++ b/drivers/i2c/i2c-core-of.c
@@ -113,17 +113,6 @@ void of_i2c_register_devices(struct i2c_adapter *adap)
 	of_node_put(bus);
 }
 
-static int of_dev_or_parent_node_match(struct device *dev, const void *data)
-{
-	if (dev->of_node == data)
-		return 1;
-
-	if (dev->parent)
-		return dev->parent->of_node == data;
-
-	return 0;
-}
-
 /* must call put_device() when done with returned i2c_client device */
 struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
 {
@@ -142,25 +131,6 @@ struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
 }
 EXPORT_SYMBOL(of_find_i2c_device_by_node);
 
-/* must call put_device() when done with returned i2c_adapter device */
-struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
-{
-	struct device *dev;
-	struct i2c_adapter *adapter;
-
-	dev = bus_find_device(&i2c_bus_type, NULL, node,
-			      of_dev_or_parent_node_match);
-	if (!dev)
-		return NULL;
-
-	adapter = i2c_verify_adapter(dev);
-	if (!adapter)
-		put_device(dev);
-
-	return adapter;
-}
-EXPORT_SYMBOL(of_find_i2c_adapter_by_node);
-
 /* must call i2c_put_adapter() when done with returned i2c_adapter device */
 struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node *node)
 {
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 8dadf8c89fd9..982918fd0093 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -975,7 +975,10 @@ fwnode_find_i2c_adapter_by_node(struct fwnode_handle *fwnode);
 struct i2c_client *of_find_i2c_device_by_node(struct device_node *node);
 
 /* must call put_device() when done with returned i2c_adapter device */
-struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node);
+static inline struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
+{
+	return fwnode_find_i2c_adapter_by_node(of_fwnode_handle(node));
+}
 
 /* must call i2c_put_adapter() when done with returned i2c_adapter device */
 struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node *node);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 6/7] i2c: mux: pinctrl: remove CONFIG_OF dependency and use fwnode API
  2022-03-23  9:18 [PATCH v2 0/7] introduce fwnode in the I2C subsystem Clément Léger
                   ` (4 preceding siblings ...)
  2022-03-23  9:18 ` [PATCH v2 5/7] i2c: of: use fwnode_get_i2c_adapter_by_node() Clément Léger
@ 2022-03-23  9:18 ` Clément Léger
  2022-03-23  9:18 ` [PATCH v2 7/7] i2c: mux: add support for fwnode Clément Léger
  6 siblings, 0 replies; 11+ messages in thread
From: Clément Léger @ 2022-03-23  9:18 UTC (permalink / raw)
  To: Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
	Greg Kroah-Hartman, Rafael J . Wysocki, Wolfram Sang,
	Peter Rosin, Rob Herring, Frank Rowand, Len Brown
  Cc: Hans de Goede, Thomas Petazzoni, Alexandre Belloni,
	Allan Nielsen, linux-kernel, linux-acpi, linux-i2c,
	Clément Léger

In order to use i2c muxes with all types of nodes, switch to fwnode
API. The fwnode layer will allow to use this with both device_node and
software_node.

This commits is simply replacing the use of "of_" prefixed functions
with there fwnode equivalent.

Signed-off-by: Clément Léger <clement.leger@bootlin.com>
---
 drivers/i2c/muxes/Kconfig           |  1 -
 drivers/i2c/muxes/i2c-mux-pinctrl.c | 23 ++++++++++++-----------
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig
index 1708b1a82da2..d9cb15cfba3e 100644
--- a/drivers/i2c/muxes/Kconfig
+++ b/drivers/i2c/muxes/Kconfig
@@ -77,7 +77,6 @@ config I2C_MUX_PCA954x
 config I2C_MUX_PINCTRL
 	tristate "pinctrl-based I2C multiplexer"
 	depends on PINCTRL
-	depends on OF || COMPILE_TEST
 	help
 	  If you say yes to this option, support will be included for an I2C
 	  multiplexer that uses the pinctrl subsystem, i.e. pin multiplexing.
diff --git a/drivers/i2c/muxes/i2c-mux-pinctrl.c b/drivers/i2c/muxes/i2c-mux-pinctrl.c
index f1bb00a11ad6..d9c0241e8790 100644
--- a/drivers/i2c/muxes/i2c-mux-pinctrl.c
+++ b/drivers/i2c/muxes/i2c-mux-pinctrl.c
@@ -53,19 +53,20 @@ static struct i2c_adapter *i2c_mux_pinctrl_root_adapter(
 
 static struct i2c_adapter *i2c_mux_pinctrl_parent_adapter(struct device *dev)
 {
-	struct device_node *np = dev->of_node;
-	struct device_node *parent_np;
+	struct fwnode_handle *fwnode = dev_fwnode(dev);
+	struct fwnode_handle *parent_fwnode;
 	struct i2c_adapter *parent;
 
-	parent_np = of_parse_phandle(np, "i2c-parent", 0);
-	if (!parent_np) {
+	parent_fwnode = fwnode_find_reference(fwnode, "i2c-parent", 0);
+	if (!parent_fwnode) {
 		dev_err(dev, "Cannot parse i2c-parent\n");
 		return ERR_PTR(-ENODEV);
 	}
-	parent = of_find_i2c_adapter_by_node(parent_np);
-	of_node_put(parent_np);
-	if (!parent)
+	parent = fwnode_find_i2c_adapter_by_node(parent_fwnode);
+	if (!parent) {
+		dev_err(dev, "Cannot find i2c-parent\n");
 		return ERR_PTR(-EPROBE_DEFER);
+	}
 
 	return parent;
 }
@@ -73,7 +74,7 @@ static struct i2c_adapter *i2c_mux_pinctrl_parent_adapter(struct device *dev)
 static int i2c_mux_pinctrl_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct device_node *np = dev->of_node;
+	struct fwnode_handle *fwnode = dev_fwnode(dev);
 	struct i2c_mux_core *muxc;
 	struct i2c_mux_pinctrl *mux;
 	struct i2c_adapter *parent;
@@ -81,7 +82,7 @@ static int i2c_mux_pinctrl_probe(struct platform_device *pdev)
 	int num_names, i, ret;
 	const char *name;
 
-	num_names = of_property_count_strings(np, "pinctrl-names");
+	num_names = fwnode_property_string_array_count(fwnode, "pinctrl-names");
 	if (num_names < 0) {
 		dev_err(dev, "Cannot parse pinctrl-names: %d\n",
 			num_names);
@@ -111,8 +112,8 @@ static int i2c_mux_pinctrl_probe(struct platform_device *pdev)
 	}
 
 	for (i = 0; i < num_names; i++) {
-		ret = of_property_read_string_index(np, "pinctrl-names", i,
-						    &name);
+		ret = fwnode_property_read_string_index(fwnode, "pinctrl-names", i,
+							&name);
 		if (ret < 0) {
 			dev_err(dev, "Cannot parse pinctrl-names: %d\n", ret);
 			goto err_put_parent;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 7/7] i2c: mux: add support for fwnode
  2022-03-23  9:18 [PATCH v2 0/7] introduce fwnode in the I2C subsystem Clément Léger
                   ` (5 preceding siblings ...)
  2022-03-23  9:18 ` [PATCH v2 6/7] i2c: mux: pinctrl: remove CONFIG_OF dependency and use fwnode API Clément Léger
@ 2022-03-23  9:18 ` Clément Léger
  6 siblings, 0 replies; 11+ messages in thread
From: Clément Léger @ 2022-03-23  9:18 UTC (permalink / raw)
  To: Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
	Greg Kroah-Hartman, Rafael J . Wysocki, Wolfram Sang,
	Peter Rosin, Rob Herring, Frank Rowand, Len Brown
  Cc: Hans de Goede, Thomas Petazzoni, Alexandre Belloni,
	Allan Nielsen, linux-kernel, linux-acpi, linux-i2c,
	Clément Léger

Modify i2c_mux_add_adapter() to use the fwnode API to create mux
adapters with fwnode based devices. This allows to have a node agnostic
support for i2c muxes.

Signed-off-by: Clément Léger <clement.leger@bootlin.com>
---
 drivers/i2c/i2c-mux.c | 39 ++++++++++++++++++---------------------
 1 file changed, 18 insertions(+), 21 deletions(-)

diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c
index 774507b54b57..98d735349bd6 100644
--- a/drivers/i2c/i2c-mux.c
+++ b/drivers/i2c/i2c-mux.c
@@ -24,7 +24,7 @@
 #include <linux/i2c-mux.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/of.h>
+#include <linux/property.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
 
@@ -347,38 +347,35 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
 	else
 		priv->adap.class = class;
 
-	/*
-	 * Try to populate the mux adapter's of_node, expands to
-	 * nothing if !CONFIG_OF.
-	 */
-	if (muxc->dev->of_node) {
-		struct device_node *dev_node = muxc->dev->of_node;
-		struct device_node *mux_node, *child = NULL;
+	/* Try to populate the mux adapter's device node */
+	if (dev_fwnode(muxc->dev) && !has_acpi_companion(muxc->dev)) {
+		struct fwnode_handle *dev_node = dev_fwnode(muxc->dev);
+		struct fwnode_handle *mux_node, *child = NULL;
 		u32 reg;
 
 		if (muxc->arbitrator)
-			mux_node = of_get_child_by_name(dev_node, "i2c-arb");
+			mux_node = fwnode_get_named_child_node(dev_node, "i2c-arb");
 		else if (muxc->gate)
-			mux_node = of_get_child_by_name(dev_node, "i2c-gate");
+			mux_node = fwnode_get_named_child_node(dev_node, "i2c-gate");
 		else
-			mux_node = of_get_child_by_name(dev_node, "i2c-mux");
+			mux_node = fwnode_get_named_child_node(dev_node, "i2c-mux");
 
 		if (mux_node) {
 			/* A "reg" property indicates an old-style DT entry */
-			if (!of_property_read_u32(mux_node, "reg", &reg)) {
-				of_node_put(mux_node);
+			if (!fwnode_property_read_u32(mux_node, "reg", &reg)) {
+				fwnode_handle_put(mux_node);
 				mux_node = NULL;
 			}
 		}
 
 		if (!mux_node)
-			mux_node = of_node_get(dev_node);
+			mux_node = fwnode_handle_get(dev_node);
 		else if (muxc->arbitrator || muxc->gate)
-			child = of_node_get(mux_node);
+			child = fwnode_handle_get(mux_node);
 
 		if (!child) {
-			for_each_child_of_node(mux_node, child) {
-				ret = of_property_read_u32(child, "reg", &reg);
+			fwnode_for_each_child_node(mux_node, child) {
+				ret = fwnode_property_read_u32(child, "reg", &reg);
 				if (ret)
 					continue;
 				if (chan_id == reg)
@@ -386,8 +383,8 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
 			}
 		}
 
-		priv->adap.dev.of_node = child;
-		of_node_put(mux_node);
+		device_set_node(&priv->adap.dev, child);
+		fwnode_handle_put(mux_node);
 	}
 
 	/*
@@ -444,7 +441,7 @@ void i2c_mux_del_adapters(struct i2c_mux_core *muxc)
 	while (muxc->num_adapters) {
 		struct i2c_adapter *adap = muxc->adapter[--muxc->num_adapters];
 		struct i2c_mux_priv *priv = adap->algo_data;
-		struct device_node *np = adap->dev.of_node;
+		struct fwnode_handle *fwnode = dev_fwnode(&adap->dev);
 
 		muxc->adapter[muxc->num_adapters] = NULL;
 
@@ -454,7 +451,7 @@ void i2c_mux_del_adapters(struct i2c_mux_core *muxc)
 
 		sysfs_remove_link(&priv->adap.dev.kobj, "mux_device");
 		i2c_del_adapter(adap);
-		of_node_put(np);
+		fwnode_handle_put(fwnode);
 		kfree(priv);
 	}
 }
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 1/7] device property: add fwnode_property_read_string_index()
  2022-03-23  9:18 ` [PATCH v2 1/7] device property: add fwnode_property_read_string_index() Clément Léger
@ 2022-03-23 11:34   ` Sakari Ailus
  2022-03-23 11:39     ` Clément Léger
  0 siblings, 1 reply; 11+ messages in thread
From: Sakari Ailus @ 2022-03-23 11:34 UTC (permalink / raw)
  To: Clément Léger
  Cc: Andy Shevchenko, Daniel Scally, Heikki Krogerus,
	Greg Kroah-Hartman, Rafael J . Wysocki, Wolfram Sang,
	Peter Rosin, Rob Herring, Frank Rowand, Len Brown, Hans de Goede,
	Thomas Petazzoni, Alexandre Belloni, Allan Nielsen, linux-kernel,
	linux-acpi, linux-i2c

Hi Clément,

Thanks for the set.

On Wed, Mar 23, 2022 at 10:18:04AM +0100, Clément Léger wrote:
> Add fwnode_property_read_string_index() function which allows to
> retrieve a string from an array by its index. This function is the
> equivalent of of_property_read_string_index() but for fwnode support.
> A .property_read_string_index callback is added to fwnode_ops to avoid
> doing a full allocation of an array just to retrieve one value.
> 
> Signed-off-by: Clément Léger <clement.leger@bootlin.com>
> ---
>  drivers/base/property.c  | 26 ++++++++++++++++++++++++++
>  include/linux/fwnode.h   |  6 ++++++
>  include/linux/property.h |  3 +++
>  3 files changed, 35 insertions(+)
> 
> diff --git a/drivers/base/property.c b/drivers/base/property.c
> index e6497f6877ee..a8dd6e496a1d 100644
> --- a/drivers/base/property.c
> +++ b/drivers/base/property.c
> @@ -451,6 +451,32 @@ int fwnode_property_match_string(const struct fwnode_handle *fwnode,
>  }
>  EXPORT_SYMBOL_GPL(fwnode_property_match_string);
>  
> +/**
> + * fwnode_property_read_string_index - read a string in an array using an index
> + * @fwnode: Firmware node to get the property of
> + * @propname: Name of the property holding the array
> + * @index: Index of the string to look for
> + * @string: Pointer to the string if found
> + *
> + * Find a string by a given index in a string array and if it is found return
> + * the string value in @string.
> + *
> + * Return: %0 if the property was found (success),
> + *	   %-EINVAL if given arguments are not valid,
> + *	   %-ENODATA if the property does not have a value,
> + *	   %-EPROTO if the property is not an array of strings,
> + *	   %-ENXIO if no suitable firmware interface is present.
> + */
> +int fwnode_property_read_string_index(const struct fwnode_handle *fwnode,
> +				      const char *propname, int index,
> +				      const char **string)
> +{
> +	return fwnode_call_int_op(fwnode, property_read_string_index, propname,
> +				  index,
> +				  string);
> +}
> +EXPORT_SYMBOL_GPL(fwnode_property_read_string_index);
> +
>  /**
>   * fwnode_property_get_reference_args() - Find a reference with arguments
>   * @fwnode:	Firmware node where to look for the reference
> diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h
> index 3a532ba66f6c..71ba8f53cf1e 100644
> --- a/include/linux/fwnode.h
> +++ b/include/linux/fwnode.h
> @@ -93,6 +93,9 @@ struct fwnode_reference_args {
>   *			     success, a negative error code otherwise.
>   * @property_read_string_array: Read an array of string properties. Return zero
>   *				on success, a negative error code otherwise.
> + * @property_read_string_index: Read a string from a string array using an
> + *				index. Return zero on success, a negative error
> + *				code otherwise.
>   * @get_name: Return the name of an fwnode.
>   * @get_name_prefix: Get a prefix for a node (for printing purposes).
>   * @get_parent: Return the parent of an fwnode.
> @@ -123,6 +126,9 @@ struct fwnode_operations {
>  	(*property_read_string_array)(const struct fwnode_handle *fwnode_handle,
>  				      const char *propname, const char **val,
>  				      size_t nval);
> +	int (*property_read_string_index)(const struct fwnode_handle *fwnode,
> +					  const char *propname, int index,
> +					  const char **string);

Could this instead be done by adding an index argument to the
property_read_string_array?

The ACPI case is a bit more work but it guess it could be implemented later
as part of a more general cleanup there.

>  	const char *(*get_name)(const struct fwnode_handle *fwnode);
>  	const char *(*get_name_prefix)(const struct fwnode_handle *fwnode);
>  	struct fwnode_handle *(*get_parent)(const struct fwnode_handle *fwnode);
> diff --git a/include/linux/property.h b/include/linux/property.h
> index 7399a0b45f98..a033920eb10a 100644
> --- a/include/linux/property.h
> +++ b/include/linux/property.h
> @@ -70,6 +70,9 @@ int fwnode_property_read_string_array(const struct fwnode_handle *fwnode,
>  				      size_t nval);
>  int fwnode_property_read_string(const struct fwnode_handle *fwnode,
>  				const char *propname, const char **val);
> +int fwnode_property_read_string_index(const struct fwnode_handle *fwnode,
> +				      const char *propname, int index,
> +				      const char **string);
>  int fwnode_property_match_string(const struct fwnode_handle *fwnode,
>  				 const char *propname, const char *string);
>  int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode,

-- 
Kind regards,

Sakari Ailus

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 1/7] device property: add fwnode_property_read_string_index()
  2022-03-23 11:34   ` Sakari Ailus
@ 2022-03-23 11:39     ` Clément Léger
  2022-03-23 13:57       ` Sakari Ailus
  0 siblings, 1 reply; 11+ messages in thread
From: Clément Léger @ 2022-03-23 11:39 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Andy Shevchenko, Daniel Scally, Heikki Krogerus,
	Greg Kroah-Hartman, Rafael J . Wysocki, Wolfram Sang,
	Peter Rosin, Rob Herring, Frank Rowand, Len Brown, Hans de Goede,
	Thomas Petazzoni, Alexandre Belloni, Allan Nielsen, linux-kernel,
	linux-acpi, linux-i2c

Le Wed, 23 Mar 2022 13:34:07 +0200,
Sakari Ailus <sakari.ailus@linux.intel.com> a écrit :

> >   * @get_parent: Return the parent of an fwnode.
> > @@ -123,6 +126,9 @@ struct fwnode_operations {
> >  	(*property_read_string_array)(const struct fwnode_handle *fwnode_handle,
> >  				      const char *propname, const char **val,
> >  				      size_t nval);
> > +	int (*property_read_string_index)(const struct fwnode_handle *fwnode,
> > +					  const char *propname, int index,
> > +					  const char **string);  
> 
> Could this instead be done by adding an index argument to the
> property_read_string_array?

Hi Sakari,

I guess I could do that. Do you expect the string pointer to be
returned in "val" ? Guess a -1 index would mean that we don't care
about the index but want the array to be returned. And if index is
specified, nval will be ignored.

> 
> The ACPI case is a bit more work but it guess it could be implemented later
> as part of a more general cleanup there.

-- 
Clément Léger,
Embedded Linux and Kernel engineer at Bootlin
https://bootlin.com

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 1/7] device property: add fwnode_property_read_string_index()
  2022-03-23 11:39     ` Clément Léger
@ 2022-03-23 13:57       ` Sakari Ailus
  0 siblings, 0 replies; 11+ messages in thread
From: Sakari Ailus @ 2022-03-23 13:57 UTC (permalink / raw)
  To: Clément Léger
  Cc: Andy Shevchenko, Daniel Scally, Heikki Krogerus,
	Greg Kroah-Hartman, Rafael J . Wysocki, Wolfram Sang,
	Peter Rosin, Rob Herring, Frank Rowand, Len Brown, Hans de Goede,
	Thomas Petazzoni, Alexandre Belloni, Allan Nielsen, linux-kernel,
	linux-acpi, linux-i2c

Hi Clément,

On Wed, Mar 23, 2022 at 12:39:02PM +0100, Clément Léger wrote:
> Le Wed, 23 Mar 2022 13:34:07 +0200,
> Sakari Ailus <sakari.ailus@linux.intel.com> a écrit :
> 
> > >   * @get_parent: Return the parent of an fwnode.
> > > @@ -123,6 +126,9 @@ struct fwnode_operations {
> > >  	(*property_read_string_array)(const struct fwnode_handle *fwnode_handle,
> > >  				      const char *propname, const char **val,
> > >  				      size_t nval);
> > > +	int (*property_read_string_index)(const struct fwnode_handle *fwnode,
> > > +					  const char *propname, int index,
> > > +					  const char **string);  
> > 
> > Could this instead be done by adding an index argument to the
> > property_read_string_array?
> 
> Hi Sakari,
> 
> I guess I could do that. Do you expect the string pointer to be
> returned in "val" ? Guess a -1 index would mean that we don't care
> about the index but want the array to be returned. And if index is
> specified, nval will be ignored.

I'd keep the behaviour the same independently of the value of index.

-- 
Sakari Ailus

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2022-03-23 13:57 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-23  9:18 [PATCH v2 0/7] introduce fwnode in the I2C subsystem Clément Léger
2022-03-23  9:18 ` [PATCH v2 1/7] device property: add fwnode_property_read_string_index() Clément Léger
2022-03-23 11:34   ` Sakari Ailus
2022-03-23 11:39     ` Clément Léger
2022-03-23 13:57       ` Sakari Ailus
2022-03-23  9:18 ` [PATCH v2 2/7] of: property: implement .property_read_string_index callback Clément Léger
2022-03-23  9:18 ` [PATCH v2 3/7] software node: " Clément Léger
2022-03-23  9:18 ` [PATCH v2 4/7] i2c: fwnode: add fwnode_find_i2c_adapter_by_node() Clément Léger
2022-03-23  9:18 ` [PATCH v2 5/7] i2c: of: use fwnode_get_i2c_adapter_by_node() Clément Léger
2022-03-23  9:18 ` [PATCH v2 6/7] i2c: mux: pinctrl: remove CONFIG_OF dependency and use fwnode API Clément Léger
2022-03-23  9:18 ` [PATCH v2 7/7] i2c: mux: add support for fwnode Clément Léger

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).