|
@@ -187,6 +187,50 @@ struct fwnode_handle *dev_fwnode(struct device *dev)
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(dev_fwnode);
|
|
EXPORT_SYMBOL_GPL(dev_fwnode);
|
|
|
|
|
|
|
|
+static bool pset_fwnode_property_present(struct fwnode_handle *fwnode,
|
|
|
|
+ const char *propname)
|
|
|
|
+{
|
|
|
|
+ return !!pset_prop_get(to_pset_node(fwnode), propname);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int pset_fwnode_read_int_array(struct fwnode_handle *fwnode,
|
|
|
|
+ const char *propname,
|
|
|
|
+ unsigned int elem_size, void *val,
|
|
|
|
+ size_t nval)
|
|
|
|
+{
|
|
|
|
+ struct property_set *node = to_pset_node(fwnode);
|
|
|
|
+
|
|
|
|
+ if (!val)
|
|
|
|
+ return pset_prop_count_elems_of_size(node, propname, elem_size);
|
|
|
|
+
|
|
|
|
+ switch (elem_size) {
|
|
|
|
+ case sizeof(u8):
|
|
|
|
+ return pset_prop_read_u8_array(node, propname, val, nval);
|
|
|
|
+ case sizeof(u16):
|
|
|
|
+ return pset_prop_read_u16_array(node, propname, val, nval);
|
|
|
|
+ case sizeof(u32):
|
|
|
|
+ return pset_prop_read_u32_array(node, propname, val, nval);
|
|
|
|
+ case sizeof(u64):
|
|
|
|
+ return pset_prop_read_u64_array(node, propname, val, nval);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return -ENXIO;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int pset_fwnode_property_read_string_array(struct fwnode_handle *fwnode,
|
|
|
|
+ const char *propname,
|
|
|
|
+ const char **val, size_t nval)
|
|
|
|
+{
|
|
|
|
+ return pset_prop_read_string_array(to_pset_node(fwnode), propname,
|
|
|
|
+ val, nval);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static const struct fwnode_operations pset_fwnode_ops = {
|
|
|
|
+ .property_present = pset_fwnode_property_present,
|
|
|
|
+ .property_read_int_array = pset_fwnode_read_int_array,
|
|
|
|
+ .property_read_string_array = pset_fwnode_property_read_string_array,
|
|
|
|
+};
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* device_property_present - check if a property of a device is present
|
|
* device_property_present - check if a property of a device is present
|
|
* @dev: Device whose property is being checked
|
|
* @dev: Device whose property is being checked
|
|
@@ -200,18 +244,6 @@ 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,
|
|
|
|
- const char *propname)
|
|
|
|
-{
|
|
|
|
- if (is_of_node(fwnode))
|
|
|
|
- return of_property_read_bool(to_of_node(fwnode), propname);
|
|
|
|
- else if (is_acpi_node(fwnode))
|
|
|
|
- return !acpi_node_prop_get(fwnode, propname, NULL);
|
|
|
|
- else if (is_pset_node(fwnode))
|
|
|
|
- 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_property_present - check if a property of a firmware node is present
|
|
* @fwnode: Firmware node whose property to check
|
|
* @fwnode: Firmware node whose property to check
|
|
@@ -221,10 +253,11 @@ bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname)
|
|
{
|
|
{
|
|
bool ret;
|
|
bool ret;
|
|
|
|
|
|
- ret = __fwnode_property_present(fwnode, propname);
|
|
|
|
|
|
+ ret = fwnode_call_int_op(fwnode, property_present, propname);
|
|
if (ret == false && !IS_ERR_OR_NULL(fwnode) &&
|
|
if (ret == false && !IS_ERR_OR_NULL(fwnode) &&
|
|
!IS_ERR_OR_NULL(fwnode->secondary))
|
|
!IS_ERR_OR_NULL(fwnode->secondary))
|
|
- ret = __fwnode_property_present(fwnode->secondary, propname);
|
|
|
|
|
|
+ ret = fwnode_call_int_op(fwnode->secondary, property_present,
|
|
|
|
+ propname);
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(fwnode_property_present);
|
|
EXPORT_SYMBOL_GPL(fwnode_property_present);
|
|
@@ -398,42 +431,23 @@ int device_property_match_string(struct device *dev, const char *propname,
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(device_property_match_string);
|
|
EXPORT_SYMBOL_GPL(device_property_match_string);
|
|
|
|
|
|
-#define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \
|
|
|
|
- (val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \
|
|
|
|
- : of_property_count_elems_of_size((node), (propname), sizeof(type))
|
|
|
|
-
|
|
|
|
-#define PSET_PROP_READ_ARRAY(node, propname, type, val, nval) \
|
|
|
|
- (val) ? pset_prop_read_##type##_array((node), (propname), (val), (nval)) \
|
|
|
|
- : pset_prop_count_elems_of_size((node), (propname), sizeof(type))
|
|
|
|
-
|
|
|
|
-#define FWNODE_PROP_READ(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \
|
|
|
|
-({ \
|
|
|
|
- int _ret_; \
|
|
|
|
- if (is_of_node(_fwnode_)) \
|
|
|
|
- _ret_ = OF_DEV_PROP_READ_ARRAY(to_of_node(_fwnode_), _propname_, \
|
|
|
|
- _type_, _val_, _nval_); \
|
|
|
|
- else if (is_acpi_node(_fwnode_)) \
|
|
|
|
- _ret_ = acpi_node_prop_read(_fwnode_, _propname_, _proptype_, \
|
|
|
|
- _val_, _nval_); \
|
|
|
|
- else if (is_pset_node(_fwnode_)) \
|
|
|
|
- _ret_ = PSET_PROP_READ_ARRAY(to_pset_node(_fwnode_), _propname_, \
|
|
|
|
- _type_, _val_, _nval_); \
|
|
|
|
- else \
|
|
|
|
- _ret_ = -ENXIO; \
|
|
|
|
- _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 && !IS_ERR_OR_NULL(_fwnode_) && \
|
|
|
|
- !IS_ERR_OR_NULL(_fwnode_->secondary)) \
|
|
|
|
- _ret_ = FWNODE_PROP_READ(_fwnode_->secondary, _propname_, _type_, \
|
|
|
|
- _proptype_, _val_, _nval_); \
|
|
|
|
- _ret_; \
|
|
|
|
-})
|
|
|
|
|
|
+static int fwnode_property_read_int_array(struct fwnode_handle *fwnode,
|
|
|
|
+ const char *propname,
|
|
|
|
+ unsigned int elem_size, void *val,
|
|
|
|
+ size_t nval)
|
|
|
|
+{
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ ret = fwnode_call_int_op(fwnode, property_read_int_array, propname,
|
|
|
|
+ elem_size, val, nval);
|
|
|
|
+ if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode) &&
|
|
|
|
+ !IS_ERR_OR_NULL(fwnode->secondary))
|
|
|
|
+ ret = fwnode_call_int_op(
|
|
|
|
+ fwnode->secondary, property_read_int_array, propname,
|
|
|
|
+ elem_size, val, nval);
|
|
|
|
+
|
|
|
|
+ return 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
|
|
@@ -456,8 +470,8 @@ EXPORT_SYMBOL_GPL(device_property_match_string);
|
|
int fwnode_property_read_u8_array(struct fwnode_handle *fwnode,
|
|
int fwnode_property_read_u8_array(struct fwnode_handle *fwnode,
|
|
const char *propname, u8 *val, size_t nval)
|
|
const char *propname, u8 *val, size_t nval)
|
|
{
|
|
{
|
|
- return FWNODE_PROP_READ_ARRAY(fwnode, propname, u8, DEV_PROP_U8,
|
|
|
|
- val, nval);
|
|
|
|
|
|
+ return fwnode_property_read_int_array(fwnode, propname, sizeof(u8),
|
|
|
|
+ val, nval);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(fwnode_property_read_u8_array);
|
|
EXPORT_SYMBOL_GPL(fwnode_property_read_u8_array);
|
|
|
|
|
|
@@ -482,8 +496,8 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_u8_array);
|
|
int fwnode_property_read_u16_array(struct fwnode_handle *fwnode,
|
|
int fwnode_property_read_u16_array(struct fwnode_handle *fwnode,
|
|
const char *propname, u16 *val, size_t nval)
|
|
const char *propname, u16 *val, size_t nval)
|
|
{
|
|
{
|
|
- return FWNODE_PROP_READ_ARRAY(fwnode, propname, u16, DEV_PROP_U16,
|
|
|
|
- val, nval);
|
|
|
|
|
|
+ return fwnode_property_read_int_array(fwnode, propname, sizeof(u16),
|
|
|
|
+ val, nval);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(fwnode_property_read_u16_array);
|
|
EXPORT_SYMBOL_GPL(fwnode_property_read_u16_array);
|
|
|
|
|
|
@@ -508,8 +522,8 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_u16_array);
|
|
int fwnode_property_read_u32_array(struct fwnode_handle *fwnode,
|
|
int fwnode_property_read_u32_array(struct fwnode_handle *fwnode,
|
|
const char *propname, u32 *val, size_t nval)
|
|
const char *propname, u32 *val, size_t nval)
|
|
{
|
|
{
|
|
- return FWNODE_PROP_READ_ARRAY(fwnode, propname, u32, DEV_PROP_U32,
|
|
|
|
- val, nval);
|
|
|
|
|
|
+ return fwnode_property_read_int_array(fwnode, propname, sizeof(u32),
|
|
|
|
+ val, nval);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(fwnode_property_read_u32_array);
|
|
EXPORT_SYMBOL_GPL(fwnode_property_read_u32_array);
|
|
|
|
|
|
@@ -534,29 +548,11 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_u32_array);
|
|
int fwnode_property_read_u64_array(struct fwnode_handle *fwnode,
|
|
int fwnode_property_read_u64_array(struct fwnode_handle *fwnode,
|
|
const char *propname, u64 *val, size_t nval)
|
|
const char *propname, u64 *val, size_t nval)
|
|
{
|
|
{
|
|
- return FWNODE_PROP_READ_ARRAY(fwnode, propname, u64, DEV_PROP_U64,
|
|
|
|
- val, nval);
|
|
|
|
|
|
+ return fwnode_property_read_int_array(fwnode, propname, sizeof(u64),
|
|
|
|
+ val, nval);
|
|
}
|
|
}
|
|
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 pset_prop_read_string_array(to_pset_node(fwnode),
|
|
|
|
- propname, val, nval);
|
|
|
|
- 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
|
|
@@ -581,11 +577,13 @@ int fwnode_property_read_string_array(struct fwnode_handle *fwnode,
|
|
{
|
|
{
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
- ret = __fwnode_property_read_string_array(fwnode, propname, val, nval);
|
|
|
|
|
|
+ ret = fwnode_call_int_op(fwnode, property_read_string_array, propname,
|
|
|
|
+ val, nval);
|
|
if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode) &&
|
|
if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode) &&
|
|
!IS_ERR_OR_NULL(fwnode->secondary))
|
|
!IS_ERR_OR_NULL(fwnode->secondary))
|
|
- ret = __fwnode_property_read_string_array(fwnode->secondary,
|
|
|
|
- propname, val, nval);
|
|
|
|
|
|
+ ret = fwnode_call_int_op(fwnode->secondary,
|
|
|
|
+ property_read_string_array, propname,
|
|
|
|
+ val, nval);
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);
|
|
EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);
|
|
@@ -903,6 +901,7 @@ int device_add_properties(struct device *dev,
|
|
return PTR_ERR(p);
|
|
return PTR_ERR(p);
|
|
|
|
|
|
p->fwnode.type = FWNODE_PDATA;
|
|
p->fwnode.type = FWNODE_PDATA;
|
|
|
|
+ p->fwnode.ops = &pset_fwnode_ops;
|
|
set_secondary_fwnode(dev, &p->fwnode);
|
|
set_secondary_fwnode(dev, &p->fwnode);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -938,19 +937,7 @@ EXPORT_SYMBOL_GPL(fwnode_get_next_parent);
|
|
*/
|
|
*/
|
|
struct fwnode_handle *fwnode_get_parent(struct fwnode_handle *fwnode)
|
|
struct fwnode_handle *fwnode_get_parent(struct fwnode_handle *fwnode)
|
|
{
|
|
{
|
|
- struct fwnode_handle *parent = NULL;
|
|
|
|
-
|
|
|
|
- if (is_of_node(fwnode)) {
|
|
|
|
- struct device_node *node;
|
|
|
|
-
|
|
|
|
- node = of_get_parent(to_of_node(fwnode));
|
|
|
|
- if (node)
|
|
|
|
- parent = &node->fwnode;
|
|
|
|
- } else if (is_acpi_node(fwnode)) {
|
|
|
|
- parent = acpi_node_get_parent(fwnode);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return parent;
|
|
|
|
|
|
+ return fwnode_call_ptr_op(fwnode, get_parent);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(fwnode_get_parent);
|
|
EXPORT_SYMBOL_GPL(fwnode_get_parent);
|
|
|
|
|
|
@@ -962,18 +949,7 @@ EXPORT_SYMBOL_GPL(fwnode_get_parent);
|
|
struct fwnode_handle *fwnode_get_next_child_node(struct fwnode_handle *fwnode,
|
|
struct fwnode_handle *fwnode_get_next_child_node(struct fwnode_handle *fwnode,
|
|
struct fwnode_handle *child)
|
|
struct fwnode_handle *child)
|
|
{
|
|
{
|
|
- if (is_of_node(fwnode)) {
|
|
|
|
- struct device_node *node;
|
|
|
|
-
|
|
|
|
- node = of_get_next_available_child(to_of_node(fwnode),
|
|
|
|
- to_of_node(child));
|
|
|
|
- if (node)
|
|
|
|
- return &node->fwnode;
|
|
|
|
- } else if (is_acpi_node(fwnode)) {
|
|
|
|
- return acpi_get_next_subnode(fwnode, child);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return NULL;
|
|
|
|
|
|
+ return fwnode_call_ptr_op(fwnode, get_next_child_node, child);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(fwnode_get_next_child_node);
|
|
EXPORT_SYMBOL_GPL(fwnode_get_next_child_node);
|
|
|
|
|
|
@@ -1005,23 +981,7 @@ EXPORT_SYMBOL_GPL(device_get_next_child_node);
|
|
struct fwnode_handle *fwnode_get_named_child_node(struct fwnode_handle *fwnode,
|
|
struct fwnode_handle *fwnode_get_named_child_node(struct fwnode_handle *fwnode,
|
|
const char *childname)
|
|
const char *childname)
|
|
{
|
|
{
|
|
- struct fwnode_handle *child;
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * Find first matching named child node of this fwnode.
|
|
|
|
- * For ACPI this will be a data only sub-node.
|
|
|
|
- */
|
|
|
|
- fwnode_for_each_child_node(fwnode, child) {
|
|
|
|
- if (is_of_node(child)) {
|
|
|
|
- if (!of_node_cmp(to_of_node(child)->name, childname))
|
|
|
|
- return child;
|
|
|
|
- } else if (is_acpi_data_node(child)) {
|
|
|
|
- if (acpi_data_node_match(child, childname))
|
|
|
|
- return child;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return NULL;
|
|
|
|
|
|
+ return fwnode_call_ptr_op(fwnode, get_named_child_node, childname);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(fwnode_get_named_child_node);
|
|
EXPORT_SYMBOL_GPL(fwnode_get_named_child_node);
|
|
|
|
|
|
@@ -1043,8 +1003,7 @@ EXPORT_SYMBOL_GPL(device_get_named_child_node);
|
|
*/
|
|
*/
|
|
void fwnode_handle_get(struct fwnode_handle *fwnode)
|
|
void fwnode_handle_get(struct fwnode_handle *fwnode)
|
|
{
|
|
{
|
|
- if (is_of_node(fwnode))
|
|
|
|
- of_node_get(to_of_node(fwnode));
|
|
|
|
|
|
+ fwnode_call_void_op(fwnode, get);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(fwnode_handle_get);
|
|
EXPORT_SYMBOL_GPL(fwnode_handle_get);
|
|
|
|
|
|
@@ -1058,8 +1017,7 @@ EXPORT_SYMBOL_GPL(fwnode_handle_get);
|
|
*/
|
|
*/
|
|
void fwnode_handle_put(struct fwnode_handle *fwnode)
|
|
void fwnode_handle_put(struct fwnode_handle *fwnode)
|
|
{
|
|
{
|
|
- if (is_of_node(fwnode))
|
|
|
|
- of_node_put(to_of_node(fwnode));
|
|
|
|
|
|
+ fwnode_call_void_op(fwnode, put);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(fwnode_handle_put);
|
|
EXPORT_SYMBOL_GPL(fwnode_handle_put);
|
|
|
|
|