Commit 362c0b30 authored by Andy Shevchenko's avatar Andy Shevchenko Committed by Rafael J. Wysocki

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: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 3c60f114
...@@ -214,12 +214,8 @@ bool device_property_present(struct device *dev, const char *propname) ...@@ -214,12 +214,8 @@ bool device_property_present(struct device *dev, const char *propname)
} }
EXPORT_SYMBOL_GPL(device_property_present); EXPORT_SYMBOL_GPL(device_property_present);
/** static bool __fwnode_property_present(struct fwnode_handle *fwnode,
* fwnode_property_present - check if a property of a firmware node is present const char *propname)
* @fwnode: Firmware node whose property to check
* @propname: Name of the property
*/
bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname)
{ {
if (is_of_node(fwnode)) if (is_of_node(fwnode))
return of_property_read_bool(to_of_node(fwnode), propname); 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) ...@@ -229,6 +225,21 @@ bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname)
return !!pset_prop_get(to_pset_node(fwnode), propname); return !!pset_prop_get(to_pset_node(fwnode), propname);
return false; return false;
} }
/**
* fwnode_property_present - check if a property of a firmware node is present
* @fwnode: Firmware node whose property to check
* @propname: Name of the property
*/
bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname)
{
bool ret;
ret = __fwnode_property_present(fwnode, propname);
if (ret == false && fwnode->secondary)
ret = __fwnode_property_present(fwnode->secondary, propname);
return ret;
}
EXPORT_SYMBOL_GPL(fwnode_property_present); EXPORT_SYMBOL_GPL(fwnode_property_present);
/** /**
...@@ -408,7 +419,7 @@ EXPORT_SYMBOL_GPL(device_property_match_string); ...@@ -408,7 +419,7 @@ EXPORT_SYMBOL_GPL(device_property_match_string);
(val) ? pset_prop_read_##type##_array((node), (propname), (val), (nval)) \ (val) ? pset_prop_read_##type##_array((node), (propname), (val), (nval)) \
: pset_prop_count_elems_of_size((node), (propname), sizeof(type)) : pset_prop_count_elems_of_size((node), (propname), sizeof(type))
#define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \ #define FWNODE_PROP_READ(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \
({ \ ({ \
int _ret_; \ int _ret_; \
if (is_of_node(_fwnode_)) \ if (is_of_node(_fwnode_)) \
...@@ -425,6 +436,17 @@ EXPORT_SYMBOL_GPL(device_property_match_string); ...@@ -425,6 +436,17 @@ EXPORT_SYMBOL_GPL(device_property_match_string);
_ret_; \ _ret_; \
}) })
#define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \
({ \
int _ret_; \
_ret_ = FWNODE_PROP_READ(_fwnode_, _propname_, _type_, _proptype_, \
_val_, _nval_); \
if (_ret_ == -EINVAL && _fwnode_->secondary) \
_ret_ = FWNODE_PROP_READ(_fwnode_->secondary, _propname_, _type_, \
_proptype_, _val_, _nval_); \
_ret_; \
})
/** /**
* fwnode_property_read_u8_array - return a u8 array property of firmware node * fwnode_property_read_u8_array - return a u8 array property of firmware node
* @fwnode: Firmware node to get the property of * @fwnode: Firmware node to get the property of
...@@ -529,6 +551,41 @@ int fwnode_property_read_u64_array(struct fwnode_handle *fwnode, ...@@ -529,6 +551,41 @@ int fwnode_property_read_u64_array(struct fwnode_handle *fwnode,
} }
EXPORT_SYMBOL_GPL(fwnode_property_read_u64_array); EXPORT_SYMBOL_GPL(fwnode_property_read_u64_array);
static int __fwnode_property_read_string_array(struct fwnode_handle *fwnode,
const char *propname,
const char **val, size_t nval)
{
if (is_of_node(fwnode))
return val ?
of_property_read_string_array(to_of_node(fwnode),
propname, val, nval) :
of_property_count_strings(to_of_node(fwnode), propname);
else if (is_acpi_node(fwnode))
return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
val, nval);
else if (is_pset_node(fwnode))
return val ?
pset_prop_read_string_array(to_pset_node(fwnode),
propname, val, nval) :
pset_prop_count_elems_of_size(to_pset_node(fwnode),
propname,
sizeof(const char *));
return -ENXIO;
}
static int __fwnode_property_read_string(struct fwnode_handle *fwnode,
const char *propname, const char **val)
{
if (is_of_node(fwnode))
return of_property_read_string(to_of_node(fwnode), propname, val);
else if (is_acpi_node(fwnode))
return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
val, 1);
else if (is_pset_node(fwnode))
return pset_prop_read_string(to_pset_node(fwnode), propname, val);
return -ENXIO;
}
/** /**
* fwnode_property_read_string_array - return string array property of a node * fwnode_property_read_string_array - return string array property of a node
* @fwnode: Firmware node to get the property of * @fwnode: Firmware node to get the property of
...@@ -551,22 +608,13 @@ int fwnode_property_read_string_array(struct fwnode_handle *fwnode, ...@@ -551,22 +608,13 @@ int fwnode_property_read_string_array(struct fwnode_handle *fwnode,
const char *propname, const char **val, const char *propname, const char **val,
size_t nval) size_t nval)
{ {
if (is_of_node(fwnode)) int ret;
return val ?
of_property_read_string_array(to_of_node(fwnode), ret = __fwnode_property_read_string_array(fwnode, propname, val, nval);
propname, val, nval) : if (ret == -EINVAL && fwnode->secondary)
of_property_count_strings(to_of_node(fwnode), propname); ret = __fwnode_property_read_string_array(fwnode->secondary,
else if (is_acpi_node(fwnode)) propname, val, nval);
return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING, return ret;
val, nval);
else if (is_pset_node(fwnode))
return val ?
pset_prop_read_string_array(to_pset_node(fwnode),
propname, val, nval) :
pset_prop_count_elems_of_size(to_pset_node(fwnode),
propname,
sizeof(const char *));
return -ENXIO;
} }
EXPORT_SYMBOL_GPL(fwnode_property_read_string_array); EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);
...@@ -588,14 +636,13 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_string_array); ...@@ -588,14 +636,13 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);
int fwnode_property_read_string(struct fwnode_handle *fwnode, int fwnode_property_read_string(struct fwnode_handle *fwnode,
const char *propname, const char **val) const char *propname, const char **val)
{ {
if (is_of_node(fwnode)) int ret;
return of_property_read_string(to_of_node(fwnode), propname, val);
else if (is_acpi_node(fwnode)) ret = __fwnode_property_read_string(fwnode, propname, val);
return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING, if (ret == -EINVAL && fwnode->secondary)
val, 1); ret = __fwnode_property_read_string(fwnode->secondary,
else if (is_pset_node(fwnode)) propname, val);
return pset_prop_read_string(to_pset_node(fwnode), propname, val); return ret;
return -ENXIO;
} }
EXPORT_SYMBOL_GPL(fwnode_property_read_string); EXPORT_SYMBOL_GPL(fwnode_property_read_string);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment