summaryrefslogtreecommitdiff
path: root/drivers/of/of_reserved_mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/of/of_reserved_mem.c')
-rw-r--r--drivers/of/of_reserved_mem.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 1a84bc0d5fa8..f61e8739502a 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -358,6 +358,25 @@ int of_reserved_mem_device_init_by_idx(struct device *dev,
EXPORT_SYMBOL_GPL(of_reserved_mem_device_init_by_idx);
/**
+ * of_reserved_mem_device_init_by_name() - assign named reserved memory region
+ * to given device
+ * @dev: pointer to the device to configure
+ * @np: pointer to the device node with 'memory-region' property
+ * @name: name of the selected memory region
+ *
+ * Returns: 0 on success or a negative error-code on failure.
+ */
+int of_reserved_mem_device_init_by_name(struct device *dev,
+ struct device_node *np,
+ const char *name)
+{
+ int idx = of_property_match_string(np, "memory-region-names", name);
+
+ return of_reserved_mem_device_init_by_idx(dev, np, idx);
+}
+EXPORT_SYMBOL_GPL(of_reserved_mem_device_init_by_name);
+
+/**
* of_reserved_mem_device_release() - release reserved memory device structures
* @dev: Pointer to the device to deconfigure
*
@@ -366,24 +385,22 @@ EXPORT_SYMBOL_GPL(of_reserved_mem_device_init_by_idx);
*/
void of_reserved_mem_device_release(struct device *dev)
{
- struct rmem_assigned_device *rd;
- struct reserved_mem *rmem = NULL;
+ struct rmem_assigned_device *rd, *tmp;
+ LIST_HEAD(release_list);
mutex_lock(&of_rmem_assigned_device_mutex);
- list_for_each_entry(rd, &of_rmem_assigned_device_list, list) {
- if (rd->dev == dev) {
- rmem = rd->rmem;
- list_del(&rd->list);
- kfree(rd);
- break;
- }
+ list_for_each_entry_safe(rd, tmp, &of_rmem_assigned_device_list, list) {
+ if (rd->dev == dev)
+ list_move_tail(&rd->list, &release_list);
}
mutex_unlock(&of_rmem_assigned_device_mutex);
- if (!rmem || !rmem->ops || !rmem->ops->device_release)
- return;
+ list_for_each_entry_safe(rd, tmp, &release_list, list) {
+ if (rd->rmem && rd->rmem->ops && rd->rmem->ops->device_release)
+ rd->rmem->ops->device_release(rd->rmem, dev);
- rmem->ops->device_release(rmem, dev);
+ kfree(rd);
+ }
}
EXPORT_SYMBOL_GPL(of_reserved_mem_device_release);