Skip to content

Commit 613e972

Browse files
Adam Thomsonbroonie
authored andcommitted
device property: Add function to search for named child of device
For device nodes in both DT and ACPI, it possible to have named child nodes which contain properties (an existing example being gpio-leds). This adds a function to find a named child node for a device which can be used by drivers for property retrieval. For DT data node name matching, of_node_cmp() and similar functions are made available outside of CONFIG_OF block so the new function can reference these for DT and non-DT builds. For ACPI data node name matching, a helper function is also added which returns false if CONFIG_ACPI is not set, otherwise it performs a string comparison on the data node name. This avoids using the acpi_data_node struct for non CONFIG_ACPI builds, which would otherwise cause a build failure. Signed-off-by: Adam Thomson <[email protected]> Acked-by: Sathyanarayana Nujella <[email protected]> Acked-by: Rob Herring <[email protected]> Acked-by: Rafael J. Wysocki <[email protected]> Signed-off-by: Mark Brown <[email protected]>
1 parent 1a695a9 commit 613e972

File tree

5 files changed

+51
-7
lines changed

5 files changed

+51
-7
lines changed

drivers/base/property.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,34 @@ struct fwnode_handle *device_get_next_child_node(struct device *dev,
887887
}
888888
EXPORT_SYMBOL_GPL(device_get_next_child_node);
889889

890+
/**
891+
* device_get_named_child_node - Return first matching named child node handle
892+
* @dev: Device to find the named child node for.
893+
* @childname: String to match child node name against.
894+
*/
895+
struct fwnode_handle *device_get_named_child_node(struct device *dev,
896+
const char *childname)
897+
{
898+
struct fwnode_handle *child;
899+
900+
/*
901+
* Find first matching named child node of this device.
902+
* For ACPI this will be a data only sub-node.
903+
*/
904+
device_for_each_child_node(dev, child) {
905+
if (is_of_node(child)) {
906+
if (!of_node_cmp(to_of_node(child)->name, childname))
907+
return child;
908+
} else if (is_acpi_data_node(child)) {
909+
if (acpi_data_node_match(child, childname))
910+
return child;
911+
}
912+
}
913+
914+
return NULL;
915+
}
916+
EXPORT_SYMBOL_GPL(device_get_named_child_node);
917+
890918
/**
891919
* fwnode_handle_put - Drop reference to a device node
892920
* @fwnode: Pointer to the device node to drop the reference to.

include/acpi/acpi_bus.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,13 @@ static inline struct acpi_data_node *to_acpi_data_node(struct fwnode_handle *fwn
420420
container_of(fwnode, struct acpi_data_node, fwnode) : NULL;
421421
}
422422

423+
static inline bool acpi_data_node_match(struct fwnode_handle *fwnode,
424+
const char *name)
425+
{
426+
return is_acpi_data_node(fwnode) ?
427+
(!strcmp(to_acpi_data_node(fwnode)->name, name)) : false;
428+
}
429+
423430
static inline struct fwnode_handle *acpi_fwnode_handle(struct acpi_device *adev)
424431
{
425432
return &adev->fwnode;

include/linux/acpi.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,12 @@ static inline struct acpi_data_node *to_acpi_data_node(struct fwnode_handle *fwn
568568
return NULL;
569569
}
570570

571+
static inline bool acpi_data_node_match(struct fwnode_handle *fwnode,
572+
const char *name)
573+
{
574+
return false;
575+
}
576+
571577
static inline struct fwnode_handle *acpi_fwnode_handle(struct acpi_device *adev)
572578
{
573579
return NULL;

include/linux/of.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -238,13 +238,6 @@ static inline unsigned long of_read_ulong(const __be32 *cell, int size)
238238
#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
239239
#endif
240240

241-
/* Default string compare functions, Allow arch asm/prom.h to override */
242-
#if !defined(of_compat_cmp)
243-
#define of_compat_cmp(s1, s2, l) strcasecmp((s1), (s2))
244-
#define of_prop_cmp(s1, s2) strcmp((s1), (s2))
245-
#define of_node_cmp(s1, s2) strcasecmp((s1), (s2))
246-
#endif
247-
248241
#define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
249242
#define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
250243

@@ -726,6 +719,13 @@ static inline void of_property_clear_flag(struct property *p, unsigned long flag
726719
#define of_match_node(_matches, _node) NULL
727720
#endif /* CONFIG_OF */
728721

722+
/* Default string compare functions, Allow arch asm/prom.h to override */
723+
#if !defined(of_compat_cmp)
724+
#define of_compat_cmp(s1, s2, l) strcasecmp((s1), (s2))
725+
#define of_prop_cmp(s1, s2) strcmp((s1), (s2))
726+
#define of_node_cmp(s1, s2) strcasecmp((s1), (s2))
727+
#endif
728+
729729
#if defined(CONFIG_OF) && defined(CONFIG_NUMA)
730730
extern int of_node_to_nid(struct device_node *np);
731731
#else

include/linux/property.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ struct fwnode_handle *device_get_next_child_node(struct device *dev,
7777
for (child = device_get_next_child_node(dev, NULL); child; \
7878
child = device_get_next_child_node(dev, child))
7979

80+
struct fwnode_handle *device_get_named_child_node(struct device *dev,
81+
const char *childname);
82+
8083
void fwnode_handle_put(struct fwnode_handle *fwnode);
8184

8285
unsigned int device_get_child_node_count(struct device *dev);

0 commit comments

Comments
 (0)