aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhao Qiang <qiang.zhao@freescale.com>2015-11-29 21:48:53 -0500
committerScott Wood <scottwood@freescale.com>2015-12-22 18:10:17 -0500
commitb26981c8f743d3cb64a6907eb1f5c6c4ba6ca672 (patch)
tree60c2eb0964020d0ffe5fbe51f68d9bc03d89655c
parentde2dd0eb30af55d3893979d5641c50c7a8969c99 (diff)
genalloc:support allocating specific region
Add new algo for genalloc, it reserve a specific region of memory Signed-off-by: Zhao Qiang <qiang.zhao@freescale.com> Signed-off-by: Scott Wood <scottwood@freescale.com>
-rw-r--r--include/linux/genalloc.h11
-rw-r--r--lib/genalloc.c32
2 files changed, 43 insertions, 0 deletions
diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h
index 3c676ce46ee0..29d4385903d4 100644
--- a/include/linux/genalloc.h
+++ b/include/linux/genalloc.h
@@ -84,6 +84,13 @@ struct genpool_data_align {
84 int align; /* alignment by bytes for starting address */ 84 int align; /* alignment by bytes for starting address */
85}; 85};
86 86
87/*
88 * gen_pool data descriptor for gen_pool_fixed_alloc.
89 */
90struct genpool_data_fixed {
91 unsigned long offset; /* The offset of the specific region */
92};
93
87extern struct gen_pool *gen_pool_create(int, int); 94extern struct gen_pool *gen_pool_create(int, int);
88extern phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, unsigned long); 95extern phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, unsigned long);
89extern int gen_pool_add_virt(struct gen_pool *, unsigned long, phys_addr_t, 96extern int gen_pool_add_virt(struct gen_pool *, unsigned long, phys_addr_t,
@@ -124,6 +131,10 @@ extern unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size,
124 unsigned long start, unsigned int nr, void *data, 131 unsigned long start, unsigned int nr, void *data,
125 struct gen_pool *pool); 132 struct gen_pool *pool);
126 133
134extern unsigned long gen_pool_fixed_alloc(unsigned long *map,
135 unsigned long size, unsigned long start, unsigned int nr,
136 void *data, struct gen_pool *pool);
137
127extern unsigned long gen_pool_first_fit_align(unsigned long *map, 138extern unsigned long gen_pool_first_fit_align(unsigned long *map,
128 unsigned long size, unsigned long start, unsigned int nr, 139 unsigned long size, unsigned long start, unsigned int nr,
129 void *data, struct gen_pool *pool); 140 void *data, struct gen_pool *pool);
diff --git a/lib/genalloc.c b/lib/genalloc.c
index b8cf89d9e17d..5ec83cd93284 100644
--- a/lib/genalloc.c
+++ b/lib/genalloc.c
@@ -556,6 +556,38 @@ unsigned long gen_pool_first_fit_align(unsigned long *map, unsigned long size,
556EXPORT_SYMBOL(gen_pool_first_fit_align); 556EXPORT_SYMBOL(gen_pool_first_fit_align);
557 557
558/** 558/**
559 * gen_pool_fixed_alloc - reserve a specific region
560 * @map: The address to base the search on
561 * @size: The bitmap size in bits
562 * @start: The bitnumber to start searching at
563 * @nr: The number of zeroed bits we're looking for
564 * @data: data for alignment
565 * @pool: pool to get order from
566 */
567unsigned long gen_pool_fixed_alloc(unsigned long *map, unsigned long size,
568 unsigned long start, unsigned int nr, void *data,
569 struct gen_pool *pool)
570{
571 struct genpool_data_fixed *fixed_data;
572 int order;
573 unsigned long offset_bit;
574 unsigned long start_bit;
575
576 fixed_data = data;
577 order = pool->min_alloc_order;
578 offset_bit = fixed_data->offset >> order;
579 if (WARN_ON(fixed_data->offset & (1UL << order - 1)))
580 return size;
581
582 start_bit = bitmap_find_next_zero_area(map, size,
583 start + offset_bit, nr, 0);
584 if (start_bit != offset_bit)
585 start_bit = size;
586 return start_bit;
587}
588EXPORT_SYMBOL(gen_pool_fixed_alloc);
589
590/**
559 * gen_pool_first_fit_order_align - find the first available region 591 * gen_pool_first_fit_order_align - find the first available region
560 * of memory matching the size requirement. The region will be aligned 592 * of memory matching the size requirement. The region will be aligned
561 * to the order of the size specified. 593 * to the order of the size specified.