diff options
Diffstat (limited to 'drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_dynamic_pool.c')
-rw-r--r-- | drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_dynamic_pool.c | 233 |
1 files changed, 0 insertions, 233 deletions
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_dynamic_pool.c b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_dynamic_pool.c deleted file mode 100644 index f59fd99..0000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_dynamic_pool.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Support for Medifield PNW Camera Imaging ISP subsystem. - * - * Copyright (c) 2010 Intel Corporation. All Rights Reserved. - * - * Copyright (c) 2010 Silicon Hive www.siliconhive.com. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - */ -/* - * This file contains functions for dynamic memory pool management - */ -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/mm.h> - -#include <asm/set_memory.h> - -#include "atomisp_internal.h" - -#include "hmm/hmm_pool.h" - -/* - * dynamic memory pool ops. - */ -static unsigned int get_pages_from_dynamic_pool(void *pool, - struct hmm_page_object *page_obj, - unsigned int size, bool cached) -{ - struct hmm_page *hmm_page; - unsigned long flags; - unsigned int i = 0; - struct hmm_dynamic_pool_info *dypool_info = pool; - - if (!dypool_info) - return 0; - - spin_lock_irqsave(&dypool_info->list_lock, flags); - if (dypool_info->initialized) { - while (!list_empty(&dypool_info->pages_list)) { - hmm_page = list_entry(dypool_info->pages_list.next, - struct hmm_page, list); - - list_del(&hmm_page->list); - dypool_info->pgnr--; - spin_unlock_irqrestore(&dypool_info->list_lock, flags); - - page_obj[i].page = hmm_page->page; - page_obj[i++].type = HMM_PAGE_TYPE_DYNAMIC; - kmem_cache_free(dypool_info->pgptr_cache, hmm_page); - - if (i == size) - return i; - - spin_lock_irqsave(&dypool_info->list_lock, flags); - } - } - spin_unlock_irqrestore(&dypool_info->list_lock, flags); - - return i; -} - -static void free_pages_to_dynamic_pool(void *pool, - struct hmm_page_object *page_obj) -{ - struct hmm_page *hmm_page; - unsigned long flags; - int ret; - struct hmm_dynamic_pool_info *dypool_info = pool; - - if (!dypool_info) - return; - - spin_lock_irqsave(&dypool_info->list_lock, flags); - if (!dypool_info->initialized) { - spin_unlock_irqrestore(&dypool_info->list_lock, flags); - return; - } - spin_unlock_irqrestore(&dypool_info->list_lock, flags); - - if (page_obj->type == HMM_PAGE_TYPE_RESERVED) - return; - - if (dypool_info->pgnr >= dypool_info->pool_size) { - /* free page directly back to system */ - ret = set_pages_wb(page_obj->page, 1); - if (ret) - dev_err(atomisp_dev, - "set page to WB err ...ret=%d\n", ret); - /* - W/A: set_pages_wb seldom return value = -EFAULT - indicate that address of page is not in valid - range(0xffff880000000000~0xffffc7ffffffffff) - then, _free_pages would panic; Do not know why page - address be valid, it maybe memory corruption by lowmemory - */ - if (!ret) { - __free_pages(page_obj->page, 0); - hmm_mem_stat.sys_size--; - } - return; - } - hmm_page = kmem_cache_zalloc(dypool_info->pgptr_cache, - GFP_KERNEL); - if (!hmm_page) { - /* free page directly */ - ret = set_pages_wb(page_obj->page, 1); - if (ret) - dev_err(atomisp_dev, - "set page to WB err ...ret=%d\n", ret); - if (!ret) { - __free_pages(page_obj->page, 0); - hmm_mem_stat.sys_size--; - } - return; - } - - hmm_page->page = page_obj->page; - - /* - * add to pages_list of pages_pool - */ - spin_lock_irqsave(&dypool_info->list_lock, flags); - list_add_tail(&hmm_page->list, &dypool_info->pages_list); - dypool_info->pgnr++; - spin_unlock_irqrestore(&dypool_info->list_lock, flags); - hmm_mem_stat.dyc_size++; -} - -static int hmm_dynamic_pool_init(void **pool, unsigned int pool_size) -{ - struct hmm_dynamic_pool_info *dypool_info; - - if (pool_size == 0) - return 0; - - dypool_info = kmalloc(sizeof(struct hmm_dynamic_pool_info), - GFP_KERNEL); - if (unlikely(!dypool_info)) - return -ENOMEM; - - dypool_info->pgptr_cache = kmem_cache_create("pgptr_cache", - sizeof(struct hmm_page), 0, - SLAB_HWCACHE_ALIGN, NULL); - if (!dypool_info->pgptr_cache) { - kfree(dypool_info); - return -ENOMEM; - } - - INIT_LIST_HEAD(&dypool_info->pages_list); - spin_lock_init(&dypool_info->list_lock); - dypool_info->initialized = true; - dypool_info->pool_size = pool_size; - dypool_info->pgnr = 0; - - *pool = dypool_info; - - return 0; -} - -static void hmm_dynamic_pool_exit(void **pool) -{ - struct hmm_dynamic_pool_info *dypool_info = *pool; - struct hmm_page *hmm_page; - unsigned long flags; - int ret; - - if (!dypool_info) - return; - - spin_lock_irqsave(&dypool_info->list_lock, flags); - if (!dypool_info->initialized) { - spin_unlock_irqrestore(&dypool_info->list_lock, flags); - return; - } - dypool_info->initialized = false; - - while (!list_empty(&dypool_info->pages_list)) { - hmm_page = list_entry(dypool_info->pages_list.next, - struct hmm_page, list); - - list_del(&hmm_page->list); - spin_unlock_irqrestore(&dypool_info->list_lock, flags); - - /* can cause thread sleep, so cannot be put into spin_lock */ - ret = set_pages_wb(hmm_page->page, 1); - if (ret) - dev_err(atomisp_dev, - "set page to WB err...ret=%d\n", ret); - if (!ret) { - __free_pages(hmm_page->page, 0); - hmm_mem_stat.dyc_size--; - hmm_mem_stat.sys_size--; - } - kmem_cache_free(dypool_info->pgptr_cache, hmm_page); - spin_lock_irqsave(&dypool_info->list_lock, flags); - } - - spin_unlock_irqrestore(&dypool_info->list_lock, flags); - - kmem_cache_destroy(dypool_info->pgptr_cache); - - kfree(dypool_info); - - *pool = NULL; -} - -static int hmm_dynamic_pool_inited(void *pool) -{ - struct hmm_dynamic_pool_info *dypool_info = pool; - - if (!dypool_info) - return 0; - - return dypool_info->initialized; -} - -struct hmm_pool_ops dynamic_pops = { - .pool_init = hmm_dynamic_pool_init, - .pool_exit = hmm_dynamic_pool_exit, - .pool_alloc_pages = get_pages_from_dynamic_pool, - .pool_free_pages = free_pages_to_dynamic_pool, - .pool_inited = hmm_dynamic_pool_inited, -}; |