scripts: remove unused function in sortextable.c
[GitHub/LineageOS/android_kernel_samsung_universal7580.git] / lib / genalloc.c
index b35cfa9bc3d42d9e0303d0ec07c2c473fd64618c..c2833f0d5d9b964b1ae7aa65ec284c332d8d5105 100644 (file)
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 
+static inline size_t chunk_size(const struct gen_pool_chunk *chunk)
+{
+       return chunk->end_addr - chunk->start_addr + 1;
+}
+
 static int set_bits_ll(unsigned long *addr, unsigned long mask_to_set)
 {
        unsigned long val, nval;
@@ -188,7 +193,7 @@ int gen_pool_add_virt(struct gen_pool *pool, unsigned long virt, phys_addr_t phy
 
        chunk->phys_addr = phys;
        chunk->start_addr = virt;
-       chunk->end_addr = virt + size;
+       chunk->end_addr = virt + size - 1;
        atomic_set(&chunk->avail, size);
 
        spin_lock(&pool->lock);
@@ -213,7 +218,7 @@ phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, unsigned long addr)
 
        rcu_read_lock();
        list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk) {
-               if (addr >= chunk->start_addr && addr < chunk->end_addr) {
+               if (addr >= chunk->start_addr && addr <= chunk->end_addr) {
                        paddr = chunk->phys_addr + (addr - chunk->start_addr);
                        break;
                }
@@ -242,7 +247,7 @@ void gen_pool_destroy(struct gen_pool *pool)
                chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk);
                list_del(&chunk->next_chunk);
 
-               end_bit = (chunk->end_addr - chunk->start_addr) >> order;
+               end_bit = chunk_size(chunk) >> order;
                bit = find_next_bit(chunk->bits, end_bit, 0);
                BUG_ON(bit < end_bit);
 
@@ -268,7 +273,7 @@ unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size)
        struct gen_pool_chunk *chunk;
        unsigned long addr = 0;
        int order = pool->min_alloc_order;
-       int nbits, start_bit = 0, end_bit, remain;
+       int nbits, start_bit, end_bit, remain;
 
 #ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG
        BUG_ON(in_nmi());
@@ -283,7 +288,8 @@ unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size)
                if (size > atomic_read(&chunk->avail))
                        continue;
 
-               end_bit = (chunk->end_addr - chunk->start_addr) >> order;
+               start_bit = 0;
+               end_bit = chunk_size(chunk) >> order;
 retry:
                start_bit = pool->algo(chunk->bits, end_bit, start_bit, nbits,
                                pool->data);
@@ -330,8 +336,8 @@ void gen_pool_free(struct gen_pool *pool, unsigned long addr, size_t size)
        nbits = (size + (1UL << order) - 1) >> order;
        rcu_read_lock();
        list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk) {
-               if (addr >= chunk->start_addr && addr < chunk->end_addr) {
-                       BUG_ON(addr + size > chunk->end_addr);
+               if (addr >= chunk->start_addr && addr <= chunk->end_addr) {
+                       BUG_ON(addr + size - 1 > chunk->end_addr);
                        start_bit = (addr - chunk->start_addr) >> order;
                        remain = bitmap_clear_ll(chunk->bits, start_bit, nbits);
                        BUG_ON(remain);
@@ -368,6 +374,35 @@ void gen_pool_for_each_chunk(struct gen_pool *pool,
 }
 EXPORT_SYMBOL(gen_pool_for_each_chunk);
 
+/**
+ * addr_in_gen_pool - checks if an address falls within the range of a pool
+ * @pool:      the generic memory pool
+ * @start:     start address
+ * @size:      size of the region
+ *
+ * Check if the range of addresses falls within the specified pool. Returns
+ * true if the entire range is contained in the pool and false otherwise.
+ */
+bool addr_in_gen_pool(struct gen_pool *pool, unsigned long start,
+                       size_t size)
+{
+       bool found = false;
+       unsigned long end = start + size;
+       struct gen_pool_chunk *chunk;
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(chunk, &(pool)->chunks, next_chunk) {
+               if (start >= chunk->start_addr && start <= chunk->end_addr) {
+                       if (end <= chunk->end_addr) {
+                               found = true;
+                               break;
+                       }
+               }
+       }
+       rcu_read_unlock();
+       return found;
+}
+
 /**
  * gen_pool_avail - get available free space of the pool
  * @pool: pool to get available free space
@@ -400,7 +435,7 @@ size_t gen_pool_size(struct gen_pool *pool)
 
        rcu_read_lock();
        list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk)
-               size += chunk->end_addr - chunk->start_addr;
+               size += chunk_size(chunk);
        rcu_read_unlock();
        return size;
 }
@@ -446,6 +481,26 @@ unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size,
 }
 EXPORT_SYMBOL(gen_pool_first_fit);
 
+/**
+ * gen_pool_first_fit_order_align - find the first available region
+ * of memory matching the size requirement. The region will be aligned
+ * to the order of the size specified.
+ * @map: The address to base the search on
+ * @size: The bitmap size in bits
+ * @start: The bitnumber to start searching at
+ * @nr: The number of zeroed bits we're looking for
+ * @data: additional data - unused
+ */
+unsigned long gen_pool_first_fit_order_align(unsigned long *map,
+               unsigned long size, unsigned long start,
+               unsigned int nr, void *data)
+{
+       unsigned long align_mask = roundup_pow_of_two(nr) - 1;
+
+       return bitmap_find_next_zero_area(map, size, start, nr, align_mask);
+}
+EXPORT_SYMBOL(gen_pool_first_fit_order_align);
+
 /**
  * gen_pool_best_fit - find the best fitting region of memory
  * macthing the size requirement (no alignment constraint)