Commit 268db333 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'devprop-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull device properties framework updates from Rafael Wysocki:
 "These mostly extend the device property API and make it easier to use
  in some cases.

  Specifics:

   - Allow error pointer to be passed to fwnode APIs (Andy Shevchenko).

   - Introduce fwnode_for_each_parent_node() (Andy Shevchenko, Douglas
     Anderson).

   - Advertise fwnode and device property count API calls (Andy
     Shevchenko).

   - Clean up fwnode_is_ancestor_of() (Andy Shevchenko).

   - Convert device_{dma_supported,get_dma_attr} to fwnode (Sakari
     Ailus).

   - Release subnode properties with data nodes (Sakari Ailus).

   - Add ->iomap() and ->irq_get() to fwnode operations (Sakari Ailus)"

* tag 'devprop-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  device property: Advertise fwnode and device property count API calls
  device property: Fix recent breakage of fwnode_get_next_parent_dev()
  device property: Drop 'test' prefix in parameters of fwnode_is_ancestor_of()
  device property: Introduce fwnode_for_each_parent_node()
  device property: Allow error pointer to be passed to fwnode APIs
  ACPI: property: Release subnode properties with data nodes
  device property: Add irq_get to fwnode operation
  device property: Add iomap to fwnode operations
  ACPI: property: Move acpi_fwnode_device_get_match_data() up
  device property: Convert device_{dma_supported,get_dma_attr} to fwnode
