|
@@ -39,17 +39,20 @@ struct gen_pool *gen_pool_create(int min_alloc_order, int nid)
|
|
|
EXPORT_SYMBOL(gen_pool_create);
|
|
|
|
|
|
/**
|
|
|
- * gen_pool_add - add a new chunk of special memory to the pool
|
|
|
+ * gen_pool_add_virt - add a new chunk of special memory to the pool
|
|
|
* @pool: pool to add new memory chunk to
|
|
|
- * @addr: starting address of memory chunk to add to pool
|
|
|
+ * @virt: virtual starting address of memory chunk to add to pool
|
|
|
+ * @phys: physical starting address of memory chunk to add to pool
|
|
|
* @size: size in bytes of the memory chunk to add to pool
|
|
|
* @nid: node id of the node the chunk structure and bitmap should be
|
|
|
* allocated on, or -1
|
|
|
*
|
|
|
* Add a new chunk of special memory to the specified pool.
|
|
|
+ *
|
|
|
+ * Returns 0 on success or a -ve errno on failure.
|
|
|
*/
|
|
|
-int gen_pool_add(struct gen_pool *pool, unsigned long addr, size_t size,
|
|
|
- int nid)
|
|
|
+int gen_pool_add_virt(struct gen_pool *pool, unsigned long virt, phys_addr_t phys,
|
|
|
+ size_t size, int nid)
|
|
|
{
|
|
|
struct gen_pool_chunk *chunk;
|
|
|
int nbits = size >> pool->min_alloc_order;
|
|
@@ -58,11 +61,12 @@ int gen_pool_add(struct gen_pool *pool, unsigned long addr, size_t size,
|
|
|
|
|
|
chunk = kmalloc_node(nbytes, GFP_KERNEL | __GFP_ZERO, nid);
|
|
|
if (unlikely(chunk == NULL))
|
|
|
- return -1;
|
|
|
+ return -ENOMEM;
|
|
|
|
|
|
spin_lock_init(&chunk->lock);
|
|
|
- chunk->start_addr = addr;
|
|
|
- chunk->end_addr = addr + size;
|
|
|
+ chunk->phys_addr = phys;
|
|
|
+ chunk->start_addr = virt;
|
|
|
+ chunk->end_addr = virt + size;
|
|
|
|
|
|
write_lock(&pool->lock);
|
|
|
list_add(&chunk->next_chunk, &pool->chunks);
|
|
@@ -70,7 +74,32 @@ int gen_pool_add(struct gen_pool *pool, unsigned long addr, size_t size,
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
-EXPORT_SYMBOL(gen_pool_add);
|
|
|
+EXPORT_SYMBOL(gen_pool_add_virt);
|
|
|
+
|
|
|
+/**
|
|
|
+ * gen_pool_virt_to_phys - return the physical address of memory
|
|
|
+ * @pool: pool to allocate from
|
|
|
+ * @addr: starting address of memory
|
|
|
+ *
|
|
|
+ * Returns the physical address on success, or -1 on error.
|
|
|
+ */
|
|
|
+phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, unsigned long addr)
|
|
|
+{
|
|
|
+ struct list_head *_chunk;
|
|
|
+ struct gen_pool_chunk *chunk;
|
|
|
+
|
|
|
+ read_lock(&pool->lock);
|
|
|
+ list_for_each(_chunk, &pool->chunks) {
|
|
|
+ chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk);
|
|
|
+
|
|
|
+ if (addr >= chunk->start_addr && addr < chunk->end_addr)
|
|
|
+ return chunk->phys_addr + addr - chunk->start_addr;
|
|
|
+ }
|
|
|
+ read_unlock(&pool->lock);
|
|
|
+
|
|
|
+ return -1;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(gen_pool_virt_to_phys);
|
|
|
|
|
|
/**
|
|
|
* gen_pool_destroy - destroy a special memory pool
|