diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/lib/Makefile | 1 | ||||
-rw-r--r-- | arch/powerpc/lib/rheap.c | 24 |
2 files changed, 21 insertions, 4 deletions
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 8030f6245d82..a0360ae10d0c 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile | |||
@@ -14,6 +14,7 @@ endif | |||
14 | obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \ | 14 | obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \ |
15 | memcpy_64.o usercopy_64.o mem_64.o string.o \ | 15 | memcpy_64.o usercopy_64.o mem_64.o string.o \ |
16 | strcase.o | 16 | strcase.o |
17 | obj-$(CONFIG_QUICC_ENGINE) += rheap.o | ||
17 | obj-$(CONFIG_XMON) += sstep.o | 18 | obj-$(CONFIG_XMON) += sstep.o |
18 | 19 | ||
19 | ifeq ($(CONFIG_PPC64),y) | 20 | ifeq ($(CONFIG_PPC64),y) |
diff --git a/arch/powerpc/lib/rheap.c b/arch/powerpc/lib/rheap.c index 31e511856dc5..57bf991ccd6e 100644 --- a/arch/powerpc/lib/rheap.c +++ b/arch/powerpc/lib/rheap.c | |||
@@ -423,17 +423,21 @@ void *rh_detach_region(rh_info_t * info, void *start, int size) | |||
423 | return (void *)s; | 423 | return (void *)s; |
424 | } | 424 | } |
425 | 425 | ||
426 | void *rh_alloc(rh_info_t * info, int size, const char *owner) | 426 | void *rh_alloc_align(rh_info_t * info, int size, int alignment, const char *owner) |
427 | { | 427 | { |
428 | struct list_head *l; | 428 | struct list_head *l; |
429 | rh_block_t *blk; | 429 | rh_block_t *blk; |
430 | rh_block_t *newblk; | 430 | rh_block_t *newblk; |
431 | void *start; | 431 | void *start; |
432 | 432 | ||
433 | /* Validate size */ | 433 | /* Validate size, (must be power of two) */ |
434 | if (size <= 0) | 434 | if (size <= 0 || (alignment & (alignment - 1)) != 0) |
435 | return ERR_PTR(-EINVAL); | 435 | return ERR_PTR(-EINVAL); |
436 | 436 | ||
437 | /* given alignment larger that default rheap alignment */ | ||
438 | if (alignment > info->alignment) | ||
439 | size += alignment - 1; | ||
440 | |||
437 | /* Align to configured alignment */ | 441 | /* Align to configured alignment */ |
438 | size = (size + (info->alignment - 1)) & ~(info->alignment - 1); | 442 | size = (size + (info->alignment - 1)) & ~(info->alignment - 1); |
439 | 443 | ||
@@ -476,15 +480,27 @@ void *rh_alloc(rh_info_t * info, int size, const char *owner) | |||
476 | 480 | ||
477 | attach_taken_block(info, newblk); | 481 | attach_taken_block(info, newblk); |
478 | 482 | ||
483 | /* for larger alignment return fixed up pointer */ | ||
484 | /* this is no problem with the deallocator since */ | ||
485 | /* we scan for pointers that lie in the blocks */ | ||
486 | if (alignment > info->alignment) | ||
487 | start = (void *)(((unsigned long)start + alignment - 1) & | ||
488 | ~(alignment - 1)); | ||
489 | |||
479 | return start; | 490 | return start; |
480 | } | 491 | } |
481 | 492 | ||
493 | void *rh_alloc(rh_info_t * info, int size, const char *owner) | ||
494 | { | ||
495 | return rh_alloc_align(info, size, info->alignment, owner); | ||
496 | } | ||
497 | |||
482 | /* allocate at precisely the given address */ | 498 | /* allocate at precisely the given address */ |
483 | void *rh_alloc_fixed(rh_info_t * info, void *start, int size, const char *owner) | 499 | void *rh_alloc_fixed(rh_info_t * info, void *start, int size, const char *owner) |
484 | { | 500 | { |
485 | struct list_head *l; | 501 | struct list_head *l; |
486 | rh_block_t *blk, *newblk1, *newblk2; | 502 | rh_block_t *blk, *newblk1, *newblk2; |
487 | unsigned long s, e, m, bs, be; | 503 | unsigned long s, e, m, bs = 0, be = 0; |
488 | 504 | ||
489 | /* Validate size */ | 505 | /* Validate size */ |
490 | if (size <= 0) | 506 | if (size <= 0) |