From 200ae6b4eef9f6041016887f71fc01c5daee6f69 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 1 Dec 2011 21:44:02 +0100 Subject: add resource management functions It is time to track our memory usage. Add a simple resource management. Signed-off-by: Sascha Hauer --- common/Makefile | 1 + common/resource.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/ioport.h | 14 ++++++ 3 files changed, 136 insertions(+) create mode 100644 common/resource.c diff --git a/common/Makefile b/common/Makefile index 55d9dbcb43..9bce47943c 100644 --- a/common/Makefile +++ b/common/Makefile @@ -27,6 +27,7 @@ obj-y += startup.o obj-y += misc.o obj-y += memsize.o obj-y += filetype.o +obj-y += resource.o obj-$(CONFIG_MENU) += menu.o obj-$(CONFIG_PASSWORD) += password.o obj-$(CONFIG_MODULES) += module.o diff --git a/common/resource.c b/common/resource.c new file mode 100644 index 0000000000..63e9c49ca1 --- /dev/null +++ b/common/resource.c @@ -0,0 +1,121 @@ +/* + * resource.c - barebox resource management + * + * Copyright (c) 2011 Sascha Hauer , 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation. + */ +#include +#include +#include +#include +#include + +static int init_resource(struct resource *res, const char *name) +{ + INIT_LIST_HEAD(&res->children); + res->parent = NULL; + res->name = xstrdup(name); + + return 0; +} + +/* + * request a region. + * This will succedd 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 size) +{ + struct resource *r, *new; + + /* outside parent resource? */ + if (start < parent->start || + start + size > parent->start + parent->size) { + debug("%s: 0x%08x:0x%08x outside parent resource 0x%08x:0x%08x\n", + __func__, start, size, parent->start, + parent->size); + return NULL; + } + + /* + * We keep the list of child resources ordered which helps + * us searching for conflicts here. + */ + list_for_each_entry(r, &parent->children, sibling) { + if (start + size <= r->start) + goto ok; + if (start >= r->start + r->size) + continue; + debug("%s: 0x%08x:0x%08x conflicts with 0x%08x:0x%08x\n", + __func__, start, size, r->start, r->size); + return NULL; + } + +ok: + debug("%s ok: 0x%08x 0x%08x\n", __func__, start, size); + + new = xzalloc(sizeof(*new)); + init_resource(new, name); + new->start = start; + new->size = size; + new->parent = parent; + list_add_tail(&new->sibling, &r->sibling); + + return new; +} + +/* + * release a region previously requested with request_region + */ +int release_region(struct resource *res) +{ + if (!list_empty(&res->children)) + return -EBUSY; + + list_del(&res->sibling); + free((char *)res->name); + free(res); + + return 0; +} + +/* The root resource for the whole io space */ +struct resource iomem_resource = { + .start = 0, + .size = ~0, +}; + +/* + * request a region inside the io space + */ +struct resource *request_iomem_region(const char *name, + resource_size_t start, resource_size_t size) +{ + return request_region(&iomem_resource, name, start, size); +} + +static int iomem_init(void) +{ + init_resource(&iomem_resource, "iomem"); + + return 0; +} +postcore_initcall(iomem_init); diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 51431158d3..c837b53491 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -20,6 +20,9 @@ struct resource { resource_size_t size; const char *name; unsigned long flags; + struct resource *parent; + struct list_head children; + struct list_head sibling; }; /* @@ -111,5 +114,16 @@ static inline unsigned long resource_type(const struct resource *res) return res->flags & IORESOURCE_TYPE_BITS; } +struct resource *request_iomem_region(const char *name, + resource_size_t start, resource_size_t size); + +struct resource *request_region(struct resource *parent, + const char *name, resource_size_t start, + resource_size_t size); + +int release_region(struct resource *res); + +extern struct resource iomem_resource; + #endif /* __ASSEMBLY__ */ #endif /* _LINUX_IOPORT_H */ -- cgit v1.2.3