* [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
* 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
* [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", ®)) {
- of_node_put(mux_node);
+ if (!fwnode_property_read_u32(mux_node, "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", ®);
+ fwnode_for_each_child_node(mux_node, child) {
+ ret = fwnode_property_read_u32(child, "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