diff options
Diffstat (limited to 'kernel/resource.c')
-rw-r--r-- | kernel/resource.c | 90 |
1 files changed, 65 insertions, 25 deletions
diff --git a/kernel/resource.c b/kernel/resource.c index e3080fcc66a3..bf1130d81b7f 100644 --- a/kernel/resource.c +++ b/kernel/resource.c | |||
@@ -23,20 +23,18 @@ | |||
23 | 23 | ||
24 | struct resource ioport_resource = { | 24 | struct resource ioport_resource = { |
25 | .name = "PCI IO", | 25 | .name = "PCI IO", |
26 | .start = 0x0000, | 26 | .start = 0, |
27 | .end = IO_SPACE_LIMIT, | 27 | .end = IO_SPACE_LIMIT, |
28 | .flags = IORESOURCE_IO, | 28 | .flags = IORESOURCE_IO, |
29 | }; | 29 | }; |
30 | |||
31 | EXPORT_SYMBOL(ioport_resource); | 30 | EXPORT_SYMBOL(ioport_resource); |
32 | 31 | ||
33 | struct resource iomem_resource = { | 32 | struct resource iomem_resource = { |
34 | .name = "PCI mem", | 33 | .name = "PCI mem", |
35 | .start = 0UL, | 34 | .start = 0, |
36 | .end = ~0UL, | 35 | .end = -1, |
37 | .flags = IORESOURCE_MEM, | 36 | .flags = IORESOURCE_MEM, |
38 | }; | 37 | }; |
39 | |||
40 | EXPORT_SYMBOL(iomem_resource); | 38 | EXPORT_SYMBOL(iomem_resource); |
41 | 39 | ||
42 | static DEFINE_RWLOCK(resource_lock); | 40 | static DEFINE_RWLOCK(resource_lock); |
@@ -83,10 +81,10 @@ static int r_show(struct seq_file *m, void *v) | |||
83 | for (depth = 0, p = r; depth < MAX_IORES_LEVEL; depth++, p = p->parent) | 81 | for (depth = 0, p = r; depth < MAX_IORES_LEVEL; depth++, p = p->parent) |
84 | if (p->parent == root) | 82 | if (p->parent == root) |
85 | break; | 83 | break; |
86 | seq_printf(m, "%*s%0*lx-%0*lx : %s\n", | 84 | seq_printf(m, "%*s%0*llx-%0*llx : %s\n", |
87 | depth * 2, "", | 85 | depth * 2, "", |
88 | width, r->start, | 86 | width, (unsigned long long) r->start, |
89 | width, r->end, | 87 | width, (unsigned long long) r->end, |
90 | r->name ? r->name : "<BAD>"); | 88 | r->name ? r->name : "<BAD>"); |
91 | return 0; | 89 | return 0; |
92 | } | 90 | } |
@@ -151,8 +149,8 @@ __initcall(ioresources_init); | |||
151 | /* Return the conflict entry if you can't request it */ | 149 | /* Return the conflict entry if you can't request it */ |
152 | static struct resource * __request_resource(struct resource *root, struct resource *new) | 150 | static struct resource * __request_resource(struct resource *root, struct resource *new) |
153 | { | 151 | { |
154 | unsigned long start = new->start; | 152 | resource_size_t start = new->start; |
155 | unsigned long end = new->end; | 153 | resource_size_t end = new->end; |
156 | struct resource *tmp, **p; | 154 | struct resource *tmp, **p; |
157 | 155 | ||
158 | if (end < start) | 156 | if (end < start) |
@@ -232,15 +230,52 @@ int release_resource(struct resource *old) | |||
232 | 230 | ||
233 | EXPORT_SYMBOL(release_resource); | 231 | EXPORT_SYMBOL(release_resource); |
234 | 232 | ||
233 | #ifdef CONFIG_MEMORY_HOTPLUG | ||
234 | /* | ||
235 | * Finds the lowest memory reosurce exists within [res->start.res->end) | ||
236 | * the caller must specify res->start, res->end, res->flags. | ||
237 | * If found, returns 0, res is overwritten, if not found, returns -1. | ||
238 | */ | ||
239 | int find_next_system_ram(struct resource *res) | ||
240 | { | ||
241 | resource_size_t start, end; | ||
242 | struct resource *p; | ||
243 | |||
244 | BUG_ON(!res); | ||
245 | |||
246 | start = res->start; | ||
247 | end = res->end; | ||
248 | |||
249 | read_lock(&resource_lock); | ||
250 | for (p = iomem_resource.child; p ; p = p->sibling) { | ||
251 | /* system ram is just marked as IORESOURCE_MEM */ | ||
252 | if (p->flags != res->flags) | ||
253 | continue; | ||
254 | if (p->start > end) { | ||
255 | p = NULL; | ||
256 | break; | ||
257 | } | ||
258 | if (p->start >= start) | ||
259 | break; | ||
260 | } | ||
261 | read_unlock(&resource_lock); | ||
262 | if (!p) | ||
263 | return -1; | ||
264 | /* copy data */ | ||
265 | res->start = p->start; | ||
266 | res->end = p->end; | ||
267 | return 0; | ||
268 | } | ||
269 | #endif | ||
270 | |||
235 | /* | 271 | /* |
236 | * Find empty slot in the resource tree given range and alignment. | 272 | * Find empty slot in the resource tree given range and alignment. |
237 | */ | 273 | */ |
238 | static int find_resource(struct resource *root, struct resource *new, | 274 | static int find_resource(struct resource *root, struct resource *new, |
239 | unsigned long size, | 275 | resource_size_t size, resource_size_t min, |
240 | unsigned long min, unsigned long max, | 276 | resource_size_t max, resource_size_t align, |
241 | unsigned long align, | ||
242 | void (*alignf)(void *, struct resource *, | 277 | void (*alignf)(void *, struct resource *, |
243 | unsigned long, unsigned long), | 278 | resource_size_t, resource_size_t), |
244 | void *alignf_data) | 279 | void *alignf_data) |
245 | { | 280 | { |
246 | struct resource *this = root->child; | 281 | struct resource *this = root->child; |
@@ -282,11 +317,10 @@ static int find_resource(struct resource *root, struct resource *new, | |||
282 | * Allocate empty slot in the resource tree given range and alignment. | 317 | * Allocate empty slot in the resource tree given range and alignment. |
283 | */ | 318 | */ |
284 | int allocate_resource(struct resource *root, struct resource *new, | 319 | int allocate_resource(struct resource *root, struct resource *new, |
285 | unsigned long size, | 320 | resource_size_t size, resource_size_t min, |
286 | unsigned long min, unsigned long max, | 321 | resource_size_t max, resource_size_t align, |
287 | unsigned long align, | ||
288 | void (*alignf)(void *, struct resource *, | 322 | void (*alignf)(void *, struct resource *, |
289 | unsigned long, unsigned long), | 323 | resource_size_t, resource_size_t), |
290 | void *alignf_data) | 324 | void *alignf_data) |
291 | { | 325 | { |
292 | int err; | 326 | int err; |
@@ -378,10 +412,10 @@ EXPORT_SYMBOL(insert_resource); | |||
378 | * arguments. Returns -EBUSY if it can't fit. Existing children of | 412 | * arguments. Returns -EBUSY if it can't fit. Existing children of |
379 | * the resource are assumed to be immutable. | 413 | * the resource are assumed to be immutable. |
380 | */ | 414 | */ |
381 | int adjust_resource(struct resource *res, unsigned long start, unsigned long size) | 415 | int adjust_resource(struct resource *res, resource_size_t start, resource_size_t size) |
382 | { | 416 | { |
383 | struct resource *tmp, *parent = res->parent; | 417 | struct resource *tmp, *parent = res->parent; |
384 | unsigned long end = start + size - 1; | 418 | resource_size_t end = start + size - 1; |
385 | int result = -EBUSY; | 419 | int result = -EBUSY; |
386 | 420 | ||
387 | write_lock(&resource_lock); | 421 | write_lock(&resource_lock); |
@@ -428,7 +462,9 @@ EXPORT_SYMBOL(adjust_resource); | |||
428 | * | 462 | * |
429 | * Release-region releases a matching busy region. | 463 | * Release-region releases a matching busy region. |
430 | */ | 464 | */ |
431 | struct resource * __request_region(struct resource *parent, unsigned long start, unsigned long n, const char *name) | 465 | struct resource * __request_region(struct resource *parent, |
466 | resource_size_t start, resource_size_t n, | ||
467 | const char *name) | ||
432 | { | 468 | { |
433 | struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); | 469 | struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); |
434 | 470 | ||
@@ -464,7 +500,8 @@ struct resource * __request_region(struct resource *parent, unsigned long start, | |||
464 | 500 | ||
465 | EXPORT_SYMBOL(__request_region); | 501 | EXPORT_SYMBOL(__request_region); |
466 | 502 | ||
467 | int __check_region(struct resource *parent, unsigned long start, unsigned long n) | 503 | int __check_region(struct resource *parent, resource_size_t start, |
504 | resource_size_t n) | ||
468 | { | 505 | { |
469 | struct resource * res; | 506 | struct resource * res; |
470 | 507 | ||
@@ -479,10 +516,11 @@ int __check_region(struct resource *parent, unsigned long start, unsigned long n | |||
479 | 516 | ||
480 | EXPORT_SYMBOL(__check_region); | 517 | EXPORT_SYMBOL(__check_region); |
481 | 518 | ||
482 | void __release_region(struct resource *parent, unsigned long start, unsigned long n) | 519 | void __release_region(struct resource *parent, resource_size_t start, |
520 | resource_size_t n) | ||
483 | { | 521 | { |
484 | struct resource **p; | 522 | struct resource **p; |
485 | unsigned long end; | 523 | resource_size_t end; |
486 | 524 | ||
487 | p = &parent->child; | 525 | p = &parent->child; |
488 | end = start + n - 1; | 526 | end = start + n - 1; |
@@ -511,7 +549,9 @@ void __release_region(struct resource *parent, unsigned long start, unsigned lon | |||
511 | 549 | ||
512 | write_unlock(&resource_lock); | 550 | write_unlock(&resource_lock); |
513 | 551 | ||
514 | printk(KERN_WARNING "Trying to free nonexistent resource <%08lx-%08lx>\n", start, end); | 552 | printk(KERN_WARNING "Trying to free nonexistent resource " |
553 | "<%016llx-%016llx>\n", (unsigned long long)start, | ||
554 | (unsigned long long)end); | ||
515 | } | 555 | } |
516 | 556 | ||
517 | EXPORT_SYMBOL(__release_region); | 557 | EXPORT_SYMBOL(__release_region); |