From 3708184afc77bb67709a67a35d9f367ebd32cbc4 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 6 Jun 2017 12:37:37 +0300 Subject: device property: Move FW type specific functionality to FW specific files The device and fwnode property API supports Devicetree, ACPI and pset properties. The implementation of this functionality for each firmware type was embedded in the fwnode property core. Move it out to firmware type specific locations, making it easier to maintain. Depends-on: ("of: Move OF property and graph API from base.c to property.c") Signed-off-by: Sakari Ailus Reviewed-by: Mika Westerberg Acked-by: Rob Herring Signed-off-by: Rafael J. Wysocki --- include/linux/acpi.h | 4 ++++ include/linux/fwnode.h | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/of.h | 2 ++ 3 files changed, 60 insertions(+) (limited to 'include/linux') 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 + 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 */ -- cgit v1.2.3 From 3b27d00e7b6d7c889d87fd00df600c495b968e30 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 6 Jun 2017 12:37:38 +0300 Subject: device property: Move fwnode graph ops to firmware specific locations Move firmware specific implementations of the fwnode graph operations to firmware specific locations. Signed-off-by: Sakari Ailus Reviewed-by: Mika Westerberg Acked-by: Rob Herring Signed-off-by: Rafael J. Wysocki --- include/linux/fwnode.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'include/linux') diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h index 8f64b3ae9c57..e315d867d631 100644 --- a/include/linux/fwnode.h +++ b/include/linux/fwnode.h @@ -57,6 +57,11 @@ struct fwnode_endpoint { * @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. + * @graph_get_next_endpoint: Return an endpoint node in an iteration. + * @graph_get_remote_endpoint: Return the remote endpoint node of a local + * endpoint node. + * @graph_get_port_parent: Return the parent node of a port node. + * @graph_parse_endpoint: Parse endpoint for port and endpoint id. */ struct fwnode_operations { void (*get)(struct fwnode_handle *fwnode); @@ -76,6 +81,15 @@ struct fwnode_operations { struct fwnode_handle *child); struct fwnode_handle * (*get_named_child_node)(struct fwnode_handle *fwnode, const char *name); + struct fwnode_handle * + (*graph_get_next_endpoint)(struct fwnode_handle *fwnode, + struct fwnode_handle *prev); + struct fwnode_handle * + (*graph_get_remote_endpoint)(struct fwnode_handle *fwnode); + struct fwnode_handle * + (*graph_get_port_parent)(struct fwnode_handle *fwnode); + int (*graph_parse_endpoint)(struct fwnode_handle *fwnode, + struct fwnode_endpoint *endpoint); }; #define fwnode_has_op(fwnode, op) \ -- cgit v1.2.3 From 2294b3af05e9b3fe0b84a78971e709037bd7593c Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 6 Jun 2017 12:37:39 +0300 Subject: device property: Introduce fwnode_device_is_available() Add fwnode_device_is_available() to tell whether the device corresponding to a certain fwnode_handle is available for use. Signed-off-by: Sakari Ailus Reviewed-by: Mika Westerberg Acked-by: Rob Herring Signed-off-by: Rafael J. Wysocki --- include/linux/fwnode.h | 1 + include/linux/property.h | 1 + 2 files changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h index e315d867d631..9ab375419189 100644 --- a/include/linux/fwnode.h +++ b/include/linux/fwnode.h @@ -66,6 +66,7 @@ struct fwnode_endpoint { struct fwnode_operations { void (*get)(struct fwnode_handle *fwnode); void (*put)(struct fwnode_handle *fwnode); + bool (*device_is_available)(struct fwnode_handle *fwnode); bool (*property_present)(struct fwnode_handle *fwnode, const char *propname); int (*property_read_int_array)(struct fwnode_handle *fwnode, diff --git a/include/linux/property.h b/include/linux/property.h index 2f482616a2f2..7be014af78ed 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -51,6 +51,7 @@ int device_property_read_string(struct device *dev, const char *propname, int device_property_match_string(struct device *dev, const char *propname, const char *string); +bool fwnode_device_is_available(struct fwnode_handle *fwnode); bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname); int fwnode_property_read_u8_array(struct fwnode_handle *fwnode, const char *propname, u8 *val, -- cgit v1.2.3 From 125ee6b3b0fa920c730b0991e6f083a9f5b1e4c3 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 6 Jun 2017 12:37:40 +0300 Subject: device property: Add FW type agnostic fwnode_graph_get_remote_node Add fwnode_graph_get_remote_node() function which is equivalent to of_graph_get_remote_node() on OF. Signed-off-by: Sakari Ailus Reviewed-by: Mika Westerberg Signed-off-by: Rafael J. Wysocki --- include/linux/property.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/property.h b/include/linux/property.h index 7be014af78ed..0597a743aa66 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -281,6 +281,8 @@ struct fwnode_handle *fwnode_graph_get_remote_port( struct fwnode_handle *fwnode); struct fwnode_handle *fwnode_graph_get_remote_endpoint( struct fwnode_handle *fwnode); +struct fwnode_handle *fwnode_graph_get_remote_node(struct fwnode_handle *fwnode, + u32 port, u32 endpoint); int fwnode_graph_parse_endpoint(struct fwnode_handle *fwnode, struct fwnode_endpoint *endpoint); -- cgit v1.2.3 From 6a71d8d77795e0f7d887baa95bfc0d1d2bc74899 Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Tue, 6 Jun 2017 12:37:41 +0300 Subject: device property: Add fwnode_graph_get_port_parent Provide a helper to obtain the parent device fwnode without first parsing the remote-endpoint as per fwnode_graph_get_remote_port_parent. Signed-off-by: Kieran Bingham Signed-off-by: Sakari Ailus Reviewed-by: Mika Westerberg Signed-off-by: Rafael J. Wysocki --- include/linux/property.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/property.h b/include/linux/property.h index 0597a743aa66..7e77039e6b81 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -275,6 +275,8 @@ void *device_get_mac_address(struct device *dev, char *addr, int alen); struct fwnode_handle *fwnode_graph_get_next_endpoint( struct fwnode_handle *fwnode, struct fwnode_handle *prev); +struct fwnode_handle * +fwnode_graph_get_port_parent(struct fwnode_handle *fwnode); struct fwnode_handle *fwnode_graph_get_remote_port_parent( struct fwnode_handle *fwnode); struct fwnode_handle *fwnode_graph_get_remote_port( -- cgit v1.2.3