aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/resource.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/resource.c')
-rw-r--r--kernel/resource.c85
1 files changed, 67 insertions, 18 deletions
diff --git a/kernel/resource.c b/kernel/resource.c
index fb11a58b9594..4e9d87fd7bc5 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -188,6 +188,36 @@ static int __release_resource(struct resource *old)
188 return -EINVAL; 188 return -EINVAL;
189} 189}
190 190
191static void __release_child_resources(struct resource *r)
192{
193 struct resource *tmp, *p;
194 resource_size_t size;
195
196 p = r->child;
197 r->child = NULL;
198 while (p) {
199 tmp = p;
200 p = p->sibling;
201
202 tmp->parent = NULL;
203 tmp->sibling = NULL;
204 __release_child_resources(tmp);
205
206 printk(KERN_DEBUG "release child resource %pR\n", tmp);
207 /* need to restore size, and keep flags */
208 size = resource_size(tmp);
209 tmp->start = 0;
210 tmp->end = size - 1;
211 }
212}
213
214void release_child_resources(struct resource *r)
215{
216 write_lock(&resource_lock);
217 __release_child_resources(r);
218 write_unlock(&resource_lock);
219}
220
191/** 221/**
192 * request_resource - request and reserve an I/O or memory resource 222 * request_resource - request and reserve an I/O or memory resource
193 * @root: root resource descriptor 223 * @root: root resource descriptor
@@ -297,46 +327,63 @@ int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages,
297 327
298#endif 328#endif
299 329
330static int __is_ram(unsigned long pfn, unsigned long nr_pages, void *arg)
331{
332 return 1;
333}
334/*
335 * This generic page_is_ram() returns true if specified address is
336 * registered as "System RAM" in iomem_resource list.
337 */
338int __weak page_is_ram(unsigned long pfn)
339{
340 return walk_system_ram_range(pfn, 1, NULL, __is_ram) == 1;
341}
342
300/* 343/*
301 * Find empty slot in the resource tree given range and alignment. 344 * Find empty slot in the resource tree given range and alignment.
302 */ 345 */
303static int find_resource(struct resource *root, struct resource *new, 346static int find_resource(struct resource *root, struct resource *new,
304 resource_size_t size, resource_size_t min, 347 resource_size_t size, resource_size_t min,
305 resource_size_t max, resource_size_t align, 348 resource_size_t max, resource_size_t align,
306 void (*alignf)(void *, struct resource *, 349 resource_size_t (*alignf)(void *,
307 resource_size_t, resource_size_t), 350 const struct resource *,
351 resource_size_t,
352 resource_size_t),
308 void *alignf_data) 353 void *alignf_data)
309{ 354{
310 struct resource *this = root->child; 355 struct resource *this = root->child;
356 struct resource tmp = *new;
311 357
312 new->start = root->start; 358 tmp.start = root->start;
313 /* 359 /*
314 * Skip past an allocated resource that starts at 0, since the assignment 360 * Skip past an allocated resource that starts at 0, since the assignment
315 * of this->start - 1 to new->end below would cause an underflow. 361 * of this->start - 1 to tmp->end below would cause an underflow.
316 */ 362 */
317 if (this && this->start == 0) { 363 if (this && this->start == 0) {
318 new->start = this->end + 1; 364 tmp.start = this->end + 1;
319 this = this->sibling; 365 this = this->sibling;
320 } 366 }
321 for(;;) { 367 for(;;) {
322 if (this) 368 if (this)
323 new->end = this->start - 1; 369 tmp.end = this->start - 1;
324 else 370 else
325 new->end = root->end; 371 tmp.end = root->end;
326 if (new->start < min) 372 if (tmp.start < min)
327 new->start = min; 373 tmp.start = min;
328 if (new->end > max) 374 if (tmp.end > max)
329 new->end = max; 375 tmp.end = max;
330 new->start = ALIGN(new->start, align); 376 tmp.start = ALIGN(tmp.start, align);
331 if (alignf) 377 if (alignf)
332 alignf(alignf_data, new, size, align); 378 tmp.start = alignf(alignf_data, &tmp, size, align);
333 if (new->start < new->end && new->end - new->start >= size - 1) { 379 if (tmp.start < tmp.end && tmp.end - tmp.start >= size - 1) {
334 new->end = new->start + size - 1; 380 new->start = tmp.start;
381 new->end = tmp.start + size - 1;
335 return 0; 382 return 0;
336 } 383 }
337 if (!this) 384 if (!this)
338 break; 385 break;
339 new->start = this->end + 1; 386 tmp.start = this->end + 1;
340 this = this->sibling; 387 this = this->sibling;
341 } 388 }
342 return -EBUSY; 389 return -EBUSY;
@@ -356,8 +403,10 @@ static int find_resource(struct resource *root, struct resource *new,
356int allocate_resource(struct resource *root, struct resource *new, 403int allocate_resource(struct resource *root, struct resource *new,
357 resource_size_t size, resource_size_t min, 404 resource_size_t size, resource_size_t min,
358 resource_size_t max, resource_size_t align, 405 resource_size_t max, resource_size_t align,
359 void (*alignf)(void *, struct resource *, 406 resource_size_t (*alignf)(void *,
360 resource_size_t, resource_size_t), 407 const struct resource *,
408 resource_size_t,
409 resource_size_t),
361 void *alignf_data) 410 void *alignf_data)
362{ 411{
363 int err; 412 int err;