Lines Matching +full:space +full:- +full:constraint

1 // SPDX-License-Identifier: GPL-2.0-only
44 .end = -1,
61 if (p->child) in next_resource()
62 return p->child; in next_resource()
63 while (!p->sibling && p->parent) in next_resource()
64 p = p->parent; in next_resource()
65 return p->sibling; in next_resource()
70 while (!p->sibling && p->parent) in next_resource_skip_children()
71 p = p->parent; in next_resource_skip_children()
72 return p->sibling; in next_resource_skip_children()
76 for ((_p) = (_root)->child; (_p); \
94 struct resource *p = pde_data(file_inode(m->file)); in r_start()
97 for (p = p->child; p && l < *pos; p = r_next(m, p, &l)) in r_start()
110 struct resource *root = pde_data(file_inode(m->file)); in r_show()
113 int width = root->end < 0x10000 ? 4 : 8; in r_show()
116 for (depth = 0, p = r; depth < MAX_IORES_LEVEL; depth++, p = p->parent) in r_show()
117 if (p->parent == root) in r_show()
120 if (file_ns_capable(m->file, &init_user_ns, CAP_SYS_ADMIN)) { in r_show()
121 start = r->start; in r_show()
122 end = r->end; in r_show()
127 seq_printf(m, "%*s%0*llx-%0*llx : %s\n", in r_show()
131 r->name ? r->name : "<BAD>"); in r_show()
173 resource_size_t start = new->start; in __request_resource()
174 resource_size_t end = new->end; in __request_resource()
179 if (start < root->start) in __request_resource()
181 if (end > root->end) in __request_resource()
183 p = &root->child; in __request_resource()
186 if (!tmp || tmp->start > end) { in __request_resource()
187 new->sibling = tmp; in __request_resource()
189 new->parent = root; in __request_resource()
192 p = &tmp->sibling; in __request_resource()
193 if (tmp->end < start) in __request_resource()
203 p = &old->parent->child; in __release_resource()
209 if (release_child || !(tmp->child)) { in __release_resource()
210 *p = tmp->sibling; in __release_resource()
212 for (chd = tmp->child;; chd = chd->sibling) { in __release_resource()
213 chd->parent = tmp->parent; in __release_resource()
214 if (!(chd->sibling)) in __release_resource()
217 *p = tmp->child; in __release_resource()
218 chd->sibling = tmp->sibling; in __release_resource()
220 old->parent = NULL; in __release_resource()
223 p = &tmp->sibling; in __release_resource()
225 return -EINVAL; in __release_resource()
233 p = r->child; in __release_child_resources()
234 r->child = NULL; in __release_child_resources()
237 p = p->sibling; in __release_child_resources()
239 tmp->parent = NULL; in __release_child_resources()
240 tmp->sibling = NULL; in __release_child_resources()
246 tmp->start = 0; in __release_child_resources()
247 tmp->end = size - 1; in __release_child_resources()
259 * request_resource_conflict - request and reserve an I/O or memory resource
276 * request_resource - request and reserve an I/O or memory resource
287 return conflict ? -EBUSY : 0; in request_resource()
293 * release_resource - release a previously reserved resource
309 * find_next_iomem_res - Finds the lowest iomem resource that covers part of
314 * -ENODEV. Returns -EINVAL for invalid parameters.
332 return -EINVAL; in find_next_iomem_res()
335 return -EINVAL; in find_next_iomem_res()
341 if (p->start > end) { in find_next_iomem_res()
347 if (p->end < start) in find_next_iomem_res()
350 if ((p->flags & flags) != flags) in find_next_iomem_res()
352 if ((desc != IORES_DESC_NONE) && (desc != p->desc)) in find_next_iomem_res()
362 .start = max(start, p->start), in find_next_iomem_res()
363 .end = min(end, p->end), in find_next_iomem_res()
364 .flags = p->flags, in find_next_iomem_res()
365 .desc = p->desc, in find_next_iomem_res()
366 .parent = p->parent, in find_next_iomem_res()
371 return p ? 0 : -ENODEV; in find_next_iomem_res()
380 int ret = -EINVAL; in __walk_iomem_res_desc()
395 * walk_iomem_res_desc - Walks through iomem resources and calls func()
422 * not PFNs. If resources are not PFN-aligned, dealing with PFNs can truncate
459 int ret = -EINVAL; in walk_system_ram_range()
462 end = ((u64)(start_pfn + nr_pages) << PAGE_SHIFT) - 1; in walk_system_ram_range()
469 ret = (*func)(pfn, end_pfn - pfn, arg); in walk_system_ram_range()
501 res.end = start + size - 1; in __region_intersects()
503 for (p = parent->child; p ; p = p->sibling) { in __region_intersects()
504 bool is_type = (((p->flags & flags) == flags) && in __region_intersects()
506 (desc == p->desc))); in __region_intersects()
522 * region_intersects() - determine intersection of region with known resources
563 return avail->start; in simple_align_resource()
569 if (res->start < min) in resource_clip()
570 res->start = min; in resource_clip()
571 if (res->end > max) in resource_clip()
572 res->end = max; in resource_clip()
582 struct resource_constraint *constraint) in __find_resource() argument
584 struct resource *this = root->child; in __find_resource()
587 tmp.start = root->start; in __find_resource()
590 * of this->start - 1 to tmp->end below would cause an underflow. in __find_resource()
592 if (this && this->start == root->start) { in __find_resource()
593 tmp.start = (this == old) ? old->start : this->end + 1; in __find_resource()
594 this = this->sibling; in __find_resource()
598 tmp.end = (this == old) ? this->end : this->start - 1; in __find_resource()
600 tmp.end = root->end; in __find_resource()
605 resource_clip(&tmp, constraint->min, constraint->max); in __find_resource()
609 avail.start = ALIGN(tmp.start, constraint->align); in __find_resource()
611 avail.flags = new->flags & ~IORESOURCE_UNSET; in __find_resource()
614 alloc.start = constraint->alignf(constraint->alignf_data, &avail, in __find_resource()
615 size, constraint->align); in __find_resource()
616 alloc.end = alloc.start + size - 1; in __find_resource()
619 new->start = alloc.start; in __find_resource()
620 new->end = alloc.end; in __find_resource()
625 next: if (!this || this->end == root->end) in __find_resource()
629 tmp.start = this->end + 1; in __find_resource()
630 this = this->sibling; in __find_resource()
632 return -EBUSY; in __find_resource()
640 struct resource_constraint *constraint) in find_resource() argument
642 return __find_resource(root, NULL, new, size, constraint); in find_resource()
646 * reallocate_resource - allocate a slot in the resource tree given range & alignment.
653 * @constraint: the size and alignment constraints to be met.
657 struct resource_constraint *constraint) in reallocate_resource() argument
665 if ((err = __find_resource(root, old, &new, newsize, constraint))) in reallocate_resource()
669 old->start = new.start; in reallocate_resource()
670 old->end = new.end; in reallocate_resource()
674 if (old->child) { in reallocate_resource()
675 err = -EBUSY; in reallocate_resource()
680 old->start = new.start; in reallocate_resource()
681 old->end = new.end; in reallocate_resource()
695 * allocate_resource - allocate empty slot in the resource tree given range & alignment.
716 struct resource_constraint constraint; in allocate_resource() local
721 constraint.min = min; in allocate_resource()
722 constraint.max = max; in allocate_resource()
723 constraint.align = align; in allocate_resource()
724 constraint.alignf = alignf; in allocate_resource()
725 constraint.alignf_data = alignf_data; in allocate_resource()
727 if ( new->parent ) { in allocate_resource()
730 return reallocate_resource(root, new, size, &constraint); in allocate_resource()
734 err = find_resource(root, new, size, &constraint); in allocate_resource()
736 err = -EBUSY; in allocate_resource()
744 * lookup_resource - find an existing resource by a resource start address
755 for (res = root->child; res; res = res->sibling) { in lookup_resource()
756 if (res->start == start) in lookup_resource()
782 if ((first->start > new->start) || (first->end < new->end)) in __insert_resource()
784 if ((first->start == new->start) && (first->end == new->end)) in __insert_resource()
788 for (next = first; ; next = next->sibling) { in __insert_resource()
790 if (next->start < new->start || next->end > new->end) in __insert_resource()
792 if (!next->sibling) in __insert_resource()
794 if (next->sibling->start > new->end) in __insert_resource()
798 new->parent = parent; in __insert_resource()
799 new->sibling = next->sibling; in __insert_resource()
800 new->child = first; in __insert_resource()
802 next->sibling = NULL; in __insert_resource()
803 for (next = first; next; next = next->sibling) in __insert_resource()
804 next->parent = new; in __insert_resource()
806 if (parent->child == first) { in __insert_resource()
807 parent->child = new; in __insert_resource()
809 next = parent->child; in __insert_resource()
810 while (next->sibling != first) in __insert_resource()
811 next = next->sibling; in __insert_resource()
812 next->sibling = new; in __insert_resource()
818 * insert_resource_conflict - Inserts resource in the resource tree
844 * insert_resource - Inserts a resource in the resource tree
848 * Returns 0 on success, -EBUSY if the resource can't be inserted.
858 return conflict ? -EBUSY : 0; in insert_resource()
863 * insert_resource_expand_to_fit - Insert a resource into the resource tree
872 if (new->parent) in insert_resource_expand_to_fit()
886 if (conflict->start < new->start) in insert_resource_expand_to_fit()
887 new->start = conflict->start; in insert_resource_expand_to_fit()
888 if (conflict->end > new->end) in insert_resource_expand_to_fit()
889 new->end = conflict->end; in insert_resource_expand_to_fit()
891 pr_info("Expanded resource %s due to conflict with %s\n", new->name, conflict->name); in insert_resource_expand_to_fit()
898 * to use this interface. The former are built-in and only the latter,
904 * remove_resource - Remove a resource in the resource tree
907 * Returns 0 on success, -EINVAL if the resource is not valid.
932 struct resource *tmp, *parent = res->parent; in __adjust_resource()
933 resource_size_t end = start + size - 1; in __adjust_resource()
934 int result = -EBUSY; in __adjust_resource()
939 if ((start < parent->start) || (end > parent->end)) in __adjust_resource()
942 if (res->sibling && (res->sibling->start <= end)) in __adjust_resource()
945 tmp = parent->child; in __adjust_resource()
947 while (tmp->sibling != res) in __adjust_resource()
948 tmp = tmp->sibling; in __adjust_resource()
949 if (start <= tmp->end) in __adjust_resource()
954 for (tmp = res->child; tmp; tmp = tmp->sibling) in __adjust_resource()
955 if ((tmp->start < start) || (tmp->end > end)) in __adjust_resource()
958 res->start = start; in __adjust_resource()
959 res->end = end; in __adjust_resource()
967 * adjust_resource - modify a resource's start and size
973 * arguments. Returns 0 on success, -EBUSY if it can't fit.
1001 res->name = name; in __reserve_region_with_split()
1002 res->start = start; in __reserve_region_with_split()
1003 res->end = end; in __reserve_region_with_split()
1004 res->flags = type | IORESOURCE_BUSY; in __reserve_region_with_split()
1005 res->desc = IORES_DESC_NONE; in __reserve_region_with_split()
1019 if (conflict->start <= res->start && in __reserve_region_with_split()
1020 conflict->end >= res->end) { in __reserve_region_with_split()
1027 if (conflict->start > res->start) { in __reserve_region_with_split()
1028 end = res->end; in __reserve_region_with_split()
1029 res->end = conflict->start - 1; in __reserve_region_with_split()
1030 if (conflict->end < end) { in __reserve_region_with_split()
1036 next_res->name = name; in __reserve_region_with_split()
1037 next_res->start = conflict->end + 1; in __reserve_region_with_split()
1038 next_res->end = end; in __reserve_region_with_split()
1039 next_res->flags = type | IORESOURCE_BUSY; in __reserve_region_with_split()
1040 next_res->desc = IORES_DESC_NONE; in __reserve_region_with_split()
1043 res->start = conflict->end + 1; in __reserve_region_with_split()
1056 if (root->start > start || root->end < end) { in reserve_region_with_split()
1057 pr_err("requested range [0x%llx-0x%llx] not in root %pr\n", in reserve_region_with_split()
1060 if (start > root->end || end < root->start) in reserve_region_with_split()
1063 if (end > root->end) in reserve_region_with_split()
1064 end = root->end; in reserve_region_with_split()
1065 if (start < root->start) in reserve_region_with_split()
1066 start = root->start; in reserve_region_with_split()
1067 pr_err("fixing request to [0x%llx-0x%llx]\n", in reserve_region_with_split()
1079 * resource_alignment - calculate resource's alignment
1086 switch (res->flags & (IORESOURCE_SIZEALIGN | IORESOURCE_STARTALIGN)) { in resource_alignment()
1090 return res->start; in resource_alignment()
1132 if (devmem_is_allowed(PHYS_PFN(res->start)) && in revoke_iomem()
1133 devmem_is_allowed(PHYS_PFN(res->end))) { in revoke_iomem()
1141 unmap_mapping_range(inode->i_mapping, res->start, resource_size(res), 1); in revoke_iomem()
1155 return smp_load_acquire(&iomem_inode)->i_mapping; in iomem_get_mapping()
1164 res->name = name; in __request_region_locked()
1165 res->start = start; in __request_region_locked()
1166 res->end = start + n - 1; in __request_region_locked()
1171 res->flags = resource_type(parent) | resource_ext_type(parent); in __request_region_locked()
1172 res->flags |= IORESOURCE_BUSY | flags; in __request_region_locked()
1173 res->desc = parent->desc; in __request_region_locked()
1183 if (conflict->desc == IORES_DESC_DEVICE_PRIVATE_MEMORY) { in __request_region_locked()
1185 conflict->name, conflict, res); in __request_region_locked()
1188 if (!(conflict->flags & IORESOURCE_BUSY)) { in __request_region_locked()
1193 if (conflict->flags & flags & IORESOURCE_MUXED) { in __request_region_locked()
1203 return -EBUSY; in __request_region_locked()
1210 * __request_region - create a new busy resource region
1244 * __release_region - release a previously reserved resource region
1257 p = &parent->child; in __release_region()
1258 end = start + n - 1; in __release_region()
1267 if (res->start <= start && res->end >= end) { in __release_region()
1268 if (!(res->flags & IORESOURCE_BUSY)) { in __release_region()
1269 p = &res->child; in __release_region()
1272 if (res->start != start || res->end != end) in __release_region()
1274 *p = res->sibling; in __release_region()
1276 if (res->flags & IORESOURCE_MUXED) in __release_region()
1281 p = &res->sibling; in __release_region()
1286 pr_warn("Trying to free nonexistent resource <%pa-%pa>\n", &start, &end); in __release_region()
1292 * release_mem_region_adjustable - release a previously reserved memory region
1296 * This interface is intended for memory hot-delete. The requested region
1304 * - Additional release conditions, such as overlapping region, can be
1306 * - When a busy memory resource gets split into two entries, the code
1319 end = start + size - 1; in release_mem_region_adjustable()
1320 if (WARN_ON_ONCE((start < parent->start) || (end > parent->end))) in release_mem_region_adjustable()
1326 * fail - let's play save and make it never fail as the caller cannot in release_mem_region_adjustable()
1327 * perform any error handling (e.g., trying to re-add memory will fail in release_mem_region_adjustable()
1333 p = &parent->child; in release_mem_region_adjustable()
1337 if (res->start >= end) in release_mem_region_adjustable()
1341 if (res->start > start || res->end < end) { in release_mem_region_adjustable()
1342 p = &res->sibling; in release_mem_region_adjustable()
1346 if (!(res->flags & IORESOURCE_MEM)) in release_mem_region_adjustable()
1349 if (!(res->flags & IORESOURCE_BUSY)) { in release_mem_region_adjustable()
1350 p = &res->child; in release_mem_region_adjustable()
1355 if (res->start == start && res->end == end) { in release_mem_region_adjustable()
1357 *p = res->sibling; in release_mem_region_adjustable()
1359 } else if (res->start == start && res->end != end) { in release_mem_region_adjustable()
1362 res->end - end)); in release_mem_region_adjustable()
1363 } else if (res->start != start && res->end == end) { in release_mem_region_adjustable()
1365 WARN_ON_ONCE(__adjust_resource(res, res->start, in release_mem_region_adjustable()
1366 start - res->start)); in release_mem_region_adjustable()
1368 /* split into two entries - we need a new resource */ in release_mem_region_adjustable()
1377 new_res->name = res->name; in release_mem_region_adjustable()
1378 new_res->start = end + 1; in release_mem_region_adjustable()
1379 new_res->end = res->end; in release_mem_region_adjustable()
1380 new_res->flags = res->flags; in release_mem_region_adjustable()
1381 new_res->desc = res->desc; in release_mem_region_adjustable()
1382 new_res->parent = res->parent; in release_mem_region_adjustable()
1383 new_res->sibling = res->sibling; in release_mem_region_adjustable()
1384 new_res->child = NULL; in release_mem_region_adjustable()
1386 if (WARN_ON_ONCE(__adjust_resource(res, res->start, in release_mem_region_adjustable()
1387 start - res->start))) in release_mem_region_adjustable()
1389 res->sibling = new_res; in release_mem_region_adjustable()
1406 return r1->flags == r2->flags && r1->end + 1 == r2->start && in system_ram_resources_mergeable()
1407 r1->name == r2->name && r1->desc == r2->desc && in system_ram_resources_mergeable()
1408 !r1->child && !r2->child; in system_ram_resources_mergeable()
1412 * merge_system_ram_resource - mark the System RAM resource mergeable and try to
1424 * - The caller has to make sure that no pointers to resources that are
1425 * marked mergeable are used anymore after this call - the resource might
1427 * - release_mem_region_adjustable() will split on demand on memory hotunplug
1434 if (WARN_ON_ONCE((res->flags & flags) != flags)) in merge_system_ram_resource()
1438 res->flags |= IORESOURCE_SYSRAM_MERGEABLE; in merge_system_ram_resource()
1441 cur = res->sibling; in merge_system_ram_resource()
1443 res->end = cur->end; in merge_system_ram_resource()
1444 res->sibling = cur->sibling; in merge_system_ram_resource()
1449 cur = res->parent->child; in merge_system_ram_resource()
1450 while (cur && cur->sibling != res) in merge_system_ram_resource()
1451 cur = cur->sibling; in merge_system_ram_resource()
1453 cur->end = res->end; in merge_system_ram_resource()
1454 cur->sibling = res->sibling; in merge_system_ram_resource()
1472 * devm_request_resource() - request and reserve an I/O or memory resource
1477 * This is a device-managed version of request_resource(). There is usually
1496 return -ENOMEM; in devm_request_resource()
1503 new, conflict->name, conflict); in devm_request_resource()
1505 return -EBUSY; in devm_request_resource()
1521 * devm_release_resource() - release a previously requested resource
1544 __release_region(this->parent, this->start, this->n); in devm_region_release()
1551 return this->parent == match->parent && in devm_region_match()
1552 this->start == match->start && this->n == match->n; in devm_region_match()
1567 dr->parent = parent; in __devm_request_region()
1568 dr->start = start; in __devm_request_region()
1569 dr->n = n; in __devm_request_region()
1615 * I/O port space; otherwise assume it's memory. in reserve_setup()
1618 res->flags = IORESOURCE_IO; in reserve_setup()
1621 res->flags = IORESOURCE_MEM; in reserve_setup()
1624 res->name = "reserved"; in reserve_setup()
1625 res->start = io_start; in reserve_setup()
1626 res->end = io_start + io_num - 1; in reserve_setup()
1627 res->flags |= IORESOURCE_BUSY; in reserve_setup()
1628 res->desc = IORES_DESC_NONE; in reserve_setup()
1629 res->child = NULL; in reserve_setup()
1645 resource_size_t end = addr + size - 1; in iomem_map_sanity_check()
1650 for (p = p->child; p ; p = r_next(NULL, p, &l)) { in iomem_map_sanity_check()
1655 if (p->start > end) in iomem_map_sanity_check()
1657 if (p->end < addr) in iomem_map_sanity_check()
1659 if (PFN_DOWN(p->start) <= PFN_DOWN(addr) && in iomem_map_sanity_check()
1660 PFN_DOWN(p->end) >= PFN_DOWN(end)) in iomem_map_sanity_check()
1668 if (p->flags & IORESOURCE_BUSY) in iomem_map_sanity_check()
1671 pr_warn("resource sanity check: requesting [mem %pa-%pa], which spans more than %s %pR\n", in iomem_map_sanity_check()
1672 &addr, &end, p->name, p); in iomem_map_sanity_check()
1673 err = -1; in iomem_map_sanity_check()
1689 * user space, for example, via /dev/mem.
1702 if (p->start >= addr + size) in resource_is_exclusive()
1704 if (p->end < addr) { in resource_is_exclusive()
1717 if ((p->flags & exclusive_system_ram) == exclusive_system_ram) { in resource_is_exclusive()
1727 if (!strict_iomem_checks || !(p->flags & IORESOURCE_BUSY)) in resource_is_exclusive()
1730 || p->flags & IORESOURCE_EXCLUSIVE) { in resource_is_exclusive()
1753 INIT_LIST_HEAD(&entry->node); in resource_list_create_entry()
1754 entry->res = res ? res : &entry->__res; in resource_list_create_entry()
1781 end = min_t(resource_size_t, base->end, in gfr_start()
1782 (1ULL << MAX_PHYSMEM_BITS) - 1); in gfr_start()
1783 return end - size + 1; in gfr_start()
1786 return ALIGN(base->start, align); in gfr_start()
1793 return addr > size && addr >= base->start; in gfr_continue()
1798 return addr > addr - size && in gfr_continue()
1799 addr <= min_t(resource_size_t, base->end, in gfr_continue()
1800 (1ULL << MAX_PHYSMEM_BITS) - 1); in gfr_continue()
1807 return addr - size; in gfr_next()
1815 if (res->parent) in remove_free_mem_region()
1834 return ERR_PTR(-ENOMEM); in get_free_mem_region()
1841 return ERR_PTR(-ENOMEM); in get_free_mem_region()
1845 return ERR_PTR(-ENOMEM); in get_free_mem_region()
1862 dr->parent = &iomem_resource; in get_free_mem_region()
1863 dr->start = addr; in get_free_mem_region()
1864 dr->n = size; in get_free_mem_region()
1868 res->desc = desc; in get_free_mem_region()
1878 res->start = addr; in get_free_mem_region()
1879 res->end = addr + size - 1; in get_free_mem_region()
1880 res->name = name; in get_free_mem_region()
1881 res->desc = desc; in get_free_mem_region()
1882 res->flags = IORESOURCE_MEM; in get_free_mem_region()
1888 if (__insert_resource(base, res) || res->child) in get_free_mem_region()
1904 return ERR_PTR(-ERANGE); in get_free_mem_region()
1908 * devm_request_free_mem_region - find free region for device private memory
1940 * alloc_free_mem_region - find a free region relative to @base
1947 * need a method to allocate physical address space for those regions.
1975 return init_pseudo(fc, DEVMEM_MAGIC) ? 0 : -ENOMEM; in iomem_fs_init_fs_context()
1998 inode = alloc_anon_inode(iomem_vfs_mount->mnt_sb); in iomem_init_inode()