diff options
Diffstat (limited to 'drivers/base/ump/src/imports')
-rwxr-xr-x | drivers/base/ump/src/imports/ion/Makefile | 52 | ||||
-rwxr-xr-x | drivers/base/ump/src/imports/ion/sconscript | 57 | ||||
-rwxr-xr-x | drivers/base/ump/src/imports/ion/ump_kernel_import_ion.c | 208 | ||||
-rwxr-xr-x | drivers/base/ump/src/imports/sconscript | 24 |
4 files changed, 341 insertions, 0 deletions
diff --git a/drivers/base/ump/src/imports/ion/Makefile b/drivers/base/ump/src/imports/ion/Makefile new file mode 100755 index 00000000000..2095fcca117 --- /dev/null +++ b/drivers/base/ump/src/imports/ion/Makefile @@ -0,0 +1,52 @@ +# +# (C) COPYRIGHT 2011 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. +# +# + + + +# default to building for the host +ARCH ?= $(shell uname -m) + +# linux build system integration + +ifneq ($(KERNELRELEASE),) +# Inside the kernel build system + +EXTRA_CFLAGS += -I$(KBUILD_EXTMOD) -I$(KBUILD_EXTMOD)/../../../../.. +KBUILD_EXTRA_SYMBOLS += "$(KBUILD_EXTMOD)/../../Module.symvers" + +SRC += ump_kernel_import_ion.c + +MODULE:=ump_ion_import.ko + +obj-m := $(MODULE:.ko=.o) +$(MODULE:.ko=-y) := $(SRC:.c=.o) +$(MODULE:.ko=-objs) := $(SRC:.c=.o) + +else +# Outside the kernel build system +# +# + +ifeq ($(KDIR),) +$(error Must specify KDIR to point to the kernel to target)) +endif + +all: + $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) + +clean: + $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) clean + +endif + diff --git a/drivers/base/ump/src/imports/ion/sconscript b/drivers/base/ump/src/imports/ion/sconscript new file mode 100755 index 00000000000..dde149076a2 --- /dev/null +++ b/drivers/base/ump/src/imports/ion/sconscript @@ -0,0 +1,57 @@ +# +# (C) COPYRIGHT 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. +# +# + + +import os +Import('env') + +# Clone the environment so changes don't affect other build files +env_ion = env.Clone() + +if env_ion['ump_ion'] != '1': + Return() + +if env_ion['v'] != '1': + env_ion['MAKECOMSTR'] = '[MAKE] ${SOURCE.dir}' + +# Source files required for UMP. +ion_src = [Glob('#kernel/drivers/base/ump/src/imports/ion/*.c')] + +# Note: cleaning via the Linux kernel build system does not yet work +if env_ion.GetOption('clean') : + makeAction=Action("cd ${SOURCE.dir} && make clean", '$MAKECOMSTR') +else: + if env['arch'] == 'x86_32' : + env_ion['arch_linux'] = 'x86' + elif 'arm' in env['arch']: + env_ion['arch_linux'] = 'arm' + else: + env_ion['arch_linux'] = env['arch'] + makeAction=Action("cd ${SOURCE.dir} && make ARCH=$arch_linux PLATFORM=${platform} && cp ump_ion_import.ko $STATIC_LIB_PATH/ump_ion_import.ko", '$MAKECOMSTR') +# The target is ump_import_ion.ko, built from the source in ion_src, via the action makeAction +# ump_import_ion.ko will be copied to $STATIC_LIB_PATH after being built by the standard Linux +# kernel build system, after which it can be installed to the directory specified if +# "libs_install" is set; this is done by LibTarget. +cmd = env_ion.Command('$STATIC_LIB_PATH/ump_ion_import.ko', ion_src, [makeAction]) + +# Until we fathom out how the invoke the Linux build system to clean, we can use Clean +# to remove generated files. + +patterns = ['*.mod.c', '*.o', '*.ko', '*.a', '.*.cmd', 'modules.order', '.tmp_versions', 'Module.symvers'] + +for p in patterns: + Clean(cmd, Glob('#kernel/drivers/base/ump/src/imports/ion/%s' % p)) + +env_ion.Depends('$STATIC_LIB_PATH/ump_ion_import.ko', '$STATIC_LIB_PATH/ump.ko') +env_ion.ProgTarget('ump', cmd) diff --git a/drivers/base/ump/src/imports/ion/ump_kernel_import_ion.c b/drivers/base/ump/src/imports/ion/ump_kernel_import_ion.c new file mode 100755 index 00000000000..9353e6aa987 --- /dev/null +++ b/drivers/base/ump/src/imports/ion/ump_kernel_import_ion.c @@ -0,0 +1,208 @@ +/* + * + * (C) COPYRIGHT 2011-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. + * + */ + + + +#include <linux/ump.h> +#include <linux/dma-mapping.h> +#include <linux/ion.h> +#include <linux/slab.h> +#include <linux/uaccess.h> +#include <linux/vmalloc.h> + +struct ion_wrapping_info +{ + struct ion_client * ion_client; + struct ion_handle * ion_handle; + int num_phys_blocks; + struct scatterlist * sglist; +}; + +static struct ion_device * ion_device_get(void) +{ + /* < Customer to provide implementation > + * Return a pointer to the global ion_device on the system + */ + return NULL; +} + +static unsigned int ion_heap_mask_get(void) +{ + /* < Customer to provide implementation > + * Return the heap mask to use with UMP clients. + * Suspect this can be kept as 0 as we won't allocate memory, just import. + */ + return 0; +} + +static int import_ion_client_create(void** const custom_session_data) +{ + struct ion_client ** ion_client; + + ion_client = (struct ion_client**)custom_session_data; + *ion_client = ion_client_create(ion_device_get(), ion_heap_mask_get(), "ump"); + + return PTR_RET(*ion_client); +} + + +static void import_ion_client_destroy(void* custom_session_data) +{ + struct ion_client * ion_client; + + ion_client = (struct ion_client*)custom_session_data; + BUG_ON(!ion_client); + + ion_client_destroy(ion_client); +} + + +static void import_ion_final_release_callback(const ump_dd_handle handle, void * info) +{ + struct ion_wrapping_info * ion_info; + + BUG_ON(!info); + + (void)handle; + ion_info = (struct ion_wrapping_info*)info; + + dma_unmap_sg(NULL, ion_info->sglist, ion_info->num_phys_blocks, DMA_BIDIRECTIONAL); + ion_unmap_dma(ion_info->ion_client, ion_info->ion_handle); + ion_free(ion_info->ion_client, ion_info->ion_handle); + kfree(ion_info); + module_put(THIS_MODULE); +} + +static ump_dd_handle import_ion_import(void * custom_session_data, void * pfd, ump_alloc_flags flags) +{ + int fd; + ump_dd_handle ump_handle; + struct scatterlist * sg; + int num_dma_blocks; + ump_dd_physical_block_64 * phys_blocks; + unsigned long i; + + struct ion_wrapping_info * ion_info; + + BUG_ON(!custom_session_data); + BUG_ON(!pfd); + + ion_info = kzalloc(GFP_KERNEL, sizeof(*ion_info)); + if (NULL == ion_info) + { + return UMP_DD_INVALID_MEMORY_HANDLE; + } + + ion_info->ion_client = (struct ion_client*)custom_session_data; + + if (get_user(fd, (int*)pfd)) + { + goto out; + } + + ion_info->ion_handle = ion_import_fd(ion_info->ion_client, fd); + + if (IS_ERR_OR_NULL(ion_info->ion_handle)) + { + goto out; + } + + ion_info->sglist = ion_map_dma(ion_info->ion_client, ion_info->ion_handle); + if (IS_ERR_OR_NULL(ion_info->sglist)) + { + goto ion_dma_map_failed; + } + + sg = ion_info->sglist; + while (sg) + { + ion_info->num_phys_blocks++; + sg = sg_next(sg); + } + + num_dma_blocks = dma_map_sg(NULL, ion_info->sglist, ion_info->num_phys_blocks, DMA_BIDIRECTIONAL); + + if (0 == num_dma_blocks) + { + goto linux_dma_map_failed; + } + + phys_blocks = vmalloc(num_dma_blocks * sizeof(*phys_blocks)); + if (NULL == phys_blocks) + { + goto vmalloc_failed; + } + + for_each_sg(ion_info->sglist, sg, num_dma_blocks, i) + { + phys_blocks[i].addr = sg_phys(sg); + phys_blocks[i].size = sg_dma_len(sg); + } + + ump_handle = ump_dd_create_from_phys_blocks_64(phys_blocks, num_dma_blocks, flags, NULL, import_ion_final_release_callback, ion_info); + + vfree(phys_blocks); + + if (ump_handle != UMP_DD_INVALID_MEMORY_HANDLE) + { + /* + * As we have a final release callback installed + * we must keep the module locked until + * the callback has been triggered + * */ + __module_get(THIS_MODULE); + return ump_handle; + } + + /* failed*/ +vmalloc_failed: + dma_unmap_sg(NULL, ion_info->sglist, ion_info->num_phys_blocks, DMA_BIDIRECTIONAL); +linux_dma_map_failed: + ion_unmap_dma(ion_info->ion_client, ion_info->ion_handle); +ion_dma_map_failed: + ion_free(ion_info->ion_client, ion_info->ion_handle); +out: + kfree(ion_info); + return UMP_DD_INVALID_MEMORY_HANDLE; +} + +struct ump_import_handler import_handler_ion = +{ + .linux_module = THIS_MODULE, + .session_begin = import_ion_client_create, + .session_end = import_ion_client_destroy, + .import = import_ion_import +}; + +static int __init import_ion_initialize_module(void) +{ + /* register with UMP */ + return ump_import_module_register(UMP_EXTERNAL_MEM_TYPE_ION, &import_handler_ion); +} + +static void __exit import_ion_cleanup_module(void) +{ + /* unregister import handler */ + ump_import_module_unregister(UMP_EXTERNAL_MEM_TYPE_ION); +} + +/* Setup init and exit functions for this module */ +module_init(import_ion_initialize_module); +module_exit(import_ion_cleanup_module); + +/* And some module information */ +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("ARM Ltd."); +MODULE_VERSION("1.0"); diff --git a/drivers/base/ump/src/imports/sconscript b/drivers/base/ump/src/imports/sconscript new file mode 100755 index 00000000000..a42c2f36e3a --- /dev/null +++ b/drivers/base/ump/src/imports/sconscript @@ -0,0 +1,24 @@ +# +# (C) COPYRIGHT 2011-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. +# +# + + +import os, sys +Import('env') + +import_modules = [ os.path.join( path, 'sconscript' ) for path in sorted(os.listdir( os.getcwd() )) ] + +for m in import_modules: + if os.path.exists(m): + SConscript( m, variant_dir=os.path.join( env['BUILD_DIR_PATH'], os.path.dirname(m) ), duplicate=0 ) + |