Skip to content

Commit

Permalink
device property: Fallback to secondary fwnode if primary misses the p…
Browse files Browse the repository at this point in the history
…roperty

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]>
  • Loading branch information
andy-shev authored and rafaeljw committed Dec 7, 2015
1 parent 3c60f11 commit 362c0b3
Showing 1 changed file with 78 additions and 31 deletions.
109 changes: 78 additions & 31 deletions drivers/base/property.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,12 +214,8 @@ bool device_property_present(struct device *dev, const char *propname)
}
EXPORT_SYMBOL_GPL(device_property_present);

/**
* 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)
static bool __fwnode_property_present(struct fwnode_handle *fwnode,
const char *propname)
{
if (is_of_node(fwnode))
return of_property_read_bool(to_of_node(fwnode), propname);
Expand All @@ -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 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);

/**
Expand Down Expand Up @@ -408,7 +419,7 @@ EXPORT_SYMBOL_GPL(device_property_match_string);
(val) ? pset_prop_read_##type##_array((node), (propname), (val), (nval)) \
: 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_; \
if (is_of_node(_fwnode_)) \
Expand All @@ -425,6 +436,17 @@ EXPORT_SYMBOL_GPL(device_property_match_string);
_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: Firmware node to get the property of
Expand Down Expand Up @@ -529,6 +551,41 @@ int fwnode_property_read_u64_array(struct fwnode_handle *fwnode,
}
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: Firmware node to get the property of
Expand All @@ -551,22 +608,13 @@ 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;
int ret;

ret = __fwnode_property_read_string_array(fwnode, propname, val, nval);
if (ret == -EINVAL && fwnode->secondary)
ret = __fwnode_property_read_string_array(fwnode->secondary,
propname, val, nval);
return ret;
}
EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);

Expand All @@ -588,14 +636,13 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);
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;
int ret;

ret = __fwnode_property_read_string(fwnode, propname, val);
if (ret == -EINVAL && fwnode->secondary)
ret = __fwnode_property_read_string(fwnode->secondary,
propname, val);
return ret;
}
EXPORT_SYMBOL_GPL(fwnode_property_read_string);

Expand Down

0 comments on commit 362c0b3

Please sign in to comment.