unsigned long flags, unsigned long desc,
                               bool first_lvl, struct resource *res)
 {
+       bool siblings_only = true;
        struct resource *p;
 
        if (!res)
 
        read_lock(&resource_lock);
 
-       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;
+       for (p = iomem_resource.child; p; p = next_resource(p, siblings_only)) {
+               /* If we passed the resource we are looking for, stop */
                if (p->start > end) {
                        p = NULL;
                        break;
                }
-               if ((p->end >= start) && (p->start <= end))
-                       break;
+
+               /* Skip until we find a range that matches what we look for */
+               if (p->end < start)
+                       continue;
+
+               /*
+                * Now that we found a range that matches what we look for,
+                * check the flags and the descriptor. If we were not asked to
+                * use only the first level, start looking at children as well.
+                */
+               siblings_only = first_lvl;
+
+               if ((p->flags & flags) != flags)
+                       continue;
+               if ((desc != IORES_DESC_NONE) && (desc != p->desc))
+                       continue;
+
+               /* Found a match, break */
+               break;
        }
 
        if (p) {