]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
of: reserved-memory: Support multiple regions per device
authorThierry Reding <treding@nvidia.com>
Fri, 3 Apr 2020 17:46:57 +0000 (19:46 +0200)
committerThierry Reding <treding@nvidia.com>
Thu, 30 Apr 2020 10:39:16 +0000 (12:39 +0200)
While the lookup/initialization code already supports multiple memory
regions per device, the release code will only ever release the first
matching memory region.

Enhance the code to release all matching regions. Each attachment of
a region to a device is uniquely identifiable using a struct device
pointer and a pointer to the memory region's struct reserved_mem.

Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Thierry Reding <treding@nvidia.com>
drivers/of/of_reserved_mem.c

index ed2ff6f01d3281d3a8a949d6e92a1952d0b66f0f..f61e8739502a8ab4a5dadeaaa554e92639052455 100644 (file)
@@ -385,24 +385,22 @@ EXPORT_SYMBOL_GPL(of_reserved_mem_device_init_by_name);
  */
 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);