Skip to content

Commit 362c0b3

Browse files
andy-shevrafaeljw
authored andcommitted
device property: Fallback to secondary fwnode if primary misses the property
The struct fwnode has notion of secondary fwnode. This is supposed to used as fallback if the primary firmware interface (DT, ACPI) does not have the property in question. However, the current implementation never checks the secondary node which prevents one to add default "built-in" properties to devices. This patch adds fallback to the secondary fwnode if the primary fwnode returns that the property does not exists. Signed-off-by: Mika Westerberg <[email protected]> Signed-off-by: Andy Shevchenko <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 3c60f11 commit 362c0b3

File tree

1 file changed

+78
-31
lines changed

1 file changed

+78
-31
lines changed

drivers/base/property.c

Lines changed: 78 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -214,12 +214,8 @@ bool device_property_present(struct device *dev, const char *propname)
214214
}
215215
EXPORT_SYMBOL_GPL(device_property_present);
216216

217-
/**
218-
* fwnode_property_present - check if a property of a firmware node is present
219-
* @fwnode: Firmware node whose property to check
220-
* @propname: Name of the property
221-
*/
222-
bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname)
217+
static bool __fwnode_property_present(struct fwnode_handle *fwnode,
218+
const char *propname)
223219
{
224220
if (is_of_node(fwnode))
225221
return of_property_read_bool(to_of_node(fwnode), propname);
@@ -229,6 +225,21 @@ bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname)
229225
return !!pset_prop_get(to_pset_node(fwnode), propname);
230226
return false;
231227
}
228+
229+
/**
230+
* fwnode_property_present - check if a property of a firmware node is present
231+
* @fwnode: Firmware node whose property to check
232+
* @propname: Name of the property
233+
*/
234+
bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname)
235+
{
236+
bool ret;
237+
238+
ret = __fwnode_property_present(fwnode, propname);
239+
if (ret == false && fwnode->secondary)
240+
ret = __fwnode_property_present(fwnode->secondary, propname);
241+
return ret;
242+
}
232243
EXPORT_SYMBOL_GPL(fwnode_property_present);
233244

234245
/**
@@ -408,7 +419,7 @@ EXPORT_SYMBOL_GPL(device_property_match_string);
408419
(val) ? pset_prop_read_##type##_array((node), (propname), (val), (nval)) \
409420
: pset_prop_count_elems_of_size((node), (propname), sizeof(type))
410421

411-
#define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \
422+
#define FWNODE_PROP_READ(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \
412423
({ \
413424
int _ret_; \
414425
if (is_of_node(_fwnode_)) \
@@ -425,6 +436,17 @@ EXPORT_SYMBOL_GPL(device_property_match_string);
425436
_ret_; \
426437
})
427438

439+
#define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \
440+
({ \
441+
int _ret_; \
442+
_ret_ = FWNODE_PROP_READ(_fwnode_, _propname_, _type_, _proptype_, \
443+
_val_, _nval_); \
444+
if (_ret_ == -EINVAL && _fwnode_->secondary) \
445+
_ret_ = FWNODE_PROP_READ(_fwnode_->secondary, _propname_, _type_, \
446+
_proptype_, _val_, _nval_); \
447+
_ret_; \
448+
})
449+
428450
/**
429451
* fwnode_property_read_u8_array - return a u8 array property of firmware node
430452
* @fwnode: Firmware node to get the property of
@@ -529,6 +551,41 @@ int fwnode_property_read_u64_array(struct fwnode_handle *fwnode,
529551
}
530552
EXPORT_SYMBOL_GPL(fwnode_property_read_u64_array);
531553

554+
static int __fwnode_property_read_string_array(struct fwnode_handle *fwnode,
555+
const char *propname,
556+
const char **val, size_t nval)
557+
{
558+
if (is_of_node(fwnode))
559+
return val ?
560+
of_property_read_string_array(to_of_node(fwnode),
561+
propname, val, nval) :
562+
of_property_count_strings(to_of_node(fwnode), propname);
563+
else if (is_acpi_node(fwnode))
564+
return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
565+
val, nval);
566+
else if (is_pset_node(fwnode))
567+
return val ?
568+
pset_prop_read_string_array(to_pset_node(fwnode),
569+
propname, val, nval) :
570+
pset_prop_count_elems_of_size(to_pset_node(fwnode),
571+
propname,
572+
sizeof(const char *));
573+
return -ENXIO;
574+
}
575+
576+
static int __fwnode_property_read_string(struct fwnode_handle *fwnode,
577+
const char *propname, const char **val)
578+
{
579+
if (is_of_node(fwnode))
580+
return of_property_read_string(to_of_node(fwnode), propname, val);
581+
else if (is_acpi_node(fwnode))
582+
return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
583+
val, 1);
584+
else if (is_pset_node(fwnode))
585+
return pset_prop_read_string(to_pset_node(fwnode), propname, val);
586+
return -ENXIO;
587+
}
588+
532589
/**
533590
* fwnode_property_read_string_array - return string array property of a node
534591
* @fwnode: Firmware node to get the property of
@@ -551,22 +608,13 @@ int fwnode_property_read_string_array(struct fwnode_handle *fwnode,
551608
const char *propname, const char **val,
552609
size_t nval)
553610
{
554-
if (is_of_node(fwnode))
555-
return val ?
556-
of_property_read_string_array(to_of_node(fwnode),
557-
propname, val, nval) :
558-
of_property_count_strings(to_of_node(fwnode), propname);
559-
else if (is_acpi_node(fwnode))
560-
return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
561-
val, nval);
562-
else if (is_pset_node(fwnode))
563-
return val ?
564-
pset_prop_read_string_array(to_pset_node(fwnode),
565-
propname, val, nval) :
566-
pset_prop_count_elems_of_size(to_pset_node(fwnode),
567-
propname,
568-
sizeof(const char *));
569-
return -ENXIO;
611+
int ret;
612+
613+
ret = __fwnode_property_read_string_array(fwnode, propname, val, nval);
614+
if (ret == -EINVAL && fwnode->secondary)
615+
ret = __fwnode_property_read_string_array(fwnode->secondary,
616+
propname, val, nval);
617+
return ret;
570618
}
571619
EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);
572620

@@ -588,14 +636,13 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);
588636
int fwnode_property_read_string(struct fwnode_handle *fwnode,
589637
const char *propname, const char **val)
590638
{
591-
if (is_of_node(fwnode))
592-
return of_property_read_string(to_of_node(fwnode), propname, val);
593-
else if (is_acpi_node(fwnode))
594-
return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
595-
val, 1);
596-
else if (is_pset_node(fwnode))
597-
return pset_prop_read_string(to_pset_node(fwnode), propname, val);
598-
return -ENXIO;
639+
int ret;
640+
641+
ret = __fwnode_property_read_string(fwnode, propname, val);
642+
if (ret == -EINVAL && fwnode->secondary)
643+
ret = __fwnode_property_read_string(fwnode->secondary,
644+
propname, val);
645+
return ret;
599646
}
600647
EXPORT_SYMBOL_GPL(fwnode_property_read_string);
601648

0 commit comments

Comments
 (0)