parents f4fb8596 f6e109a0
...@@ -433,6 +433,16 @@ void acpi_init_properties(struct acpi_device *adev) ...@@ -433,6 +433,16 @@ void acpi_init_properties(struct acpi_device *adev)
acpi_extract_apple_properties(adev); acpi_extract_apple_properties(adev);
} }
static void acpi_free_device_properties(struct list_head *list)
{
struct acpi_device_properties *props, *tmp;
list_for_each_entry_safe(props, tmp, list, list) {
list_del(&props->list);
kfree(props);
}
}
static void acpi_destroy_nondev_subnodes(struct list_head *list) static void acpi_destroy_nondev_subnodes(struct list_head *list)
{ {
struct acpi_data_node *dn, *next; struct acpi_data_node *dn, *next;
...@@ -445,22 +455,18 @@ static void acpi_destroy_nondev_subnodes(struct list_head *list) ...@@ -445,22 +455,18 @@ static void acpi_destroy_nondev_subnodes(struct list_head *list)
wait_for_completion(&dn->kobj_done); wait_for_completion(&dn->kobj_done);
list_del(&dn->sibling); list_del(&dn->sibling);
ACPI_FREE((void *)dn->data.pointer); ACPI_FREE((void *)dn->data.pointer);
acpi_free_device_properties(&dn->data.properties);
kfree(dn); kfree(dn);
} }
} }
void acpi_free_properties(struct acpi_device *adev) void acpi_free_properties(struct acpi_device *adev)
{ {
struct acpi_device_properties *props, *tmp;
acpi_destroy_nondev_subnodes(&adev->data.subnodes); acpi_destroy_nondev_subnodes(&adev->data.subnodes);
ACPI_FREE((void *)adev->data.pointer); ACPI_FREE((void *)adev->data.pointer);
adev->data.of_compatible = NULL; adev->data.of_compatible = NULL;
adev->data.pointer = NULL; adev->data.pointer = NULL;
list_for_each_entry_safe(props, tmp, &adev->data.properties, list) { acpi_free_device_properties(&adev->data.properties);
list_del(&props->list);
kfree(props);
}
} }
/** /**
...@@ -1256,6 +1262,24 @@ static bool acpi_fwnode_device_is_available(const struct fwnode_handle *fwnode) ...@@ -1256,6 +1262,24 @@ static bool acpi_fwnode_device_is_available(const struct fwnode_handle *fwnode)
return acpi_device_is_present(to_acpi_device_node(fwnode)); return acpi_device_is_present(to_acpi_device_node(fwnode));
} }
static const void *
acpi_fwnode_device_get_match_data(const struct fwnode_handle *fwnode,
const struct device *dev)
{
return acpi_device_get_match_data(dev);
}
static bool acpi_fwnode_device_dma_supported(const struct fwnode_handle *fwnode)
{
return acpi_dma_supported(to_acpi_device_node(fwnode));
}
static enum dev_dma_attr
acpi_fwnode_device_get_dma_attr(const struct fwnode_handle *fwnode)
{
return acpi_get_dma_attr(to_acpi_device_node(fwnode));
}
static bool acpi_fwnode_property_present(const struct fwnode_handle *fwnode, static bool acpi_fwnode_property_present(const struct fwnode_handle *fwnode,
const char *propname) const char *propname)
{ {
...@@ -1376,17 +1400,26 @@ static int acpi_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode, ...@@ -1376,17 +1400,26 @@ static int acpi_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
return 0; return 0;
} }
static const void * static int acpi_fwnode_irq_get(const struct fwnode_handle *fwnode,
acpi_fwnode_device_get_match_data(const struct fwnode_handle *fwnode, unsigned int index)
const struct device *dev)
{ {
return acpi_device_get_match_data(dev); struct resource res;
int ret;
ret = acpi_irq_get(ACPI_HANDLE_FWNODE(fwnode), index, &res);
if (ret)
return ret;
return res.start;
} }
#define DECLARE_ACPI_FWNODE_OPS(ops) \ #define DECLARE_ACPI_FWNODE_OPS(ops) \
const struct fwnode_operations ops = { \ const struct fwnode_operations ops = { \
.device_is_available = acpi_fwnode_device_is_available, \ .device_is_available = acpi_fwnode_device_is_available, \
.device_get_match_data = acpi_fwnode_device_get_match_data, \ .device_get_match_data = acpi_fwnode_device_get_match_data, \
.device_dma_supported = \
acpi_fwnode_device_dma_supported, \
.device_get_dma_attr = acpi_fwnode_device_get_dma_attr, \
.property_present = acpi_fwnode_property_present, \ .property_present = acpi_fwnode_property_present, \
.property_read_int_array = \ .property_read_int_array = \
acpi_fwnode_property_read_int_array, \ acpi_fwnode_property_read_int_array, \
...@@ -1404,6 +1437,7 @@ acpi_fwnode_device_get_match_data(const struct fwnode_handle *fwnode, ...@@ -1404,6 +1437,7 @@ acpi_fwnode_device_get_match_data(const struct fwnode_handle *fwnode,
acpi_graph_get_remote_endpoint, \ acpi_graph_get_remote_endpoint, \
.graph_get_port_parent = acpi_fwnode_get_parent, \ .graph_get_port_parent = acpi_fwnode_get_parent, \
.graph_parse_endpoint = acpi_fwnode_graph_parse_endpoint, \ .graph_parse_endpoint = acpi_fwnode_graph_parse_endpoint, \
.irq_get = acpi_fwnode_irq_get, \
}; \ }; \
EXPORT_SYMBOL_GPL(ops) EXPORT_SYMBOL_GPL(ops)
......
This diff is collapsed.
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#define pr_fmt(fmt) "OF: " fmt #define pr_fmt(fmt) "OF: " fmt
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/of_graph.h> #include <linux/of_graph.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
...@@ -872,6 +873,20 @@ static bool of_fwnode_device_is_available(const struct fwnode_handle *fwnode) ...@@ -872,6 +873,20 @@ static bool of_fwnode_device_is_available(const struct fwnode_handle *fwnode)
return of_device_is_available(to_of_node(fwnode)); return of_device_is_available(to_of_node(fwnode));
} }
static bool of_fwnode_device_dma_supported(const struct fwnode_handle *fwnode)
{
return true;
}
static enum dev_dma_attr
of_fwnode_device_get_dma_attr(const struct fwnode_handle *fwnode)
{
if (of_dma_is_coherent(to_of_node(fwnode)))
return DEV_DMA_COHERENT;
else
return DEV_DMA_NON_COHERENT;
}
static bool of_fwnode_property_present(const struct fwnode_handle *fwnode, static bool of_fwnode_property_present(const struct fwnode_handle *fwnode,
const char *propname) const char *propname)
{ {
...@@ -1450,6 +1465,21 @@ static int of_link_property(struct device_node *con_np, const char *prop_name) ...@@ -1450,6 +1465,21 @@ static int of_link_property(struct device_node *con_np, const char *prop_name)
return 0; return 0;
} }
static void __iomem *of_fwnode_iomap(struct fwnode_handle *fwnode, int index)
{
#ifdef CONFIG_OF_ADDRESS
return of_iomap(to_of_node(fwnode), index);
#else
return NULL;
#endif
}
static int of_fwnode_irq_get(const struct fwnode_handle *fwnode,
unsigned int index)
{
return of_irq_get(to_of_node(fwnode), index);
}
static int of_fwnode_add_links(struct fwnode_handle *fwnode) static int of_fwnode_add_links(struct fwnode_handle *fwnode)
{ {
struct property *p; struct property *p;
...@@ -1472,6 +1502,8 @@ const struct fwnode_operations of_fwnode_ops = { ...@@ -1472,6 +1502,8 @@ const struct fwnode_operations of_fwnode_ops = {
.put = of_fwnode_put, .put = of_fwnode_put,
.device_is_available = of_fwnode_device_is_available, .device_is_available = of_fwnode_device_is_available,
.device_get_match_data = of_fwnode_device_get_match_data, .device_get_match_data = of_fwnode_device_get_match_data,
.device_dma_supported = of_fwnode_device_dma_supported,
.device_get_dma_attr = of_fwnode_device_get_dma_attr,
.property_present = of_fwnode_property_present, .property_present = of_fwnode_property_present,
.property_read_int_array = of_fwnode_property_read_int_array, .property_read_int_array = of_fwnode_property_read_int_array,
.property_read_string_array = of_fwnode_property_read_string_array, .property_read_string_array = of_fwnode_property_read_string_array,
...@@ -1485,6 +1517,8 @@ const struct fwnode_operations of_fwnode_ops = { ...@@ -1485,6 +1517,8 @@ const struct fwnode_operations of_fwnode_ops = {
.graph_get_remote_endpoint = of_fwnode_graph_get_remote_endpoint, .graph_get_remote_endpoint = of_fwnode_graph_get_remote_endpoint,
.graph_get_port_parent = of_fwnode_graph_get_port_parent, .graph_get_port_parent = of_fwnode_graph_get_port_parent,
.graph_parse_endpoint = of_fwnode_graph_parse_endpoint, .graph_parse_endpoint = of_fwnode_graph_parse_endpoint,
.iomap = of_fwnode_iomap,
.irq_get = of_fwnode_irq_get,
.add_links = of_fwnode_add_links, .add_links = of_fwnode_add_links,
}; };
EXPORT_SYMBOL_GPL(of_fwnode_ops); EXPORT_SYMBOL_GPL(of_fwnode_ops);
...@@ -113,6 +113,9 @@ struct fwnode_operations { ...@@ -113,6 +113,9 @@ struct fwnode_operations {
bool (*device_is_available)(const struct fwnode_handle *fwnode); bool (*device_is_available)(const struct fwnode_handle *fwnode);
const void *(*device_get_match_data)(const struct fwnode_handle *fwnode, const void *(*device_get_match_data)(const struct fwnode_handle *fwnode,
const struct device *dev); const struct device *dev);
bool (*device_dma_supported)(const struct fwnode_handle *fwnode);
enum dev_dma_attr
(*device_get_dma_attr)(const struct fwnode_handle *fwnode);
bool (*property_present)(const struct fwnode_handle *fwnode, bool (*property_present)(const struct fwnode_handle *fwnode,
const char *propname); const char *propname);
int (*property_read_int_array)(const struct fwnode_handle *fwnode, int (*property_read_int_array)(const struct fwnode_handle *fwnode,
...@@ -145,15 +148,17 @@ struct fwnode_operations { ...@@ -145,15 +148,17 @@ struct fwnode_operations {
(*graph_get_port_parent)(struct fwnode_handle *fwnode); (*graph_get_port_parent)(struct fwnode_handle *fwnode);
int (*graph_parse_endpoint)(const struct fwnode_handle *fwnode, int (*graph_parse_endpoint)(const struct fwnode_handle *fwnode,
struct fwnode_endpoint *endpoint); struct fwnode_endpoint *endpoint);
void __iomem *(*iomap)(struct fwnode_handle *fwnode, int index);
int (*irq_get)(const struct fwnode_handle *fwnode, unsigned int index);
int (*add_links)(struct fwnode_handle *fwnode); int (*add_links)(struct fwnode_handle *fwnode);
}; };
#define fwnode_has_op(fwnode, op) \ #define fwnode_has_op(fwnode, op) \
((fwnode) && (fwnode)->ops && (fwnode)->ops->op) (!IS_ERR_OR_NULL(fwnode) && (fwnode)->ops && (fwnode)->ops->op)
#define fwnode_call_int_op(fwnode, op, ...) \ #define fwnode_call_int_op(fwnode, op, ...) \
(fwnode ? (fwnode_has_op(fwnode, op) ? \ (fwnode_has_op(fwnode, op) ? \
(fwnode)->ops->op(fwnode, ## __VA_ARGS__) : -ENXIO) : \ (fwnode)->ops->op(fwnode, ## __VA_ARGS__) : (IS_ERR_OR_NULL(fwnode) ? -EINVAL : -ENXIO))
-EINVAL)
#define fwnode_call_bool_op(fwnode, op, ...) \ #define fwnode_call_bool_op(fwnode, op, ...) \
(fwnode_has_op(fwnode, op) ? \ (fwnode_has_op(fwnode, op) ? \
......
...@@ -83,15 +83,19 @@ struct fwnode_handle *fwnode_find_reference(const struct fwnode_handle *fwnode, ...@@ -83,15 +83,19 @@ struct fwnode_handle *fwnode_find_reference(const struct fwnode_handle *fwnode,
const char *fwnode_get_name(const struct fwnode_handle *fwnode); const char *fwnode_get_name(const struct fwnode_handle *fwnode);
const char *fwnode_get_name_prefix(const struct fwnode_handle *fwnode); const char *fwnode_get_name_prefix(const struct fwnode_handle *fwnode);
struct fwnode_handle *fwnode_get_parent(const struct fwnode_handle *fwnode); struct fwnode_handle *fwnode_get_parent(const struct fwnode_handle *fwnode);
struct fwnode_handle *fwnode_get_next_parent( struct fwnode_handle *fwnode_get_next_parent(struct fwnode_handle *fwnode);
struct fwnode_handle *fwnode);
#define fwnode_for_each_parent_node(fwnode, parent) \
for (parent = fwnode_get_parent(fwnode); parent; \
parent = fwnode_get_next_parent(parent))
struct device *fwnode_get_next_parent_dev(struct fwnode_handle *fwnode); struct device *fwnode_get_next_parent_dev(struct fwnode_handle *fwnode);
unsigned int fwnode_count_parents(const struct fwnode_handle *fwn); unsigned int fwnode_count_parents(const struct fwnode_handle *fwn);
struct fwnode_handle *fwnode_get_nth_parent(struct fwnode_handle *fwn, struct fwnode_handle *fwnode_get_nth_parent(struct fwnode_handle *fwn,
unsigned int depth); unsigned int depth);
bool fwnode_is_ancestor_of(struct fwnode_handle *test_ancestor, bool fwnode_is_ancestor_of(struct fwnode_handle *ancestor, struct fwnode_handle *child);
struct fwnode_handle *test_child);
struct fwnode_handle *fwnode_get_next_child_node( struct fwnode_handle *fwnode_get_next_child_node(
const struct fwnode_handle *fwnode, struct fwnode_handle *child); const struct fwnode_handle *fwnode, struct fwnode_handle *child);
struct fwnode_handle *fwnode_get_next_available_child_node( struct fwnode_handle *fwnode_get_next_available_child_node(
......
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