diff options
Diffstat (limited to 'common/resource.c')
-rw-r--r-- | common/resource.c | 56 |
1 files changed, 35 insertions, 21 deletions
diff --git a/common/resource.c b/common/resource.c index abc0814d23..8678609229 100644 --- a/common/resource.c +++ b/common/resource.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * resource.c - barebox resource management * * Copyright (c) 2011 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <common.h> #include <malloc.h> @@ -34,13 +23,13 @@ static int init_resource(struct resource *res, const char *name) /* * request a region. - * This will succedd when the requested region is completely inside + * This will succeed when the requested region is completely inside * the parent resource and does not conflict with any of the child * resources. */ struct resource *__request_region(struct resource *parent, - const char *name, resource_size_t start, - resource_size_t end) + resource_size_t start, resource_size_t end, + const char *name, unsigned flags) { struct resource *r, *new; @@ -72,25 +61,28 @@ struct resource *__request_region(struct resource *parent, goto ok; if (start > r->end) continue; - debug("%s: 0x%08llx:0x%08llx conflicts with 0x%08llx:0x%08llx\n", + debug("%s: 0x%08llx:0x%08llx (%s) conflicts with 0x%08llx:0x%08llx (%s)\n", __func__, (unsigned long long)start, (unsigned long long)end, + name, (unsigned long long)r->start, - (unsigned long long)r->end); + (unsigned long long)r->end, + r->name); return ERR_PTR(-EBUSY); } ok: - debug("%s ok: 0x%08llx:0x%08llx\n", __func__, + debug("%s ok: 0x%08llx:0x%08llx flags=0x%x\n", __func__, (unsigned long long)start, - (unsigned long long)end); + (unsigned long long)end, flags); new = xzalloc(sizeof(*new)); init_resource(new, name); new->start = start; new->end = end; new->parent = parent; + new->flags = flags; list_add_tail(&new->sibling, &r->sibling); return new; @@ -111,6 +103,28 @@ int release_region(struct resource *res) return 0; } + +/* + * merge two adjacent sibling regions. + */ +int __merge_regions(const char *name, + struct resource *resa, struct resource *resb) +{ + if (!resource_adjacent(resa, resb)) + return -EINVAL; + + if (resa->start < resb->start) + resa->end = resb->end; + else + resa->start = resb->start; + + free((char *)resa->name); + resa->name = xstrdup(name); + release_region(resb); + + return 0; +} + /* The root resource for the whole memory-mapped io space */ struct resource iomem_resource = { .start = 0, @@ -125,7 +139,7 @@ struct resource iomem_resource = { struct resource *request_iomem_region(const char *name, resource_size_t start, resource_size_t end) { - return __request_region(&iomem_resource, name, start, end); + return __request_region(&iomem_resource, start, end, name, 0); } /* The root resource for the whole io-mapped io space */ @@ -144,7 +158,7 @@ struct resource *request_ioport_region(const char *name, { struct resource *res; - res = __request_region(&ioport_resource, name, start, end); + res = __request_region(&ioport_resource, start, end, name, 0); if (IS_ERR(res)) return ERR_CAST(res); |