Merge tag 'backlight-next-4.20' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux] / kernel / resource.c
index 30e1bc6..b3a3a1f 100644 (file)
@@ -318,33 +318,34 @@ int release_resource(struct resource *old)
 
 EXPORT_SYMBOL(release_resource);
 
-/*
- * Finds the lowest iomem resource existing within [res->start.res->end).
- * The caller must specify res->start, res->end, res->flags, and optionally
- * desc.  If found, returns 0, res is overwritten, if not found, returns -1.
- * This function walks the whole tree and not just first level children until
- * and unless first_level_children_only is true.
+/**
+ * Finds the lowest iomem resource that covers part of [start..end].  The
+ * caller must specify start, end, flags, and desc (which may be
+ * IORES_DESC_NONE).
+ *
+ * If a resource is found, returns 0 and *res is overwritten with the part
+ * of the resource that's within [start..end]; if none is found, returns
+ * -1.
+ *
+ * This function walks the whole tree and not just first level children
+ * unless @first_lvl is true.
  */
-static int find_next_iomem_res(struct resource *res, unsigned long desc,
-                              bool first_level_children_only)
+static int find_next_iomem_res(resource_size_t start, resource_size_t end,
+                              unsigned long flags, unsigned long desc,
+                              bool first_lvl, struct resource *res)
 {
-       resource_size_t start, end;
        struct resource *p;
-       bool sibling_only = false;
 
-       BUG_ON(!res);
-
-       start = res->start;
-       end = res->end;
-       BUG_ON(start >= end);
+       if (!res)
+               return -EINVAL;
 
-       if (first_level_children_only)
-               sibling_only = true;
+       if (start >= end)
+               return -EINVAL;
 
        read_lock(&resource_lock);
 
-       for (p = iomem_resource.child; p; p = next_resource(p, sibling_only)) {
-               if ((p->flags & res->flags) != res->flags)
+       for (p = iomem_resource.child; p; p = next_resource(p, first_lvl)) {
+               if ((p->flags & flags) != flags)
                        continue;
                if ((desc != IORES_DESC_NONE) && (desc != p->desc))
                        continue;
@@ -352,45 +353,43 @@ static int find_next_iomem_res(struct resource *res, unsigned long desc,
                        p = NULL;
                        break;
                }
-               if ((p->end >= start) && (p->start < end))
+               if ((p->end >= start) && (p->start <= end))
                        break;
        }
 
        read_unlock(&resource_lock);
        if (!p)
                return -1;
+
        /* copy data */
-       if (res->start < p->start)
-               res->start = p->start;
-       if (res->end > p->end)
-               res->end = p->end;
+       res->start = max(start, p->start);
+       res->end = min(end, p->end);
        res->flags = p->flags;
        res->desc = p->desc;
        return 0;
 }
 
-static int __walk_iomem_res_desc(struct resource *res, unsigned long desc,
-                                bool first_level_children_only,
-                                void *arg,
+static int __walk_iomem_res_desc(resource_size_t start, resource_size_t end,
+                                unsigned long flags, unsigned long desc,
+                                bool first_lvl, void *arg,
                                 int (*func)(struct resource *, void *))
 {
-       u64 orig_end = res->end;
+       struct resource res;
        int ret = -1;
 
-       while ((res->start < res->end) &&
-              !find_next_iomem_res(res, desc, first_level_children_only)) {
-               ret = (*func)(res, arg);
+       while (start < end &&
+              !find_next_iomem_res(start, end, flags, desc, first_lvl, &res)) {
+               ret = (*func)(&res, arg);
                if (ret)
                        break;
 
-               res->start = res->end + 1;
-               res->end = orig_end;
+               start = res.end + 1;
        }
 
        return ret;
 }
 
-/*
+/**
  * Walks through iomem resources and calls func() with matching resource
  * ranges. This walks through whole tree and not just first level children.
  * All the memory ranges which overlap start,end and also match flags and
@@ -407,13 +406,7 @@ static int __walk_iomem_res_desc(struct resource *res, unsigned long desc,
 int walk_iomem_res_desc(unsigned long desc, unsigned long flags, u64 start,
                u64 end, void *arg, int (*func)(struct resource *, void *))
 {
-       struct resource res;
-
-       res.start = start;
-       res.end = end;
-       res.flags = flags;
-
-       return __walk_iomem_res_desc(&res, desc, false, arg, func);
+       return __walk_iomem_res_desc(start, end, flags, desc, false, arg, func);
 }
 EXPORT_SYMBOL_GPL(walk_iomem_res_desc);
 
@@ -425,15 +418,11 @@ EXPORT_SYMBOL_GPL(walk_iomem_res_desc);
  * ranges.
  */
 int walk_system_ram_res(u64 start, u64 end, void *arg,
-                               int (*func)(struct resource *, void *))
+                       int (*func)(struct resource *, void *))
 {
-       struct resource res;
+       unsigned long flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
 
-       res.start = start;
-       res.end = end;
-       res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
-
-       return __walk_iomem_res_desc(&res, IORES_DESC_NONE, true,
+       return __walk_iomem_res_desc(start, end, flags, IORES_DESC_NONE, true,
                                     arg, func);
 }
 
@@ -444,13 +433,9 @@ int walk_system_ram_res(u64 start, u64 end, void *arg,
 int walk_mem_res(u64 start, u64 end, void *arg,
                 int (*func)(struct resource *, void *))
 {
-       struct resource res;
-
-       res.start = start;
-       res.end = end;
-       res.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+       unsigned long flags = IORESOURCE_MEM | IORESOURCE_BUSY;
 
-       return __walk_iomem_res_desc(&res, IORES_DESC_NONE, true,
+       return __walk_iomem_res_desc(start, end, flags, IORES_DESC_NONE, true,
                                     arg, func);
 }
 
@@ -462,27 +447,27 @@ int walk_mem_res(u64 start, u64 end, void *arg,
  * It is to be used only for System RAM.
  */
 int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages,
-               void *arg, int (*func)(unsigned long, unsigned long, void *))
+                         void *arg, int (*func)(unsigned long, unsigned long, void *))
 {
+       resource_size_t start, end;
+       unsigned long flags;
        struct resource res;
        unsigned long pfn, end_pfn;
-       u64 orig_end;
        int ret = -1;
 
-       res.start = (u64) start_pfn << PAGE_SHIFT;
-       res.end = ((u64)(start_pfn + nr_pages) << PAGE_SHIFT) - 1;
-       res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
-       orig_end = res.end;
-       while ((res.start < res.end) &&
-               (find_next_iomem_res(&res, IORES_DESC_NONE, true) >= 0)) {
+       start = (u64) start_pfn << PAGE_SHIFT;
+       end = ((u64)(start_pfn + nr_pages) << PAGE_SHIFT) - 1;
+       flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
+       while (start < end &&
+              !find_next_iomem_res(start, end, flags, IORES_DESC_NONE,
+                                   true, &res)) {
                pfn = (res.start + PAGE_SIZE - 1) >> PAGE_SHIFT;
                end_pfn = (res.end + 1) >> PAGE_SHIFT;
                if (end_pfn > pfn)
                        ret = (*func)(pfn, end_pfn - pfn, arg);
                if (ret)
                        break;
-               res.start = res.end + 1;
-               res.end = orig_end;
+               start = res.end + 1;
        }
        return ret;
 }
@@ -658,8 +643,8 @@ static int find_resource(struct resource *root, struct resource *new,
  * @constraint: the size and alignment constraints to be met.
  */
 static int reallocate_resource(struct resource *root, struct resource *old,
-                       resource_size_t newsize,
-                       struct resource_constraint  *constraint)
+                              resource_size_t newsize,
+                              struct resource_constraint *constraint)
 {
        int err=0;
        struct resource new = *old;
@@ -972,7 +957,7 @@ skip:
  * Existing children of the resource are assumed to be immutable.
  */
 int adjust_resource(struct resource *res, resource_size_t start,
-                       resource_size_t size)
+                   resource_size_t size)
 {
        int result;
 
@@ -983,9 +968,9 @@ int adjust_resource(struct resource *res, resource_size_t start,
 }
 EXPORT_SYMBOL(adjust_resource);
 
-static void __init __reserve_region_with_split(struct resource *root,
-               resource_size_t start, resource_size_t end,
-               const char *name)
+static void __init
+__reserve_region_with_split(struct resource *root, resource_size_t start,
+                           resource_size_t end, const char *name)
 {
        struct resource *parent = root;
        struct resource *conflict;
@@ -1044,9 +1029,9 @@ static void __init __reserve_region_with_split(struct resource *root,
 
 }
 
-void __init reserve_region_with_split(struct resource *root,
-               resource_size_t start, resource_size_t end,
-               const char *name)
+void __init
+reserve_region_with_split(struct resource *root, resource_size_t start,
+                         resource_size_t end, const char *name)
 {
        int abort = 0;
 
@@ -1172,7 +1157,7 @@ EXPORT_SYMBOL(__request_region);
  * The described resource region must match a currently busy region.
  */
 void __release_region(struct resource *parent, resource_size_t start,
-                       resource_size_t n)
+                     resource_size_t n)
 {
        struct resource **p;
        resource_size_t end;
@@ -1234,7 +1219,7 @@ EXPORT_SYMBOL(__release_region);
  *   simplicity.  Enhance this logic when necessary.
  */
 int release_mem_region_adjustable(struct resource *parent,
-                       resource_size_t start, resource_size_t size)
+                                 resource_size_t start, resource_size_t size)
 {
        struct resource **p;
        struct resource *res;
@@ -1410,9 +1395,9 @@ static int devm_region_match(struct device *dev, void *res, void *match_data)
                this->start == match->start && this->n == match->n;
 }
 
-struct resource * __devm_request_region(struct device *dev,
-                               struct resource *parent, resource_size_t start,
-                               resource_size_t n, const char *name)
+struct resource *
+__devm_request_region(struct device *dev, struct resource *parent,
+                     resource_size_t start, resource_size_t n, const char *name)
 {
        struct region_devres *dr = NULL;
        struct resource *res;