All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.