On Fri, Jan 22, 2021 at 4:46 PM Calvin Johnson <calvin.johnson@xxxxxxxxxxx> wrote: > > Using fwnode_get_id(), get the reg property value for DT node > or get the _ADR object value for ACPI node. So I'm not really sure if this is going to be generically useful. First of all, the meaning of the _ADR return value is specific to a given bus type (e.g. the PCI encoding of it is different from the I2C encoding of it) and it just happens to be matching the definition of the "reg" property for this particular binding. IOW, not everyone may expect the "reg" property and the _ADR return value to have the same encoding and belong to the same set of values, so maybe put this function somewhere closer to the code that's going to use it, because it seems to be kind of specific to this particular use case? > Signed-off-by: Calvin Johnson <calvin.johnson@xxxxxxxxxxx> > --- > > Changes in v4: > - Improve code structure to handle all cases > > Changes in v3: > - Modified to retrieve reg property value for ACPI as well > - Resolved compilation issue with CONFIG_ACPI = n > - Added more info into documentation > > Changes in v2: None > > drivers/base/property.c | 34 ++++++++++++++++++++++++++++++++++ > include/linux/property.h | 1 + > 2 files changed, 35 insertions(+) > > diff --git a/drivers/base/property.c b/drivers/base/property.c > index 35b95c6ac0c6..f0581bbf7a4b 100644 > --- a/drivers/base/property.c > +++ b/drivers/base/property.c > @@ -580,6 +580,40 @@ const char *fwnode_get_name_prefix(const struct fwnode_handle *fwnode) > return fwnode_call_ptr_op(fwnode, get_name_prefix); > } > > +/** > + * fwnode_get_id - Get the id of a fwnode. > + * @fwnode: firmware node > + * @id: id of the fwnode > + * > + * This function provides the id of a fwnode which can be either > + * DT or ACPI node. For ACPI, "reg" property value, if present will > + * be provided or else _ADR value will be provided. > + * Returns 0 on success or a negative errno. > + */ > +int fwnode_get_id(struct fwnode_handle *fwnode, u32 *id) > +{ > +#ifdef CONFIG_ACPI > + unsigned long long adr; > + acpi_status status; > +#endif > + int ret; > + > + ret = fwnode_property_read_u32(fwnode, "reg", id); > + if (ret) { > +#ifdef CONFIG_ACPI > + status = acpi_evaluate_integer(ACPI_HANDLE_FWNODE(fwnode), > + METHOD_NAME__ADR, NULL, &adr); > + if (ACPI_FAILURE(status)) > + return -EINVAL; > + *id = (u32)adr; > +#else > + return ret; > +#endif > + } > + return 0; > +} > +EXPORT_SYMBOL_GPL(fwnode_get_id); > + > /** > * fwnode_get_parent - Return parent firwmare node > * @fwnode: Firmware whose parent is retrieved > diff --git a/include/linux/property.h b/include/linux/property.h > index 0a9001fe7aea..3f41475f010b 100644 > --- a/include/linux/property.h > +++ b/include/linux/property.h > @@ -82,6 +82,7 @@ struct fwnode_handle *fwnode_find_reference(const struct fwnode_handle *fwnode, > > const char *fwnode_get_name(const struct fwnode_handle *fwnode); > const char *fwnode_get_name_prefix(const struct fwnode_handle *fwnode); > +int fwnode_get_id(struct fwnode_handle *fwnode, u32 *id); > struct fwnode_handle *fwnode_get_parent(const struct fwnode_handle *fwnode); > struct fwnode_handle *fwnode_get_next_parent( > struct fwnode_handle *fwnode); > -- > 2.17.1 >