aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/linux/acpi.h4
-rw-r--r--include/linux/fwnode.h54
-rw-r--r--include/linux/of.h2
3 files changed, 60 insertions, 0 deletions
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 137e4a3d89c5..b8f23c521b67 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -56,6 +56,9 @@ static inline acpi_handle acpi_device_handle(struct acpi_device *adev)
acpi_fwnode_handle(adev) : NULL)
#define ACPI_HANDLE(dev) acpi_device_handle(ACPI_COMPANION(dev))
+
+extern const struct fwnode_operations acpi_fwnode_ops;
+
static inline struct fwnode_handle *acpi_alloc_fwnode_static(void)
{
struct fwnode_handle *fwnode;
@@ -65,6 +68,7 @@ static inline struct fwnode_handle *acpi_alloc_fwnode_static(void)
return NULL;
fwnode->type = FWNODE_ACPI_STATIC;
+ fwnode->ops = &acpi_fwnode_ops;
return fwnode;
}
diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h
index 3dff2398a5f0..8f64b3ae9c57 100644
--- a/include/linux/fwnode.h
+++ b/include/linux/fwnode.h
@@ -12,6 +12,8 @@
#ifndef _LINUX_FWNODE_H_
#define _LINUX_FWNODE_H_
+#include <linux/types.h>
+
enum fwnode_type {
FWNODE_INVALID = 0,
FWNODE_OF,
@@ -22,9 +24,12 @@ enum fwnode_type {
FWNODE_IRQCHIP
};
+struct fwnode_operations;
+
struct fwnode_handle {
enum fwnode_type type;
struct fwnode_handle *secondary;
+ const struct fwnode_operations *ops;
};
/**
@@ -39,4 +44,53 @@ struct fwnode_endpoint {
const struct fwnode_handle *local_fwnode;
};
+/**
+ * struct fwnode_operations - Operations for fwnode interface
+ * @get: Get a reference to an fwnode.
+ * @put: Put a reference to an fwnode.
+ * @property_present: Return true if a property is present.
+ * @property_read_integer_array: Read an array of integer properties. Return
+ * zero on success, a negative error code
+ * otherwise.
+ * @property_read_string_array: Read an array of string properties. Return zero
+ * on success, a negative error code otherwise.
+ * @get_parent: Return the parent of an fwnode.
+ * @get_next_child_node: Return the next child node in an iteration.
+ * @get_named_child_node: Return a child node with a given name.
+ */
+struct fwnode_operations {
+ void (*get)(struct fwnode_handle *fwnode);
+ void (*put)(struct fwnode_handle *fwnode);
+ bool (*property_present)(struct fwnode_handle *fwnode,
+ const char *propname);
+ int (*property_read_int_array)(struct fwnode_handle *fwnode,
+ const char *propname,
+ unsigned int elem_size, void *val,
+ size_t nval);
+ int (*property_read_string_array)(struct fwnode_handle *fwnode_handle,
+ const char *propname,
+ const char **val, size_t nval);
+ struct fwnode_handle *(*get_parent)(struct fwnode_handle *fwnode);
+ struct fwnode_handle *
+ (*get_next_child_node)(struct fwnode_handle *fwnode,
+ struct fwnode_handle *child);
+ struct fwnode_handle *
+ (*get_named_child_node)(struct fwnode_handle *fwnode, const char *name);
+};
+
+#define fwnode_has_op(fwnode, op) \
+ ((fwnode) && (fwnode)->ops && (fwnode)->ops->op)
+#define fwnode_call_int_op(fwnode, op, ...) \
+ (fwnode ? (fwnode_has_op(fwnode, op) ? \
+ (fwnode)->ops->op(fwnode, ## __VA_ARGS__) : -ENXIO) : \
+ -EINVAL)
+#define fwnode_call_ptr_op(fwnode, op, ...) \
+ (fwnode_has_op(fwnode, op) ? \
+ (fwnode)->ops->op(fwnode, ## __VA_ARGS__) : NULL)
+#define fwnode_call_void_op(fwnode, op, ...) \
+ do { \
+ if (fwnode_has_op(fwnode, op)) \
+ (fwnode)->ops->op(fwnode, ## __VA_ARGS__); \
+ } while (false)
+
#endif
diff --git a/include/linux/of.h b/include/linux/of.h
index 29b7b738b509..cdbfa88c32cf 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -100,10 +100,12 @@ struct of_reconfig_data {
/* initialize a node */
extern struct kobj_type of_node_ktype;
+extern const struct fwnode_operations of_fwnode_ops;
static inline void of_node_init(struct device_node *node)
{
kobject_init(&node->kobj, &of_node_ktype);
node->fwnode.type = FWNODE_OF;
+ node->fwnode.ops = &of_fwnode_ops;
}
/* true when node is initialized */