From: Sunil V L <sunilvl@xxxxxxxxxxxxxxxx> fwnode_get_reference_args() which is common for both DT and ACPI passes a property name like #mbox-cells which needs to be fetched from the reference node to determine the number of arguments needed for the property. However, the ACPI version of this function doesn't support this and simply ignores the parameter passed from the wrapper function. Add support for dynamically finding number of arguments by reading the nargs property value. Update the callers to pass extra parameter. Signed-off-by: Sunil V L <sunilvl@xxxxxxxxxxxxxxxx> Signed-off-by: Anup Patel <apatel@xxxxxxxxxxxxxxxx> --- drivers/acpi/property.c | 15 +++++++++++++-- drivers/gpio/gpiolib-acpi.c | 2 +- drivers/pwm/core.c | 2 +- include/linux/acpi.h | 12 +++++++----- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c index 98d93ed58315..ddea5dec70bd 100644 --- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c @@ -887,6 +887,9 @@ static struct fwnode_handle *acpi_parse_string_ref(const struct fwnode_handle *f * @fwnode: Firmware node to get the property from * @propname: Name of the property * @index: Index of the reference to return + * @nargs_prop: The name of the property telling the number of arguments + * in the referred node. NULL if @num_args is known, otherwise + * @num_args is ignored. * @num_args: Maximum number of arguments after each reference * @args: Location to store the returned reference with optional arguments * (may be NULL) @@ -919,13 +922,14 @@ static struct fwnode_handle *acpi_parse_string_ref(const struct fwnode_handle *f * Return: %0 on success, negative error code on failure. */ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, - const char *propname, size_t index, size_t num_args, + const char *propname, size_t index, const char *nargs_prop, size_t num_args, struct fwnode_reference_args *args) { const union acpi_object *element, *end; const union acpi_object *obj; const struct acpi_device_data *data; struct fwnode_handle *ref_fwnode; + struct acpi_device *ref_adev; struct acpi_device *device; int ret, idx = 0; @@ -1012,6 +1016,13 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, element->string.pointer); if (!ref_fwnode) return -EINVAL; + if (nargs_prop) { + ref_adev = to_acpi_device_node(ref_fwnode); + if (!acpi_dev_get_property(ref_adev, nargs_prop, + ACPI_TYPE_INTEGER, &obj)) { + num_args = obj->integer.value; + } + } element++; @@ -1565,7 +1576,7 @@ acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode, struct fwnode_reference_args *args) { return __acpi_node_get_property_reference(fwnode, prop, index, - args_count, args); + nargs_prop, args_count, args); } static const char *acpi_fwnode_get_name(const struct fwnode_handle *fwnode) diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 1f9fe50bba00..de8e4d081539 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -839,7 +839,7 @@ static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode, int ret; memset(&args, 0, sizeof(args)); - ret = __acpi_node_get_property_reference(fwnode, propname, index, 3, + ret = __acpi_node_get_property_reference(fwnode, propname, index, NULL, 3, &args); if (ret) { struct acpi_device *adev; diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index ccd54c089bab..7afd78061e6e 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -1790,7 +1790,7 @@ static struct pwm_device *acpi_pwm_get(const struct fwnode_handle *fwnode) memset(&args, 0, sizeof(args)); - ret = __acpi_node_get_property_reference(fwnode, "pwms", 0, 3, &args); + ret = __acpi_node_get_property_reference(fwnode, "pwms", 0, NULL, 3, &args); if (ret < 0) return ERR_PTR(ret); diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 4e495b29c640..b9fd3c812e1f 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -1296,8 +1296,9 @@ static inline int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index) int acpi_dev_get_property(const struct acpi_device *adev, const char *name, acpi_object_type type, const union acpi_object **obj); int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, - const char *name, size_t index, size_t num_args, - struct fwnode_reference_args *args); + const char *name, size_t index, + const char *nargs_prop, size_t num_args, + struct fwnode_reference_args *args); static inline int acpi_node_get_property_reference( const struct fwnode_handle *fwnode, @@ -1305,7 +1306,7 @@ static inline int acpi_node_get_property_reference( struct fwnode_reference_args *args) { return __acpi_node_get_property_reference(fwnode, name, index, - NR_FWNODE_REFERENCE_ARGS, args); + NULL, NR_FWNODE_REFERENCE_ARGS, args); } static inline bool acpi_dev_has_props(const struct acpi_device *adev) @@ -1400,8 +1401,9 @@ static inline int acpi_dev_get_property(struct acpi_device *adev, static inline int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, - const char *name, size_t index, size_t num_args, - struct fwnode_reference_args *args) + const char *name, size_t index, + const char *nargs_prop, size_t num_args, + struct fwnode_reference_args *args) { return -ENXIO; } -- 2.43.0