diff options
Diffstat (limited to 'drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c')
-rw-r--r-- | drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c | 287 |
1 files changed, 0 insertions, 287 deletions
diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c deleted file mode 100644 index 82c16cc..0000000 --- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/* needed to detect kernel version specific code */ -#include <linux/version.h> - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) -#include <linux/semaphore.h> -#else /* pre 2.6.26 the file was in the arch specific location */ -#include <asm/semaphore.h> -#endif - -#include <linux/mm.h> -#include <linux/slab.h> -#include <asm/atomic.h> -#include <linux/vmalloc.h> -#include "ump_kernel_common.h" -#include "ump_kernel_memory_backend.h" - - - -#define UMP_BLOCK_SIZE (256UL * 1024UL) /* 256kB, remember to keep the ()s */ - - - -typedef struct block_info -{ - struct block_info * next; -} block_info; - - - -typedef struct block_allocator -{ - struct semaphore mutex; - block_info * all_blocks; - block_info * first_free; - u32 base; - u32 num_blocks; - u32 num_free; -} block_allocator; - - -static void block_allocator_shutdown(ump_memory_backend * backend); -static int block_allocator_allocate(void* ctx, ump_dd_mem * mem); -static void block_allocator_release(void * ctx, ump_dd_mem * handle); -static inline u32 get_phys(block_allocator * allocator, block_info * block); -static u32 block_allocator_stat(struct ump_memory_backend *backend); - - - -/* - * Create dedicated memory backend - */ -ump_memory_backend * ump_block_allocator_create(u32 base_address, u32 size) -{ - ump_memory_backend * backend; - block_allocator * allocator; - u32 usable_size; - u32 num_blocks; - - usable_size = (size + UMP_BLOCK_SIZE - 1) & ~(UMP_BLOCK_SIZE - 1); - num_blocks = usable_size / UMP_BLOCK_SIZE; - - if (0 == usable_size) - { - DBG_MSG(1, ("Memory block of size %u is unusable\n", size)); - return NULL; - } - - DBG_MSG(5, ("Creating dedicated UMP memory backend. Base address: 0x%08x, size: 0x%08x\n", base_address, size)); - DBG_MSG(6, ("%u usable bytes which becomes %u blocks\n", usable_size, num_blocks)); - - backend = kzalloc(sizeof(ump_memory_backend), GFP_KERNEL); - if (NULL != backend) - { - allocator = kmalloc(sizeof(block_allocator), GFP_KERNEL); - if (NULL != allocator) - { - allocator->all_blocks = kmalloc(sizeof(block_allocator) * num_blocks, GFP_KERNEL); - if (NULL != allocator->all_blocks) - { - int i; - - allocator->first_free = NULL; - allocator->num_blocks = num_blocks; - allocator->num_free = num_blocks; - allocator->base = base_address; - sema_init(&allocator->mutex, 1); - - for (i = 0; i < num_blocks; i++) - { - allocator->all_blocks[i].next = allocator->first_free; - allocator->first_free = &allocator->all_blocks[i]; - } - - backend->ctx = allocator; - backend->allocate = block_allocator_allocate; - backend->release = block_allocator_release; - backend->shutdown = block_allocator_shutdown; - backend->stat = block_allocator_stat; - backend->pre_allocate_physical_check = NULL; - backend->adjust_to_mali_phys = NULL; - backend->get = NULL; - backend->set = NULL; - - return backend; - } - kfree(allocator); - } - kfree(backend); - } - - return NULL; -} - - - -/* - * Destroy specified dedicated memory backend - */ -static void block_allocator_shutdown(ump_memory_backend * backend) -{ - block_allocator * allocator; - - BUG_ON(!backend); - BUG_ON(!backend->ctx); - - allocator = (block_allocator*)backend->ctx; - - DBG_MSG_IF(1, allocator->num_free != allocator->num_blocks, ("%u blocks still in use during shutdown\n", allocator->num_blocks - allocator->num_free)); - - kfree(allocator->all_blocks); - kfree(allocator); - kfree(backend); -} - - - -static int block_allocator_allocate(void* ctx, ump_dd_mem * mem) -{ - block_allocator * allocator; - u32 left; - block_info * last_allocated = NULL; - int i = 0; - - BUG_ON(!ctx); - BUG_ON(!mem); - - allocator = (block_allocator*)ctx; - left = mem->size_bytes; - - BUG_ON(!left); - BUG_ON(!&allocator->mutex); - - mem->nr_blocks = ((left + UMP_BLOCK_SIZE - 1) & ~(UMP_BLOCK_SIZE - 1)) / UMP_BLOCK_SIZE; - mem->block_array = (ump_dd_physical_block*)vmalloc(sizeof(ump_dd_physical_block) * mem->nr_blocks); - if (NULL == mem->block_array) - { - MSG_ERR(("Failed to allocate block array\n")); - return 0; - } - - if (down_interruptible(&allocator->mutex)) - { - MSG_ERR(("Could not get mutex to do block_allocate\n")); - return 0; - } - - mem->size_bytes = 0; - - while ((left > 0) && (allocator->first_free)) - { - block_info * block; - - block = allocator->first_free; - allocator->first_free = allocator->first_free->next; - block->next = last_allocated; - last_allocated = block; - allocator->num_free--; - - mem->block_array[i].addr = get_phys(allocator, block); - mem->block_array[i].size = UMP_BLOCK_SIZE; - mem->size_bytes += UMP_BLOCK_SIZE; - - i++; - - if (left < UMP_BLOCK_SIZE) left = 0; - else left -= UMP_BLOCK_SIZE; - } - - if (left) - { - block_info * block; - /* release all memory back to the pool */ - while (last_allocated) - { - block = last_allocated->next; - last_allocated->next = allocator->first_free; - allocator->first_free = last_allocated; - last_allocated = block; - allocator->num_free++; - } - - vfree(mem->block_array); - mem->backend_info = NULL; - mem->block_array = NULL; - - DBG_MSG(4, ("Could not find a mem-block for the allocation.\n")); - up(&allocator->mutex); - - return 0; - } - - mem->backend_info = last_allocated; - - up(&allocator->mutex); - mem->is_cached=0; - - return 1; -} - - - -static void block_allocator_release(void * ctx, ump_dd_mem * handle) -{ - block_allocator * allocator; - block_info * block, * next; - - BUG_ON(!ctx); - BUG_ON(!handle); - - allocator = (block_allocator*)ctx; - block = (block_info*)handle->backend_info; - BUG_ON(!block); - - if (down_interruptible(&allocator->mutex)) - { - MSG_ERR(("Allocator release: Failed to get mutex - memory leak\n")); - return; - } - - while (block) - { - next = block->next; - - BUG_ON( (block < allocator->all_blocks) || (block > (allocator->all_blocks + allocator->num_blocks))); - - block->next = allocator->first_free; - allocator->first_free = block; - allocator->num_free++; - - block = next; - } - DBG_MSG(3, ("%d blocks free after release call\n", allocator->num_free)); - up(&allocator->mutex); - - vfree(handle->block_array); - handle->block_array = NULL; -} - - - -/* - * Helper function for calculating the physical base adderss of a memory block - */ -static inline u32 get_phys(block_allocator * allocator, block_info * block) -{ - return allocator->base + ((block - allocator->all_blocks) * UMP_BLOCK_SIZE); -} - -static u32 block_allocator_stat(struct ump_memory_backend *backend) -{ - block_allocator *allocator; - BUG_ON(!backend); - allocator = (block_allocator*)backend->ctx; - BUG_ON(!allocator); - - return (allocator->num_blocks - allocator->num_free)* UMP_BLOCK_SIZE; -} |