From 3922298f52d193d5e014bf4d28e423cf7bd0b50e Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 29 Aug 2013 17:50:42 -0700 Subject: [PATCH 01/54] gpu: ion: delete ion_system_mapper.c The mapper abstraction layer was removed before the initial ion commit, but a stray ion_system_mapper.c file was left in. Delete it. Change-Id: I0001d1ea1b866ebd7ec1306e94472c67a094855f Signed-off-by: Colin Cross --- drivers/gpu/ion/ion_system_mapper.c | 114 ---------------------------- 1 file changed, 114 deletions(-) delete mode 100644 drivers/gpu/ion/ion_system_mapper.c diff --git a/drivers/gpu/ion/ion_system_mapper.c b/drivers/gpu/ion/ion_system_mapper.c deleted file mode 100644 index 692458e07b5e..000000000000 --- a/drivers/gpu/ion/ion_system_mapper.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * drivers/gpu/ion/ion_system_mapper.c - * - * Copyright (C) 2011 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include "ion_priv.h" -/* - * This mapper is valid for any heap that allocates memory that already has - * a kernel mapping, this includes vmalloc'd memory, kmalloc'd memory, - * pages obtained via io_remap, etc. - */ -static void *ion_kernel_mapper_map(struct ion_mapper *mapper, - struct ion_buffer *buffer, - struct ion_mapping **mapping) -{ - if (!((1 << buffer->heap->type) & mapper->heap_mask)) { - pr_err("%s: attempting to map an unsupported heap\n", __func__); - return ERR_PTR(-EINVAL); - } - /* XXX REVISIT ME!!! */ - *((unsigned long *)mapping) = (unsigned long)buffer->priv; - return buffer->priv; -} - -static void ion_kernel_mapper_unmap(struct ion_mapper *mapper, - struct ion_buffer *buffer, - struct ion_mapping *mapping) -{ - if (!((1 << buffer->heap->type) & mapper->heap_mask)) - pr_err("%s: attempting to unmap an unsupported heap\n", - __func__); -} - -static void *ion_kernel_mapper_map_kernel(struct ion_mapper *mapper, - struct ion_buffer *buffer, - struct ion_mapping *mapping) -{ - if (!((1 << buffer->heap->type) & mapper->heap_mask)) { - pr_err("%s: attempting to unmap an unsupported heap\n", - __func__); - return ERR_PTR(-EINVAL); - } - return buffer->priv; -} - -static int ion_kernel_mapper_map_user(struct ion_mapper *mapper, - struct ion_buffer *buffer, - struct vm_area_struct *vma, - struct ion_mapping *mapping) -{ - int ret; - - switch (buffer->heap->type) { - case ION_HEAP_KMALLOC: - { - unsigned long pfn = __phys_to_pfn(virt_to_phys(buffer->priv)); - ret = remap_pfn_range(vma, vma->vm_start, pfn + vma->vm_pgoff, - vma->vm_end - vma->vm_start, - vma->vm_page_prot); - break; - } - case ION_HEAP_VMALLOC: - ret = remap_vmalloc_range(vma, buffer->priv, vma->vm_pgoff); - break; - default: - pr_err("%s: attempting to map unsupported heap to userspace\n", - __func__); - return -EINVAL; - } - - return ret; -} - -static struct ion_mapper_ops ops = { - .map = ion_kernel_mapper_map, - .map_kernel = ion_kernel_mapper_map_kernel, - .map_user = ion_kernel_mapper_map_user, - .unmap = ion_kernel_mapper_unmap, -}; - -struct ion_mapper *ion_system_mapper_create(void) -{ - struct ion_mapper *mapper; - mapper = kzalloc(sizeof(struct ion_mapper), GFP_KERNEL); - if (!mapper) - return ERR_PTR(-ENOMEM); - mapper->type = ION_SYSTEM_MAPPER; - mapper->ops = &ops; - mapper->heap_mask = (1 << ION_HEAP_VMALLOC) | (1 << ION_HEAP_KMALLOC); - return mapper; -} - -void ion_system_mapper_destroy(struct ion_mapper *mapper) -{ - kfree(mapper); -} - From 8cb378f23cb15b6d7e5d57bde7bac8f157c9d301 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 7 Nov 2013 12:25:56 -0800 Subject: [PATCH 02/54] ion: move into staging Move ion from drivers/gpu/ion to drivers/android/staging/ion. Change-Id: Id6e996aa3954cbb8e1a8abc9578a56204f5eb211 Signed-off-by: Colin Cross --- drivers/gpu/Makefile | 2 +- drivers/staging/android/Kconfig | 2 ++ drivers/staging/android/Makefile | 2 ++ drivers/{gpu => staging/android}/ion/Kconfig | 0 drivers/{gpu => staging/android}/ion/Makefile | 0 drivers/{gpu => staging/android}/ion/compat_ion.c | 4 ++-- drivers/{gpu => staging/android}/ion/compat_ion.h | 0 drivers/{gpu => staging/android}/ion/ion.c | 2 +- {include/linux => drivers/staging/android/ion}/ion.h | 2 +- drivers/{gpu => staging/android}/ion/ion_carveout_heap.c | 2 +- drivers/{gpu => staging/android}/ion/ion_chunk_heap.c | 2 +- drivers/{gpu => staging/android}/ion/ion_cma_heap.c | 3 +-- drivers/{gpu => staging/android}/ion/ion_heap.c | 2 +- drivers/{gpu => staging/android}/ion/ion_page_pool.c | 0 drivers/{gpu => staging/android}/ion/ion_priv.h | 3 ++- drivers/{gpu => staging/android}/ion/ion_system_heap.c | 2 +- drivers/{gpu => staging/android}/ion/tegra/Makefile | 0 drivers/{gpu => staging/android}/ion/tegra/tegra_ion.c | 2 +- drivers/video/Kconfig | 2 -- 19 files changed, 17 insertions(+), 15 deletions(-) rename drivers/{gpu => staging/android}/ion/Kconfig (100%) rename drivers/{gpu => staging/android}/ion/Makefile (100%) rename drivers/{gpu => staging/android}/ion/compat_ion.c (97%) rename drivers/{gpu => staging/android}/ion/compat_ion.h (100%) rename drivers/{gpu => staging/android}/ion/ion.c (99%) rename {include/linux => drivers/staging/android/ion}/ion.h (99%) rename drivers/{gpu => staging/android}/ion/ion_carveout_heap.c (99%) rename drivers/{gpu => staging/android}/ion/ion_chunk_heap.c (99%) rename drivers/{gpu => staging/android}/ion/ion_cma_heap.c (98%) rename drivers/{gpu => staging/android}/ion/ion_heap.c (99%) rename drivers/{gpu => staging/android}/ion/ion_page_pool.c (100%) rename drivers/{gpu => staging/android}/ion/ion_priv.h (99%) rename drivers/{gpu => staging/android}/ion/ion_system_heap.c (99%) rename drivers/{gpu => staging/android}/ion/tegra/Makefile (100%) rename drivers/{gpu => staging/android}/ion/tegra/tegra_ion.c (98%) diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile index a2efb62aa776..d8a22c2a579d 100644 --- a/drivers/gpu/Makefile +++ b/drivers/gpu/Makefile @@ -1,2 +1,2 @@ -obj-y += drm/ vga/ ion/ +obj-y += drm/ vga/ obj-$(CONFIG_TEGRA_HOST1X) += host1x/ diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig index fe11eb6fa966..6da535db2538 100644 --- a/drivers/staging/android/Kconfig +++ b/drivers/staging/android/Kconfig @@ -108,6 +108,8 @@ config SW_SYNC_USER *WARNING* improper use of this can result in deadlocking kernel drivers from userspace. +source "drivers/staging/android/ion/Kconfig" + endif # if ANDROID endmenu diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile index c136299e05af..0a01e1914905 100644 --- a/drivers/staging/android/Makefile +++ b/drivers/staging/android/Makefile @@ -1,5 +1,7 @@ ccflags-y += -I$(src) # needed for trace events +obj-y += ion/ + obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o obj-$(CONFIG_ASHMEM) += ashmem.o obj-$(CONFIG_ANDROID_LOGGER) += logger.o diff --git a/drivers/gpu/ion/Kconfig b/drivers/staging/android/ion/Kconfig similarity index 100% rename from drivers/gpu/ion/Kconfig rename to drivers/staging/android/ion/Kconfig diff --git a/drivers/gpu/ion/Makefile b/drivers/staging/android/ion/Makefile similarity index 100% rename from drivers/gpu/ion/Makefile rename to drivers/staging/android/ion/Makefile diff --git a/drivers/gpu/ion/compat_ion.c b/drivers/staging/android/ion/compat_ion.c similarity index 97% rename from drivers/gpu/ion/compat_ion.c rename to drivers/staging/android/ion/compat_ion.c index e0d2839952a0..0416fabfc1b9 100644 --- a/drivers/gpu/ion/compat_ion.c +++ b/drivers/staging/android/ion/compat_ion.c @@ -14,14 +14,14 @@ * */ -#include #include #include #include +#include "ion.h" #include "compat_ion.h" -/* See include/linux/ion.h for the definition of these structs */ +/* See drivers/staging/android/uapi/ion.h for the definition of these structs */ struct compat_ion_allocation_data { compat_size_t len; compat_size_t align; diff --git a/drivers/gpu/ion/compat_ion.h b/drivers/staging/android/ion/compat_ion.h similarity index 100% rename from drivers/gpu/ion/compat_ion.h rename to drivers/staging/android/ion/compat_ion.h diff --git a/drivers/gpu/ion/ion.c b/drivers/staging/android/ion/ion.c similarity index 99% rename from drivers/gpu/ion/ion.c rename to drivers/staging/android/ion/ion.c index e4ffc9d5b94b..5c886fc9cd7e 100644 --- a/drivers/gpu/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -37,6 +36,7 @@ #include #include +#include "ion.h" #include "ion_priv.h" #include "compat_ion.h" diff --git a/include/linux/ion.h b/drivers/staging/android/ion/ion.h similarity index 99% rename from include/linux/ion.h rename to drivers/staging/android/ion/ion.h index 5771f8c3d3ac..6b4d9fbeaec4 100644 --- a/include/linux/ion.h +++ b/drivers/staging/android/ion/ion.h @@ -1,5 +1,5 @@ /* - * include/linux/ion.h + * drivers/staging/android/ion/ion.h * * Copyright (C) 2011 Google, Inc. * diff --git a/drivers/gpu/ion/ion_carveout_heap.c b/drivers/staging/android/ion/ion_carveout_heap.c similarity index 99% rename from drivers/gpu/ion/ion_carveout_heap.c rename to drivers/staging/android/ion/ion_carveout_heap.c index 86f35545eaf7..4a94b17da67e 100644 --- a/drivers/gpu/ion/ion_carveout_heap.c +++ b/drivers/staging/android/ion/ion_carveout_heap.c @@ -18,11 +18,11 @@ #include #include #include -#include #include #include #include #include +#include "ion.h" #include "ion_priv.h" #include diff --git a/drivers/gpu/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c similarity index 99% rename from drivers/gpu/ion/ion_chunk_heap.c rename to drivers/staging/android/ion/ion_chunk_heap.c index 15c9d7ad2502..a2b2e1b7af38 100644 --- a/drivers/gpu/ion/ion_chunk_heap.c +++ b/drivers/staging/android/ion/ion_chunk_heap.c @@ -18,11 +18,11 @@ #include #include #include -#include #include #include #include #include +#include "ion.h" #include "ion_priv.h" #include diff --git a/drivers/gpu/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c similarity index 98% rename from drivers/gpu/ion/ion_cma_heap.c rename to drivers/staging/android/ion/ion_cma_heap.c index 1eaa8c11e04c..55d6003f546c 100644 --- a/drivers/gpu/ion/ion_cma_heap.c +++ b/drivers/staging/android/ion/ion_cma_heap.c @@ -16,13 +16,12 @@ */ #include -#include #include #include #include #include -/* for ion_heap_ops structure */ +#include "ion.h" #include "ion_priv.h" #define ION_CMA_ALLOCATE_FAILED -1 diff --git a/drivers/gpu/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c similarity index 99% rename from drivers/gpu/ion/ion_heap.c rename to drivers/staging/android/ion/ion_heap.c index 786302de7ed0..9be246f50a01 100644 --- a/drivers/gpu/ion/ion_heap.c +++ b/drivers/staging/android/ion/ion_heap.c @@ -16,13 +16,13 @@ #include #include -#include #include #include #include #include #include #include +#include "ion.h" #include "ion_priv.h" void *ion_heap_map_kernel(struct ion_heap *heap, diff --git a/drivers/gpu/ion/ion_page_pool.c b/drivers/staging/android/ion/ion_page_pool.c similarity index 100% rename from drivers/gpu/ion/ion_page_pool.c rename to drivers/staging/android/ion/ion_page_pool.c diff --git a/drivers/gpu/ion/ion_priv.h b/drivers/staging/android/ion/ion_priv.h similarity index 99% rename from drivers/gpu/ion/ion_priv.h rename to drivers/staging/android/ion/ion_priv.h index 32461e946735..0ccf409cde7d 100644 --- a/drivers/gpu/ion/ion_priv.h +++ b/drivers/staging/android/ion/ion_priv.h @@ -17,7 +17,6 @@ #ifndef _ION_PRIV_H #define _ION_PRIV_H -#include #include #include #include @@ -26,6 +25,8 @@ #include #include +#include "ion.h" + struct ion_buffer *ion_handle_buffer(struct ion_handle *handle); /** diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c similarity index 99% rename from drivers/gpu/ion/ion_system_heap.c rename to drivers/staging/android/ion/ion_system_heap.c index 5fe81a76f2f5..06e0702396a4 100644 --- a/drivers/gpu/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -18,12 +18,12 @@ #include #include #include -#include #include #include #include #include #include +#include "ion.h" #include "ion_priv.h" static unsigned int high_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO | diff --git a/drivers/gpu/ion/tegra/Makefile b/drivers/staging/android/ion/tegra/Makefile similarity index 100% rename from drivers/gpu/ion/tegra/Makefile rename to drivers/staging/android/ion/tegra/Makefile diff --git a/drivers/gpu/ion/tegra/tegra_ion.c b/drivers/staging/android/ion/tegra/tegra_ion.c similarity index 98% rename from drivers/gpu/ion/tegra/tegra_ion.c rename to drivers/staging/android/ion/tegra/tegra_ion.c index 7af6e168ff4c..0849600bcc00 100644 --- a/drivers/gpu/ion/tegra/tegra_ion.c +++ b/drivers/staging/android/ion/tegra/tegra_ion.c @@ -15,9 +15,9 @@ */ #include -#include #include #include +#include "../ion.h" #include "../ion_priv.h" struct ion_device *idev; diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 7c5e27e52b9f..0669dac2301d 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -23,8 +23,6 @@ source "drivers/gpu/drm/Kconfig" source "drivers/gpu/host1x/Kconfig" -source "drivers/gpu/ion/Kconfig" - config VGASTATE tristate default n From 5152a44b69db2dbea5e05e763e9c77bf2ce0cacf Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 7 Nov 2013 13:29:12 -0800 Subject: [PATCH 03/54] ion: move userspace api into uapi/ion.h Split the userspace api out of drivers/staging/android/ion/ion.h into drivers/staging/android/uapi/ion.h Change-Id: I51baa4a7c86bf99c493e28a15f8664a489fd5a2d Signed-off-by: Colin Cross --- drivers/staging/android/ion/ion.h | 176 +------------------------- drivers/staging/android/uapi/ion.h | 196 +++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+), 175 deletions(-) create mode 100644 drivers/staging/android/uapi/ion.h diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h index 6b4d9fbeaec4..962e1c58d362 100644 --- a/drivers/staging/android/ion/ion.h +++ b/drivers/staging/android/ion/ion.h @@ -19,51 +19,8 @@ #include -typedef int ion_user_handle_t; +#include "../uapi/ion.h" -/** - * enum ion_heap_types - list of all possible types of heaps - * @ION_HEAP_TYPE_SYSTEM: memory allocated via vmalloc - * @ION_HEAP_TYPE_SYSTEM_CONTIG: memory allocated via kmalloc - * @ION_HEAP_TYPE_CARVEOUT: memory allocated from a prereserved - * carveout heap, allocations are physically - * contiguous - * @ION_HEAP_TYPE_DMA: memory allocated via DMA API - * @ION_NUM_HEAPS: helper for iterating over heaps, a bit mask - * is used to identify the heaps, so only 32 - * total heap types are supported - */ -enum ion_heap_type { - ION_HEAP_TYPE_SYSTEM, - ION_HEAP_TYPE_SYSTEM_CONTIG, - ION_HEAP_TYPE_CARVEOUT, - ION_HEAP_TYPE_CHUNK, - ION_HEAP_TYPE_DMA, - ION_HEAP_TYPE_CUSTOM, /* must be last so device specific heaps always - are at the end of this enum */ - ION_NUM_HEAPS = 16, -}; - -#define ION_HEAP_SYSTEM_MASK (1 << ION_HEAP_TYPE_SYSTEM) -#define ION_HEAP_SYSTEM_CONTIG_MASK (1 << ION_HEAP_TYPE_SYSTEM_CONTIG) -#define ION_HEAP_CARVEOUT_MASK (1 << ION_HEAP_TYPE_CARVEOUT) -#define ION_HEAP_TYPE_DMA_MASK (1 << ION_HEAP_TYPE_DMA) - -#define ION_NUM_HEAP_IDS sizeof(unsigned int) * 8 - -/** - * allocation flags - the lower 16 bits are used by core ion, the upper 16 - * bits are reserved for use by the heaps themselves. - */ -#define ION_FLAG_CACHED 1 /* mappings of this buffer should be - cached, ion will do cache - maintenance when the buffer is - mapped for dma */ -#define ION_FLAG_CACHED_NEEDS_SYNC 2 /* mappings of this buffer will created - at mmap time, if this is set - caches must be managed manually */ - -#ifdef __KERNEL__ struct ion_handle; struct ion_device; struct ion_heap; @@ -244,135 +201,4 @@ int ion_share_dma_buf_fd(struct ion_client *client, struct ion_handle *handle); */ struct ion_handle *ion_import_dma_buf(struct ion_client *client, int fd); -#endif /* __KERNEL__ */ - -/** - * DOC: Ion Userspace API - * - * create a client by opening /dev/ion - * most operations handled via following ioctls - * - */ - -/** - * struct ion_allocation_data - metadata passed from userspace for allocations - * @len: size of the allocation - * @align: required alignment of the allocation - * @heap_id_mask: mask of heap ids to allocate from - * @flags: flags passed to heap - * @handle: pointer that will be populated with a cookie to use to - * refer to this allocation - * - * Provided by userspace as an argument to the ioctl - */ -struct ion_allocation_data { - size_t len; - size_t align; - unsigned int heap_id_mask; - unsigned int flags; - ion_user_handle_t handle; -}; - -/** - * struct ion_fd_data - metadata passed to/from userspace for a handle/fd pair - * @handle: a handle - * @fd: a file descriptor representing that handle - * - * For ION_IOC_SHARE or ION_IOC_MAP userspace populates the handle field with - * the handle returned from ion alloc, and the kernel returns the file - * descriptor to share or map in the fd field. For ION_IOC_IMPORT, userspace - * provides the file descriptor and the kernel returns the handle. - */ -struct ion_fd_data { - ion_user_handle_t handle; - int fd; -}; - -/** - * struct ion_handle_data - a handle passed to/from the kernel - * @handle: a handle - */ -struct ion_handle_data { - ion_user_handle_t handle; -}; - -/** - * struct ion_custom_data - metadata passed to/from userspace for a custom ioctl - * @cmd: the custom ioctl function to call - * @arg: additional data to pass to the custom ioctl, typically a user - * pointer to a predefined structure - * - * This works just like the regular cmd and arg fields of an ioctl. - */ -struct ion_custom_data { - unsigned int cmd; - unsigned long arg; -}; - -#define ION_IOC_MAGIC 'I' - -/** - * DOC: ION_IOC_ALLOC - allocate memory - * - * Takes an ion_allocation_data struct and returns it with the handle field - * populated with the opaque handle for the allocation. - */ -#define ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \ - struct ion_allocation_data) - -/** - * DOC: ION_IOC_FREE - free memory - * - * Takes an ion_handle_data struct and frees the handle. - */ -#define ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data) - -/** - * DOC: ION_IOC_MAP - get a file descriptor to mmap - * - * Takes an ion_fd_data struct with the handle field populated with a valid - * opaque handle. Returns the struct with the fd field set to a file - * descriptor open in the current address space. This file descriptor - * can then be used as an argument to mmap. - */ -#define ION_IOC_MAP _IOWR(ION_IOC_MAGIC, 2, struct ion_fd_data) - -/** - * DOC: ION_IOC_SHARE - creates a file descriptor to use to share an allocation - * - * Takes an ion_fd_data struct with the handle field populated with a valid - * opaque handle. Returns the struct with the fd field set to a file - * descriptor open in the current address space. This file descriptor - * can then be passed to another process. The corresponding opaque handle can - * be retrieved via ION_IOC_IMPORT. - */ -#define ION_IOC_SHARE _IOWR(ION_IOC_MAGIC, 4, struct ion_fd_data) - -/** - * DOC: ION_IOC_IMPORT - imports a shared file descriptor - * - * Takes an ion_fd_data struct with the fd field populated with a valid file - * descriptor obtained from ION_IOC_SHARE and returns the struct with the handle - * filed set to the corresponding opaque handle. - */ -#define ION_IOC_IMPORT _IOWR(ION_IOC_MAGIC, 5, struct ion_fd_data) - -/** - * DOC: ION_IOC_SYNC - syncs a shared file descriptors to memory - * - * Deprecated in favor of using the dma_buf api's correctly (syncing - * will happend automatically when the buffer is mapped to a device). - * If necessary should be used after touching a cached buffer from the cpu, - * this will make the buffer in memory coherent. - */ -#define ION_IOC_SYNC _IOWR(ION_IOC_MAGIC, 7, struct ion_fd_data) - -/** - * DOC: ION_IOC_CUSTOM - call architecture specific ion ioctl - * - * Takes the argument of the architecture specific ioctl to call and - * passes appropriate userdata for that ioctl - */ -#define ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, struct ion_custom_data) - #endif /* _LINUX_ION_H */ diff --git a/drivers/staging/android/uapi/ion.h b/drivers/staging/android/uapi/ion.h new file mode 100644 index 000000000000..f09e7c154d69 --- /dev/null +++ b/drivers/staging/android/uapi/ion.h @@ -0,0 +1,196 @@ +/* + * drivers/staging/android/uapi/ion.h + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#ifndef _UAPI_LINUX_ION_H +#define _UAPI_LINUX_ION_H + +#include +#include + +typedef int ion_user_handle_t; + +/** + * enum ion_heap_types - list of all possible types of heaps + * @ION_HEAP_TYPE_SYSTEM: memory allocated via vmalloc + * @ION_HEAP_TYPE_SYSTEM_CONTIG: memory allocated via kmalloc + * @ION_HEAP_TYPE_CARVEOUT: memory allocated from a prereserved + * carveout heap, allocations are physically + * contiguous + * @ION_HEAP_TYPE_DMA: memory allocated via DMA API + * @ION_NUM_HEAPS: helper for iterating over heaps, a bit mask + * is used to identify the heaps, so only 32 + * total heap types are supported + */ +enum ion_heap_type { + ION_HEAP_TYPE_SYSTEM, + ION_HEAP_TYPE_SYSTEM_CONTIG, + ION_HEAP_TYPE_CARVEOUT, + ION_HEAP_TYPE_CHUNK, + ION_HEAP_TYPE_DMA, + ION_HEAP_TYPE_CUSTOM, /* must be last so device specific heaps always + are at the end of this enum */ + ION_NUM_HEAPS = 16, +}; + +#define ION_HEAP_SYSTEM_MASK (1 << ION_HEAP_TYPE_SYSTEM) +#define ION_HEAP_SYSTEM_CONTIG_MASK (1 << ION_HEAP_TYPE_SYSTEM_CONTIG) +#define ION_HEAP_CARVEOUT_MASK (1 << ION_HEAP_TYPE_CARVEOUT) +#define ION_HEAP_TYPE_DMA_MASK (1 << ION_HEAP_TYPE_DMA) + +#define ION_NUM_HEAP_IDS sizeof(unsigned int) * 8 + +/** + * allocation flags - the lower 16 bits are used by core ion, the upper 16 + * bits are reserved for use by the heaps themselves. + */ +#define ION_FLAG_CACHED 1 /* mappings of this buffer should be + cached, ion will do cache + maintenance when the buffer is + mapped for dma */ +#define ION_FLAG_CACHED_NEEDS_SYNC 2 /* mappings of this buffer will created + at mmap time, if this is set + caches must be managed manually */ + +/** + * DOC: Ion Userspace API + * + * create a client by opening /dev/ion + * most operations handled via following ioctls + * + */ + +/** + * struct ion_allocation_data - metadata passed from userspace for allocations + * @len: size of the allocation + * @align: required alignment of the allocation + * @heap_id_mask: mask of heap ids to allocate from + * @flags: flags passed to heap + * @handle: pointer that will be populated with a cookie to use to + * refer to this allocation + * + * Provided by userspace as an argument to the ioctl + */ +struct ion_allocation_data { + size_t len; + size_t align; + unsigned int heap_id_mask; + unsigned int flags; + ion_user_handle_t handle; +}; + +/** + * struct ion_fd_data - metadata passed to/from userspace for a handle/fd pair + * @handle: a handle + * @fd: a file descriptor representing that handle + * + * For ION_IOC_SHARE or ION_IOC_MAP userspace populates the handle field with + * the handle returned from ion alloc, and the kernel returns the file + * descriptor to share or map in the fd field. For ION_IOC_IMPORT, userspace + * provides the file descriptor and the kernel returns the handle. + */ +struct ion_fd_data { + ion_user_handle_t handle; + int fd; +}; + +/** + * struct ion_handle_data - a handle passed to/from the kernel + * @handle: a handle + */ +struct ion_handle_data { + ion_user_handle_t handle; +}; + +/** + * struct ion_custom_data - metadata passed to/from userspace for a custom ioctl + * @cmd: the custom ioctl function to call + * @arg: additional data to pass to the custom ioctl, typically a user + * pointer to a predefined structure + * + * This works just like the regular cmd and arg fields of an ioctl. + */ +struct ion_custom_data { + unsigned int cmd; + unsigned long arg; +}; + +#define ION_IOC_MAGIC 'I' + +/** + * DOC: ION_IOC_ALLOC - allocate memory + * + * Takes an ion_allocation_data struct and returns it with the handle field + * populated with the opaque handle for the allocation. + */ +#define ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \ + struct ion_allocation_data) + +/** + * DOC: ION_IOC_FREE - free memory + * + * Takes an ion_handle_data struct and frees the handle. + */ +#define ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data) + +/** + * DOC: ION_IOC_MAP - get a file descriptor to mmap + * + * Takes an ion_fd_data struct with the handle field populated with a valid + * opaque handle. Returns the struct with the fd field set to a file + * descriptor open in the current address space. This file descriptor + * can then be used as an argument to mmap. + */ +#define ION_IOC_MAP _IOWR(ION_IOC_MAGIC, 2, struct ion_fd_data) + +/** + * DOC: ION_IOC_SHARE - creates a file descriptor to use to share an allocation + * + * Takes an ion_fd_data struct with the handle field populated with a valid + * opaque handle. Returns the struct with the fd field set to a file + * descriptor open in the current address space. This file descriptor + * can then be passed to another process. The corresponding opaque handle can + * be retrieved via ION_IOC_IMPORT. + */ +#define ION_IOC_SHARE _IOWR(ION_IOC_MAGIC, 4, struct ion_fd_data) + +/** + * DOC: ION_IOC_IMPORT - imports a shared file descriptor + * + * Takes an ion_fd_data struct with the fd field populated with a valid file + * descriptor obtained from ION_IOC_SHARE and returns the struct with the handle + * filed set to the corresponding opaque handle. + */ +#define ION_IOC_IMPORT _IOWR(ION_IOC_MAGIC, 5, struct ion_fd_data) + +/** + * DOC: ION_IOC_SYNC - syncs a shared file descriptors to memory + * + * Deprecated in favor of using the dma_buf api's correctly (syncing + * will happend automatically when the buffer is mapped to a device). + * If necessary should be used after touching a cached buffer from the cpu, + * this will make the buffer in memory coherent. + */ +#define ION_IOC_SYNC _IOWR(ION_IOC_MAGIC, 7, struct ion_fd_data) + +/** + * DOC: ION_IOC_CUSTOM - call architecture specific ion ioctl + * + * Takes the argument of the architecture specific ioctl to call and + * passes appropriate userdata for that ioctl + */ +#define ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, struct ion_custom_data) + +#endif /* _UAPI_LINUX_ION_H */ From 3a7a4898998bc2d47bafd362da30df59374e2669 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 7 Nov 2013 12:46:33 -0800 Subject: [PATCH 04/54] input: misc: keychord: move header to uapi Move the entire contents of linux/keychord.h header to uapi, it only contains a userspace interface. Change-Id: If94f83328b19efb58c66391dce3bd8e927788d8d Signed-off-by: Colin Cross --- include/linux/keychord.h | 31 +-------------------- include/uapi/linux/keychord.h | 52 +++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 30 deletions(-) create mode 100644 include/uapi/linux/keychord.h diff --git a/include/linux/keychord.h b/include/linux/keychord.h index 856a5850217b..08cf5402102c 100644 --- a/include/linux/keychord.h +++ b/include/linux/keychord.h @@ -18,35 +18,6 @@ #ifndef __LINUX_KEYCHORD_H_ #define __LINUX_KEYCHORD_H_ -#include - -#define KEYCHORD_VERSION 1 - -/* - * One or more input_keychord structs are written to /dev/keychord - * at once to specify the list of keychords to monitor. - * Reading /dev/keychord returns the id of a keychord when the - * keychord combination is pressed. A keychord is signalled when - * all of the keys in the keycode list are in the pressed state. - * The order in which the keys are pressed does not matter. - * The keychord will not be signalled if keys not in the keycode - * list are pressed. - * Keychords will not be signalled on key release events. - */ -struct input_keychord { - /* should be KEYCHORD_VERSION */ - __u16 version; - /* - * client specified ID, returned from read() - * when this keychord is pressed. - */ - __u16 id; - - /* number of keycodes in this keychord */ - __u16 count; - - /* variable length array of keycodes */ - __u16 keycodes[]; -}; +#include #endif /* __LINUX_KEYCHORD_H_ */ diff --git a/include/uapi/linux/keychord.h b/include/uapi/linux/keychord.h new file mode 100644 index 000000000000..ea7cf4d27bbd --- /dev/null +++ b/include/uapi/linux/keychord.h @@ -0,0 +1,52 @@ +/* + * Key chord input driver + * + * Copyright (C) 2008 Google, Inc. + * Author: Mike Lockwood + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * +*/ + +#ifndef _UAPI_LINUX_KEYCHORD_H_ +#define _UAPI_LINUX_KEYCHORD_H_ + +#include + +#define KEYCHORD_VERSION 1 + +/* + * One or more input_keychord structs are written to /dev/keychord + * at once to specify the list of keychords to monitor. + * Reading /dev/keychord returns the id of a keychord when the + * keychord combination is pressed. A keychord is signalled when + * all of the keys in the keycode list are in the pressed state. + * The order in which the keys are pressed does not matter. + * The keychord will not be signalled if keys not in the keycode + * list are pressed. + * Keychords will not be signalled on key release events. + */ +struct input_keychord { + /* should be KEYCHORD_VERSION */ + __u16 version; + /* + * client specified ID, returned from read() + * when this keychord is pressed. + */ + __u16 id; + + /* number of keycodes in this keychord */ + __u16 count; + + /* variable length array of keycodes */ + __u16 keycodes[]; +}; + +#endif /* _UAPI_LINUX_KEYCHORD_H_ */ From 4d174ee19f31fd93f7f1d835bf7e2b613e399dad Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 7 Nov 2013 13:08:15 -0800 Subject: [PATCH 05/54] usb: gadget: f_mtp: move userspace interface to uapi Move the most of linux/usb/f_mtp.h header to uapi. Move the only remaining structure definition into f_mtp.c, the only place that uses it. Change-Id: I952c1a9dc15c36bf295a0eb4d74b6b1ad912ed03 Signed-off-by: Colin Cross --- drivers/usb/gadget/f_mtp.c | 11 ++++++ include/linux/usb/f_mtp.h | 54 +----------------------------- include/uapi/linux/usb/f_mtp.h | 61 ++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 53 deletions(-) create mode 100644 include/uapi/linux/usb/f_mtp.h diff --git a/drivers/usb/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c index 12fb818ab147..960d64fbd40b 100644 --- a/drivers/usb/gadget/f_mtp.c +++ b/drivers/usb/gadget/f_mtp.c @@ -269,6 +269,17 @@ struct mtp_device_status { __le16 wCode; }; +struct mtp_data_header { + /* length of packet, including this header */ + __le32 length; + /* container type (2 for data packet) */ + __le16 type; + /* MTP command code */ + __le16 command; + /* MTP transaction ID */ + __le32 transaction_id; +}; + /* temporary variable used between mtp_open() and mtp_gadget_bind() */ static struct mtp_dev *_mtp_dev; diff --git a/include/linux/usb/f_mtp.h b/include/linux/usb/f_mtp.h index 72a432e2fcdd..4e8417791bea 100644 --- a/include/linux/usb/f_mtp.h +++ b/include/linux/usb/f_mtp.h @@ -18,58 +18,6 @@ #ifndef __LINUX_USB_F_MTP_H #define __LINUX_USB_F_MTP_H -#include - -#ifdef __KERNEL__ - -struct mtp_data_header { - /* length of packet, including this header */ - uint32_t length; - /* container type (2 for data packet) */ - uint16_t type; - /* MTP command code */ - uint16_t command; - /* MTP transaction ID */ - uint32_t transaction_id; -}; - -#endif /* __KERNEL__ */ - -struct mtp_file_range { - /* file descriptor for file to transfer */ - int fd; - /* offset in file for start of transfer */ - loff_t offset; - /* number of bytes to transfer */ - int64_t length; - /* MTP command ID for data header, - * used only for MTP_SEND_FILE_WITH_HEADER - */ - uint16_t command; - /* MTP transaction ID for data header, - * used only for MTP_SEND_FILE_WITH_HEADER - */ - uint32_t transaction_id; -}; - -struct mtp_event { - /* size of the event */ - size_t length; - /* event data to send */ - void *data; -}; - -/* Sends the specified file range to the host */ -#define MTP_SEND_FILE _IOW('M', 0, struct mtp_file_range) -/* Receives data from the host and writes it to a file. - * The file is created if it does not exist. - */ -#define MTP_RECEIVE_FILE _IOW('M', 1, struct mtp_file_range) -/* Sends an event to the host via the interrupt endpoint */ -#define MTP_SEND_EVENT _IOW('M', 3, struct mtp_event) -/* Sends the specified file range to the host, - * with a 12 byte MTP data packet header at the beginning. - */ -#define MTP_SEND_FILE_WITH_HEADER _IOW('M', 4, struct mtp_file_range) +#include #endif /* __LINUX_USB_F_MTP_H */ diff --git a/include/uapi/linux/usb/f_mtp.h b/include/uapi/linux/usb/f_mtp.h new file mode 100644 index 000000000000..503291855abd --- /dev/null +++ b/include/uapi/linux/usb/f_mtp.h @@ -0,0 +1,61 @@ +/* + * Gadget Function Driver for MTP + * + * Copyright (C) 2010 Google, Inc. + * Author: Mike Lockwood + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#ifndef _UAPI_LINUX_USB_F_MTP_H +#define _UAPI_LINUX_USB_F_MTP_H + +#include +#include + +struct mtp_file_range { + /* file descriptor for file to transfer */ + int fd; + /* offset in file for start of transfer */ + loff_t offset; + /* number of bytes to transfer */ + int64_t length; + /* MTP command ID for data header, + * used only for MTP_SEND_FILE_WITH_HEADER + */ + uint16_t command; + /* MTP transaction ID for data header, + * used only for MTP_SEND_FILE_WITH_HEADER + */ + uint32_t transaction_id; +}; + +struct mtp_event { + /* size of the event */ + size_t length; + /* event data to send */ + void *data; +}; + +/* Sends the specified file range to the host */ +#define MTP_SEND_FILE _IOW('M', 0, struct mtp_file_range) +/* Receives data from the host and writes it to a file. + * The file is created if it does not exist. + */ +#define MTP_RECEIVE_FILE _IOW('M', 1, struct mtp_file_range) +/* Sends an event to the host via the interrupt endpoint */ +#define MTP_SEND_EVENT _IOW('M', 3, struct mtp_event) +/* Sends the specified file range to the host, + * with a 12 byte MTP data packet header at the beginning. + */ +#define MTP_SEND_FILE_WITH_HEADER _IOW('M', 4, struct mtp_file_range) + +#endif /* _UAPI_LINUX_USB_F_MTP_H */ From 7a6a0851afc3c63400f561b876374ca105448d0e Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 7 Nov 2013 13:08:39 -0800 Subject: [PATCH 06/54] usb: gadget: f_accessory: move userspace interface to uapi Move the entire contents of linux/usb/f_accessory.h header to uapi, it only contains a userspace interface. Change-Id: Ieb5547da449588ae554988a201c0e6b4e3afc531 Signed-off-by: Colin Cross --- include/linux/usb/f_accessory.h | 125 +---------------------- include/uapi/linux/usb/f_accessory.h | 146 +++++++++++++++++++++++++++ 2 files changed, 147 insertions(+), 124 deletions(-) create mode 100644 include/uapi/linux/usb/f_accessory.h diff --git a/include/linux/usb/f_accessory.h b/include/linux/usb/f_accessory.h index 61ebe0aabc5b..ebe3c4d59309 100644 --- a/include/linux/usb/f_accessory.h +++ b/include/linux/usb/f_accessory.h @@ -18,129 +18,6 @@ #ifndef __LINUX_USB_F_ACCESSORY_H #define __LINUX_USB_F_ACCESSORY_H -/* Use Google Vendor ID when in accessory mode */ -#define USB_ACCESSORY_VENDOR_ID 0x18D1 - - -/* Product ID to use when in accessory mode */ -#define USB_ACCESSORY_PRODUCT_ID 0x2D00 - -/* Product ID to use when in accessory mode and adb is enabled */ -#define USB_ACCESSORY_ADB_PRODUCT_ID 0x2D01 - -/* Indexes for strings sent by the host via ACCESSORY_SEND_STRING */ -#define ACCESSORY_STRING_MANUFACTURER 0 -#define ACCESSORY_STRING_MODEL 1 -#define ACCESSORY_STRING_DESCRIPTION 2 -#define ACCESSORY_STRING_VERSION 3 -#define ACCESSORY_STRING_URI 4 -#define ACCESSORY_STRING_SERIAL 5 - -/* Control request for retrieving device's protocol version - * - * requestType: USB_DIR_IN | USB_TYPE_VENDOR - * request: ACCESSORY_GET_PROTOCOL - * value: 0 - * index: 0 - * data version number (16 bits little endian) - * 1 for original accessory support - * 2 adds HID and device to host audio support - */ -#define ACCESSORY_GET_PROTOCOL 51 - -/* Control request for host to send a string to the device - * - * requestType: USB_DIR_OUT | USB_TYPE_VENDOR - * request: ACCESSORY_SEND_STRING - * value: 0 - * index: string ID - * data zero terminated UTF8 string - * - * The device can later retrieve these strings via the - * ACCESSORY_GET_STRING_* ioctls - */ -#define ACCESSORY_SEND_STRING 52 - -/* Control request for starting device in accessory mode. - * The host sends this after setting all its strings to the device. - * - * requestType: USB_DIR_OUT | USB_TYPE_VENDOR - * request: ACCESSORY_START - * value: 0 - * index: 0 - * data none - */ -#define ACCESSORY_START 53 - -/* Control request for registering a HID device. - * Upon registering, a unique ID is sent by the accessory in the - * value parameter. This ID will be used for future commands for - * the device - * - * requestType: USB_DIR_OUT | USB_TYPE_VENDOR - * request: ACCESSORY_REGISTER_HID_DEVICE - * value: Accessory assigned ID for the HID device - * index: total length of the HID report descriptor - * data none - */ -#define ACCESSORY_REGISTER_HID 54 - -/* Control request for unregistering a HID device. - * - * requestType: USB_DIR_OUT | USB_TYPE_VENDOR - * request: ACCESSORY_REGISTER_HID - * value: Accessory assigned ID for the HID device - * index: 0 - * data none - */ -#define ACCESSORY_UNREGISTER_HID 55 - -/* Control request for sending the HID report descriptor. - * If the HID descriptor is longer than the endpoint zero max packet size, - * the descriptor will be sent in multiple ACCESSORY_SET_HID_REPORT_DESC - * commands. The data for the descriptor must be sent sequentially - * if multiple packets are needed. - * - * requestType: USB_DIR_OUT | USB_TYPE_VENDOR - * request: ACCESSORY_SET_HID_REPORT_DESC - * value: Accessory assigned ID for the HID device - * index: offset of data in descriptor - * (needed when HID descriptor is too big for one packet) - * data the HID report descriptor - */ -#define ACCESSORY_SET_HID_REPORT_DESC 56 - -/* Control request for sending HID events. - * - * requestType: USB_DIR_OUT | USB_TYPE_VENDOR - * request: ACCESSORY_SEND_HID_EVENT - * value: Accessory assigned ID for the HID device - * index: 0 - * data the HID report for the event - */ -#define ACCESSORY_SEND_HID_EVENT 57 - -/* Control request for setting the audio mode. - * - * requestType: USB_DIR_OUT | USB_TYPE_VENDOR - * request: ACCESSORY_SET_AUDIO_MODE - * value: 0 - no audio - * 1 - device to host, 44100 16-bit stereo PCM - * index: 0 - * data none - */ -#define ACCESSORY_SET_AUDIO_MODE 58 - -/* ioctls for retrieving strings set by the host */ -#define ACCESSORY_GET_STRING_MANUFACTURER _IOW('M', 1, char[256]) -#define ACCESSORY_GET_STRING_MODEL _IOW('M', 2, char[256]) -#define ACCESSORY_GET_STRING_DESCRIPTION _IOW('M', 3, char[256]) -#define ACCESSORY_GET_STRING_VERSION _IOW('M', 4, char[256]) -#define ACCESSORY_GET_STRING_URI _IOW('M', 5, char[256]) -#define ACCESSORY_GET_STRING_SERIAL _IOW('M', 6, char[256]) -/* returns 1 if there is a start request pending */ -#define ACCESSORY_IS_START_REQUESTED _IO('M', 7) -/* returns audio mode (set via the ACCESSORY_SET_AUDIO_MODE control request) */ -#define ACCESSORY_GET_AUDIO_MODE _IO('M', 8) +#include #endif /* __LINUX_USB_F_ACCESSORY_H */ diff --git a/include/uapi/linux/usb/f_accessory.h b/include/uapi/linux/usb/f_accessory.h new file mode 100644 index 000000000000..0baeb7d0d74c --- /dev/null +++ b/include/uapi/linux/usb/f_accessory.h @@ -0,0 +1,146 @@ +/* + * Gadget Function Driver for Android USB accessories + * + * Copyright (C) 2011 Google, Inc. + * Author: Mike Lockwood + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#ifndef _UAPI_LINUX_USB_F_ACCESSORY_H +#define _UAPI_LINUX_USB_F_ACCESSORY_H + +/* Use Google Vendor ID when in accessory mode */ +#define USB_ACCESSORY_VENDOR_ID 0x18D1 + + +/* Product ID to use when in accessory mode */ +#define USB_ACCESSORY_PRODUCT_ID 0x2D00 + +/* Product ID to use when in accessory mode and adb is enabled */ +#define USB_ACCESSORY_ADB_PRODUCT_ID 0x2D01 + +/* Indexes for strings sent by the host via ACCESSORY_SEND_STRING */ +#define ACCESSORY_STRING_MANUFACTURER 0 +#define ACCESSORY_STRING_MODEL 1 +#define ACCESSORY_STRING_DESCRIPTION 2 +#define ACCESSORY_STRING_VERSION 3 +#define ACCESSORY_STRING_URI 4 +#define ACCESSORY_STRING_SERIAL 5 + +/* Control request for retrieving device's protocol version + * + * requestType: USB_DIR_IN | USB_TYPE_VENDOR + * request: ACCESSORY_GET_PROTOCOL + * value: 0 + * index: 0 + * data version number (16 bits little endian) + * 1 for original accessory support + * 2 adds HID and device to host audio support + */ +#define ACCESSORY_GET_PROTOCOL 51 + +/* Control request for host to send a string to the device + * + * requestType: USB_DIR_OUT | USB_TYPE_VENDOR + * request: ACCESSORY_SEND_STRING + * value: 0 + * index: string ID + * data zero terminated UTF8 string + * + * The device can later retrieve these strings via the + * ACCESSORY_GET_STRING_* ioctls + */ +#define ACCESSORY_SEND_STRING 52 + +/* Control request for starting device in accessory mode. + * The host sends this after setting all its strings to the device. + * + * requestType: USB_DIR_OUT | USB_TYPE_VENDOR + * request: ACCESSORY_START + * value: 0 + * index: 0 + * data none + */ +#define ACCESSORY_START 53 + +/* Control request for registering a HID device. + * Upon registering, a unique ID is sent by the accessory in the + * value parameter. This ID will be used for future commands for + * the device + * + * requestType: USB_DIR_OUT | USB_TYPE_VENDOR + * request: ACCESSORY_REGISTER_HID_DEVICE + * value: Accessory assigned ID for the HID device + * index: total length of the HID report descriptor + * data none + */ +#define ACCESSORY_REGISTER_HID 54 + +/* Control request for unregistering a HID device. + * + * requestType: USB_DIR_OUT | USB_TYPE_VENDOR + * request: ACCESSORY_REGISTER_HID + * value: Accessory assigned ID for the HID device + * index: 0 + * data none + */ +#define ACCESSORY_UNREGISTER_HID 55 + +/* Control request for sending the HID report descriptor. + * If the HID descriptor is longer than the endpoint zero max packet size, + * the descriptor will be sent in multiple ACCESSORY_SET_HID_REPORT_DESC + * commands. The data for the descriptor must be sent sequentially + * if multiple packets are needed. + * + * requestType: USB_DIR_OUT | USB_TYPE_VENDOR + * request: ACCESSORY_SET_HID_REPORT_DESC + * value: Accessory assigned ID for the HID device + * index: offset of data in descriptor + * (needed when HID descriptor is too big for one packet) + * data the HID report descriptor + */ +#define ACCESSORY_SET_HID_REPORT_DESC 56 + +/* Control request for sending HID events. + * + * requestType: USB_DIR_OUT | USB_TYPE_VENDOR + * request: ACCESSORY_SEND_HID_EVENT + * value: Accessory assigned ID for the HID device + * index: 0 + * data the HID report for the event + */ +#define ACCESSORY_SEND_HID_EVENT 57 + +/* Control request for setting the audio mode. + * + * requestType: USB_DIR_OUT | USB_TYPE_VENDOR + * request: ACCESSORY_SET_AUDIO_MODE + * value: 0 - no audio + * 1 - device to host, 44100 16-bit stereo PCM + * index: 0 + * data none + */ +#define ACCESSORY_SET_AUDIO_MODE 58 + +/* ioctls for retrieving strings set by the host */ +#define ACCESSORY_GET_STRING_MANUFACTURER _IOW('M', 1, char[256]) +#define ACCESSORY_GET_STRING_MODEL _IOW('M', 2, char[256]) +#define ACCESSORY_GET_STRING_DESCRIPTION _IOW('M', 3, char[256]) +#define ACCESSORY_GET_STRING_VERSION _IOW('M', 4, char[256]) +#define ACCESSORY_GET_STRING_URI _IOW('M', 5, char[256]) +#define ACCESSORY_GET_STRING_SERIAL _IOW('M', 6, char[256]) +/* returns 1 if there is a start request pending */ +#define ACCESSORY_IS_START_REQUESTED _IO('M', 7) +/* returns audio mode (set via the ACCESSORY_SET_AUDIO_MODE control request) */ +#define ACCESSORY_GET_AUDIO_MODE _IO('M', 8) + +#endif /* _UAPI_LINUX_USB_F_ACCESSORY_H */ From 9efb6ab8798107e5500ea6d9a2221441c580e8cb Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 7 Nov 2013 13:19:34 -0800 Subject: [PATCH 07/54] net: move PPPoLAC and PPPoPNS headers to uapi Move the entire contents of the linux/if_pppolac.h and linux/if_pppopns.h headers to uapi, they only contain userspace interfaces. Change-Id: I3cfed7f2ae400b53269a1f59144aa3dbc30ae0b5 Signed-off-by: Colin Cross --- include/linux/if_pppolac.h | 12 +----------- include/linux/if_pppopns.h | 11 +---------- include/uapi/linux/if_pppolac.h | 33 +++++++++++++++++++++++++++++++++ include/uapi/linux/if_pppopns.h | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 21 deletions(-) create mode 100644 include/uapi/linux/if_pppolac.h create mode 100644 include/uapi/linux/if_pppopns.h diff --git a/include/linux/if_pppolac.h b/include/linux/if_pppolac.h index c06bd6c8ba26..e40aa1075a30 100644 --- a/include/linux/if_pppolac.h +++ b/include/linux/if_pppolac.h @@ -18,16 +18,6 @@ #ifndef __LINUX_IF_PPPOLAC_H #define __LINUX_IF_PPPOLAC_H -#include -#include - -struct sockaddr_pppolac { - sa_family_t sa_family; /* AF_PPPOX */ - unsigned int sa_protocol; /* PX_PROTO_OLAC */ - int udp_socket; - struct __attribute__((packed)) { - __u16 tunnel, session; - } local, remote; -} __attribute__((packed)); +#include #endif /* __LINUX_IF_PPPOLAC_H */ diff --git a/include/linux/if_pppopns.h b/include/linux/if_pppopns.h index 0cf34b4d551f..4ac621a9ce7c 100644 --- a/include/linux/if_pppopns.h +++ b/include/linux/if_pppopns.h @@ -18,15 +18,6 @@ #ifndef __LINUX_IF_PPPOPNS_H #define __LINUX_IF_PPPOPNS_H -#include -#include - -struct sockaddr_pppopns { - sa_family_t sa_family; /* AF_PPPOX */ - unsigned int sa_protocol; /* PX_PROTO_OPNS */ - int tcp_socket; - __u16 local; - __u16 remote; -} __attribute__((packed)); +#include #endif /* __LINUX_IF_PPPOPNS_H */ diff --git a/include/uapi/linux/if_pppolac.h b/include/uapi/linux/if_pppolac.h new file mode 100644 index 000000000000..b7eb8153ef66 --- /dev/null +++ b/include/uapi/linux/if_pppolac.h @@ -0,0 +1,33 @@ +/* include/uapi/linux/if_pppolac.h + * + * Header for PPP on L2TP Access Concentrator / PPPoLAC Socket (RFC 2661) + * + * Copyright (C) 2009 Google, Inc. + * Author: Chia-chi Yeh + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + */ + +#ifndef _UAPI_LINUX_IF_PPPOLAC_H +#define _UAPI_LINUX_IF_PPPOLAC_H + +#include +#include + +struct sockaddr_pppolac { + sa_family_t sa_family; /* AF_PPPOX */ + unsigned int sa_protocol; /* PX_PROTO_OLAC */ + int udp_socket; + struct __attribute__((packed)) { + __u16 tunnel, session; + } local, remote; +} __attribute__((packed)); + +#endif /* _UAPI_LINUX_IF_PPPOLAC_H */ diff --git a/include/uapi/linux/if_pppopns.h b/include/uapi/linux/if_pppopns.h new file mode 100644 index 000000000000..a392b52ea6ec --- /dev/null +++ b/include/uapi/linux/if_pppopns.h @@ -0,0 +1,32 @@ +/* include/uapi/linux/if_pppopns.h + * + * Header for PPP on PPTP Network Server / PPPoPNS Socket (RFC 2637) + * + * Copyright (C) 2009 Google, Inc. + * Author: Chia-chi Yeh + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + */ + +#ifndef _UAPI_LINUX_IF_PPPOPNS_H +#define _UAPI_LINUX_IF_PPPOPNS_H + +#include +#include + +struct sockaddr_pppopns { + sa_family_t sa_family; /* AF_PPPOX */ + unsigned int sa_protocol; /* PX_PROTO_OPNS */ + int tcp_socket; + __u16 local; + __u16 remote; +} __attribute__((packed)); + +#endif /* _UAPI_LINUX_IF_PPPOPNS_H */ From 5be5f3a069efeafebf6a47876e02ddf6ec02eda0 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 7 Nov 2013 13:38:57 -0800 Subject: [PATCH 08/54] drivers: staging: android: split uapi out of android_alarm.h Move the userspace interface of android_alarm.h to drivers/staging/android/uapi/android_alarm.h Change-Id: Ieb96e8e9bf742786efc4e248e6a242dab8199ca3 Signed-off-by: Colin Cross --- drivers/staging/android/android_alarm.h | 44 +------------- drivers/staging/android/uapi/android_alarm.h | 62 ++++++++++++++++++++ 2 files changed, 64 insertions(+), 42 deletions(-) create mode 100644 drivers/staging/android/uapi/android_alarm.h diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h index 4fd32f337f9c..495b20cf3bf6 100644 --- a/drivers/staging/android/android_alarm.h +++ b/drivers/staging/android/android_alarm.h @@ -16,50 +16,10 @@ #ifndef _LINUX_ANDROID_ALARM_H #define _LINUX_ANDROID_ALARM_H -#include -#include #include +#include -enum android_alarm_type { - /* return code bit numbers or set alarm arg */ - ANDROID_ALARM_RTC_WAKEUP, - ANDROID_ALARM_RTC, - ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, - ANDROID_ALARM_ELAPSED_REALTIME, - ANDROID_ALARM_SYSTEMTIME, - - ANDROID_ALARM_TYPE_COUNT, - - /* return code bit numbers */ - /* ANDROID_ALARM_TIME_CHANGE = 16 */ -}; - -enum android_alarm_return_flags { - ANDROID_ALARM_RTC_WAKEUP_MASK = 1U << ANDROID_ALARM_RTC_WAKEUP, - ANDROID_ALARM_RTC_MASK = 1U << ANDROID_ALARM_RTC, - ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK = - 1U << ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, - ANDROID_ALARM_ELAPSED_REALTIME_MASK = - 1U << ANDROID_ALARM_ELAPSED_REALTIME, - ANDROID_ALARM_SYSTEMTIME_MASK = 1U << ANDROID_ALARM_SYSTEMTIME, - ANDROID_ALARM_TIME_CHANGE_MASK = 1U << 16 -}; - -/* Disable alarm */ -#define ANDROID_ALARM_CLEAR(type) _IO('a', 0 | ((type) << 4)) - -/* Ack last alarm and wait for next */ -#define ANDROID_ALARM_WAIT _IO('a', 1) - -#define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size) -/* Set alarm */ -#define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec) -#define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec) -#define ANDROID_ALARM_GET_TIME(type) ALARM_IOW(4, type, struct timespec) -#define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec) -#define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0))) -#define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4) - +#include "uapi/android_alarm.h" #ifdef CONFIG_COMPAT #define ANDROID_ALARM_SET_COMPAT(type) ALARM_IOW(2, type, \ diff --git a/drivers/staging/android/uapi/android_alarm.h b/drivers/staging/android/uapi/android_alarm.h new file mode 100644 index 000000000000..aa013f6f5f3a --- /dev/null +++ b/drivers/staging/android/uapi/android_alarm.h @@ -0,0 +1,62 @@ +/* drivers/staging/android/uapi/android_alarm.h + * + * Copyright (C) 2006-2007 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#ifndef _UAPI_LINUX_ANDROID_ALARM_H +#define _UAPI_LINUX_ANDROID_ALARM_H + +#include +#include + +enum android_alarm_type { + /* return code bit numbers or set alarm arg */ + ANDROID_ALARM_RTC_WAKEUP, + ANDROID_ALARM_RTC, + ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, + ANDROID_ALARM_ELAPSED_REALTIME, + ANDROID_ALARM_SYSTEMTIME, + + ANDROID_ALARM_TYPE_COUNT, + + /* return code bit numbers */ + /* ANDROID_ALARM_TIME_CHANGE = 16 */ +}; + +enum android_alarm_return_flags { + ANDROID_ALARM_RTC_WAKEUP_MASK = 1U << ANDROID_ALARM_RTC_WAKEUP, + ANDROID_ALARM_RTC_MASK = 1U << ANDROID_ALARM_RTC, + ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK = + 1U << ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, + ANDROID_ALARM_ELAPSED_REALTIME_MASK = + 1U << ANDROID_ALARM_ELAPSED_REALTIME, + ANDROID_ALARM_SYSTEMTIME_MASK = 1U << ANDROID_ALARM_SYSTEMTIME, + ANDROID_ALARM_TIME_CHANGE_MASK = 1U << 16 +}; + +/* Disable alarm */ +#define ANDROID_ALARM_CLEAR(type) _IO('a', 0 | ((type) << 4)) + +/* Ack last alarm and wait for next */ +#define ANDROID_ALARM_WAIT _IO('a', 1) + +#define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size) +/* Set alarm */ +#define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec) +#define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec) +#define ANDROID_ALARM_GET_TIME(type) ALARM_IOW(4, type, struct timespec) +#define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec) +#define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0))) +#define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4) + +#endif From d2f68ff041baf535613f6507edeba200b759867e Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 7 Nov 2013 13:46:41 -0800 Subject: [PATCH 09/54] drivers: staging: android: split uapi out of ashmem.h Move the userspace interface of ashmem.h to drivers/staging/android/uapi/ashmem.h Change-Id: I60f5baa4ce8e2425262a406f2733c089ec55aa72 Signed-off-by: Colin Cross --- drivers/staging/android/ashmem.h | 30 +---------------- drivers/staging/android/uapi/ashmem.h | 47 +++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 29 deletions(-) create mode 100644 drivers/staging/android/uapi/ashmem.h diff --git a/drivers/staging/android/ashmem.h b/drivers/staging/android/ashmem.h index 8dc0f0d3adf3..5abcfd7aa706 100644 --- a/drivers/staging/android/ashmem.h +++ b/drivers/staging/android/ashmem.h @@ -16,35 +16,7 @@ #include #include -#define ASHMEM_NAME_LEN 256 - -#define ASHMEM_NAME_DEF "dev/ashmem" - -/* Return values from ASHMEM_PIN: Was the mapping purged while unpinned? */ -#define ASHMEM_NOT_PURGED 0 -#define ASHMEM_WAS_PURGED 1 - -/* Return values from ASHMEM_GET_PIN_STATUS: Is the mapping pinned? */ -#define ASHMEM_IS_UNPINNED 0 -#define ASHMEM_IS_PINNED 1 - -struct ashmem_pin { - __u32 offset; /* offset into region, in bytes, page-aligned */ - __u32 len; /* length forward from offset, in bytes, page-aligned */ -}; - -#define __ASHMEMIOC 0x77 - -#define ASHMEM_SET_NAME _IOW(__ASHMEMIOC, 1, char[ASHMEM_NAME_LEN]) -#define ASHMEM_GET_NAME _IOR(__ASHMEMIOC, 2, char[ASHMEM_NAME_LEN]) -#define ASHMEM_SET_SIZE _IOW(__ASHMEMIOC, 3, size_t) -#define ASHMEM_GET_SIZE _IO(__ASHMEMIOC, 4) -#define ASHMEM_SET_PROT_MASK _IOW(__ASHMEMIOC, 5, unsigned long) -#define ASHMEM_GET_PROT_MASK _IO(__ASHMEMIOC, 6) -#define ASHMEM_PIN _IOW(__ASHMEMIOC, 7, struct ashmem_pin) -#define ASHMEM_UNPIN _IOW(__ASHMEMIOC, 8, struct ashmem_pin) -#define ASHMEM_GET_PIN_STATUS _IO(__ASHMEMIOC, 9) -#define ASHMEM_PURGE_ALL_CACHES _IO(__ASHMEMIOC, 10) +#include "uapi/ashmem.h" /* support of 32bit userspace on 64bit platforms */ #ifdef CONFIG_COMPAT diff --git a/drivers/staging/android/uapi/ashmem.h b/drivers/staging/android/uapi/ashmem.h new file mode 100644 index 000000000000..ba4743c71d6b --- /dev/null +++ b/drivers/staging/android/uapi/ashmem.h @@ -0,0 +1,47 @@ +/* + * drivers/staging/android/uapi/ashmem.h + * + * Copyright 2008 Google Inc. + * Author: Robert Love + * + * This file is dual licensed. It may be redistributed and/or modified + * under the terms of the Apache 2.0 License OR version 2 of the GNU + * General Public License. + */ + +#ifndef _UAPI_LINUX_ASHMEM_H +#define _UAPI_LINUX_ASHMEM_H + +#include + +#define ASHMEM_NAME_LEN 256 + +#define ASHMEM_NAME_DEF "dev/ashmem" + +/* Return values from ASHMEM_PIN: Was the mapping purged while unpinned? */ +#define ASHMEM_NOT_PURGED 0 +#define ASHMEM_WAS_PURGED 1 + +/* Return values from ASHMEM_GET_PIN_STATUS: Is the mapping pinned? */ +#define ASHMEM_IS_UNPINNED 0 +#define ASHMEM_IS_PINNED 1 + +struct ashmem_pin { + __u32 offset; /* offset into region, in bytes, page-aligned */ + __u32 len; /* length forward from offset, in bytes, page-aligned */ +}; + +#define __ASHMEMIOC 0x77 + +#define ASHMEM_SET_NAME _IOW(__ASHMEMIOC, 1, char[ASHMEM_NAME_LEN]) +#define ASHMEM_GET_NAME _IOR(__ASHMEMIOC, 2, char[ASHMEM_NAME_LEN]) +#define ASHMEM_SET_SIZE _IOW(__ASHMEMIOC, 3, size_t) +#define ASHMEM_GET_SIZE _IO(__ASHMEMIOC, 4) +#define ASHMEM_SET_PROT_MASK _IOW(__ASHMEMIOC, 5, unsigned long) +#define ASHMEM_GET_PROT_MASK _IO(__ASHMEMIOC, 6) +#define ASHMEM_PIN _IOW(__ASHMEMIOC, 7, struct ashmem_pin) +#define ASHMEM_UNPIN _IOW(__ASHMEMIOC, 8, struct ashmem_pin) +#define ASHMEM_GET_PIN_STATUS _IO(__ASHMEMIOC, 9) +#define ASHMEM_PURGE_ALL_CACHES _IO(__ASHMEMIOC, 10) + +#endif /* _UAPI_LINUX_ASHMEM_H */ From 30286d2dd2a45be35fb78008a4f1eee1073fce67 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 7 Nov 2013 13:46:41 -0800 Subject: [PATCH 10/54] drivers: staging: android: split uapi out of binder.h Move the userspace interface of binder.h to drivers/staging/android/uapi/binder.h. Change-Id: I2e56ba89ade5e1f33b121e6ecd456392d588a14e Signed-off-by: Colin Cross --- drivers/staging/android/binder.h | 306 +----------------------- drivers/staging/android/uapi/binder.h | 330 ++++++++++++++++++++++++++ 2 files changed, 331 insertions(+), 305 deletions(-) create mode 100644 drivers/staging/android/uapi/binder.h diff --git a/drivers/staging/android/binder.h b/drivers/staging/android/binder.h index dbe81ceca1bd..d4101a671718 100644 --- a/drivers/staging/android/binder.h +++ b/drivers/staging/android/binder.h @@ -20,311 +20,7 @@ #ifndef _LINUX_BINDER_H #define _LINUX_BINDER_H -#include - -#define B_PACK_CHARS(c1, c2, c3, c4) \ - ((((c1)<<24)) | (((c2)<<16)) | (((c3)<<8)) | (c4)) -#define B_TYPE_LARGE 0x85 - -enum { - BINDER_TYPE_BINDER = B_PACK_CHARS('s', 'b', '*', B_TYPE_LARGE), - BINDER_TYPE_WEAK_BINDER = B_PACK_CHARS('w', 'b', '*', B_TYPE_LARGE), - BINDER_TYPE_HANDLE = B_PACK_CHARS('s', 'h', '*', B_TYPE_LARGE), - BINDER_TYPE_WEAK_HANDLE = B_PACK_CHARS('w', 'h', '*', B_TYPE_LARGE), - BINDER_TYPE_FD = B_PACK_CHARS('f', 'd', '*', B_TYPE_LARGE), -}; - -enum { - FLAT_BINDER_FLAG_PRIORITY_MASK = 0xff, - FLAT_BINDER_FLAG_ACCEPTS_FDS = 0x100, -}; - -/* - * This is the flattened representation of a Binder object for transfer - * between processes. The 'offsets' supplied as part of a binder transaction - * contains offsets into the data where these structures occur. The Binder - * driver takes care of re-writing the structure type and data as it moves - * between processes. - */ -struct flat_binder_object { - /* 8 bytes for large_flat_header. */ - unsigned long type; - unsigned long flags; - - /* 8 bytes of data. */ - union { - void __user *binder; /* local object */ - signed long handle; /* remote object */ - }; - - /* extra data associated with local object */ - void __user *cookie; -}; - -/* - * On 64-bit platforms where user code may run in 32-bits the driver must - * translate the buffer (and local binder) addresses appropriately. - */ - -struct binder_write_read { - signed long write_size; /* bytes to write */ - signed long write_consumed; /* bytes consumed by driver */ - unsigned long write_buffer; - signed long read_size; /* bytes to read */ - signed long read_consumed; /* bytes consumed by driver */ - unsigned long read_buffer; -}; - -/* Use with BINDER_VERSION, driver fills in fields. */ -struct binder_version { - /* driver protocol version -- increment with incompatible change */ - signed long protocol_version; -}; - -/* This is the current protocol version. */ -#define BINDER_CURRENT_PROTOCOL_VERSION 7 - -#define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read) -#define BINDER_SET_IDLE_TIMEOUT _IOW('b', 3, __s64) -#define BINDER_SET_MAX_THREADS _IOW('b', 5, size_t) -#define BINDER_SET_IDLE_PRIORITY _IOW('b', 6, __s32) -#define BINDER_SET_CONTEXT_MGR _IOW('b', 7, __s32) -#define BINDER_THREAD_EXIT _IOW('b', 8, __s32) -#define BINDER_VERSION _IOWR('b', 9, struct binder_version) - -/* - * NOTE: Two special error codes you should check for when calling - * in to the driver are: - * - * EINTR -- The operation has been interupted. This should be - * handled by retrying the ioctl() until a different error code - * is returned. - * - * ECONNREFUSED -- The driver is no longer accepting operations - * from your process. That is, the process is being destroyed. - * You should handle this by exiting from your process. Note - * that once this error code is returned, all further calls to - * the driver from any thread will return this same code. - */ - -enum transaction_flags { - TF_ONE_WAY = 0x01, /* this is a one-way call: async, no return */ - TF_ROOT_OBJECT = 0x04, /* contents are the component's root object */ - TF_STATUS_CODE = 0x08, /* contents are a 32-bit status code */ - TF_ACCEPT_FDS = 0x10, /* allow replies with file descriptors */ -}; - -struct binder_transaction_data { - /* The first two are only used for bcTRANSACTION and brTRANSACTION, - * identifying the target and contents of the transaction. - */ - union { - size_t handle; /* target descriptor of command transaction */ - void *ptr; /* target descriptor of return transaction */ - } target; - void *cookie; /* target object cookie */ - unsigned int code; /* transaction command */ - - /* General information about the transaction. */ - unsigned int flags; - pid_t sender_pid; - uid_t sender_euid; - size_t data_size; /* number of bytes of data */ - size_t offsets_size; /* number of bytes of offsets */ - - /* If this transaction is inline, the data immediately - * follows here; otherwise, it ends with a pointer to - * the data buffer. - */ - union { - struct { - /* transaction data */ - const void __user *buffer; - /* offsets from buffer to flat_binder_object structs */ - const void __user *offsets; - } ptr; - uint8_t buf[8]; - } data; -}; - -struct binder_ptr_cookie { - void *ptr; - void *cookie; -}; - -struct binder_pri_desc { - int priority; - int desc; -}; - -struct binder_pri_ptr_cookie { - int priority; - void *ptr; - void *cookie; -}; - -enum binder_driver_return_protocol { - BR_ERROR = _IOR('r', 0, int), - /* - * int: error code - */ - - BR_OK = _IO('r', 1), - /* No parameters! */ - - BR_TRANSACTION = _IOR('r', 2, struct binder_transaction_data), - BR_REPLY = _IOR('r', 3, struct binder_transaction_data), - /* - * binder_transaction_data: the received command. - */ - - BR_ACQUIRE_RESULT = _IOR('r', 4, int), - /* - * not currently supported - * int: 0 if the last bcATTEMPT_ACQUIRE was not successful. - * Else the remote object has acquired a primary reference. - */ - - BR_DEAD_REPLY = _IO('r', 5), - /* - * The target of the last transaction (either a bcTRANSACTION or - * a bcATTEMPT_ACQUIRE) is no longer with us. No parameters. - */ - - BR_TRANSACTION_COMPLETE = _IO('r', 6), - /* - * No parameters... always refers to the last transaction requested - * (including replies). Note that this will be sent even for - * asynchronous transactions. - */ - - BR_INCREFS = _IOR('r', 7, struct binder_ptr_cookie), - BR_ACQUIRE = _IOR('r', 8, struct binder_ptr_cookie), - BR_RELEASE = _IOR('r', 9, struct binder_ptr_cookie), - BR_DECREFS = _IOR('r', 10, struct binder_ptr_cookie), - /* - * void *: ptr to binder - * void *: cookie for binder - */ - - BR_ATTEMPT_ACQUIRE = _IOR('r', 11, struct binder_pri_ptr_cookie), - /* - * not currently supported - * int: priority - * void *: ptr to binder - * void *: cookie for binder - */ - - BR_NOOP = _IO('r', 12), - /* - * No parameters. Do nothing and examine the next command. It exists - * primarily so that we can replace it with a BR_SPAWN_LOOPER command. - */ - - BR_SPAWN_LOOPER = _IO('r', 13), - /* - * No parameters. The driver has determined that a process has no - * threads waiting to service incoming transactions. When a process - * receives this command, it must spawn a new service thread and - * register it via bcENTER_LOOPER. - */ - - BR_FINISHED = _IO('r', 14), - /* - * not currently supported - * stop threadpool thread - */ - - BR_DEAD_BINDER = _IOR('r', 15, void *), - /* - * void *: cookie - */ - BR_CLEAR_DEATH_NOTIFICATION_DONE = _IOR('r', 16, void *), - /* - * void *: cookie - */ - - BR_FAILED_REPLY = _IO('r', 17), - /* - * The the last transaction (either a bcTRANSACTION or - * a bcATTEMPT_ACQUIRE) failed (e.g. out of memory). No parameters. - */ -}; - -enum binder_driver_command_protocol { - BC_TRANSACTION = _IOW('c', 0, struct binder_transaction_data), - BC_REPLY = _IOW('c', 1, struct binder_transaction_data), - /* - * binder_transaction_data: the sent command. - */ - - BC_ACQUIRE_RESULT = _IOW('c', 2, int), - /* - * not currently supported - * int: 0 if the last BR_ATTEMPT_ACQUIRE was not successful. - * Else you have acquired a primary reference on the object. - */ - - BC_FREE_BUFFER = _IOW('c', 3, int), - /* - * void *: ptr to transaction data received on a read - */ - - BC_INCREFS = _IOW('c', 4, int), - BC_ACQUIRE = _IOW('c', 5, int), - BC_RELEASE = _IOW('c', 6, int), - BC_DECREFS = _IOW('c', 7, int), - /* - * int: descriptor - */ - - BC_INCREFS_DONE = _IOW('c', 8, struct binder_ptr_cookie), - BC_ACQUIRE_DONE = _IOW('c', 9, struct binder_ptr_cookie), - /* - * void *: ptr to binder - * void *: cookie for binder - */ - - BC_ATTEMPT_ACQUIRE = _IOW('c', 10, struct binder_pri_desc), - /* - * not currently supported - * int: priority - * int: descriptor - */ - - BC_REGISTER_LOOPER = _IO('c', 11), - /* - * No parameters. - * Register a spawned looper thread with the device. - */ - - BC_ENTER_LOOPER = _IO('c', 12), - BC_EXIT_LOOPER = _IO('c', 13), - /* - * No parameters. - * These two commands are sent as an application-level thread - * enters and exits the binder loop, respectively. They are - * used so the binder can have an accurate count of the number - * of looping threads it has available. - */ - - BC_REQUEST_DEATH_NOTIFICATION = _IOW('c', 14, struct binder_ptr_cookie), - /* - * void *: ptr to binder - * void *: cookie - */ - - BC_CLEAR_DEATH_NOTIFICATION = _IOW('c', 15, struct binder_ptr_cookie), - /* - * void *: ptr to binder - * void *: cookie - */ - - BC_DEAD_BINDER_DONE = _IOW('c', 16, void *), - /* - * void *: cookie - */ -}; +#include "uapi/binder.h" #endif /* _LINUX_BINDER_H */ diff --git a/drivers/staging/android/uapi/binder.h b/drivers/staging/android/uapi/binder.h new file mode 100644 index 000000000000..b6cb483592ca --- /dev/null +++ b/drivers/staging/android/uapi/binder.h @@ -0,0 +1,330 @@ +/* + * Copyright (C) 2008 Google, Inc. + * + * Based on, but no longer compatible with, the original + * OpenBinder.org binder driver interface, which is: + * + * Copyright (c) 2005 Palmsource, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#ifndef _UAPI_LINUX_BINDER_H +#define _UAPI_LINUX_BINDER_H + +#include + +#define B_PACK_CHARS(c1, c2, c3, c4) \ + ((((c1)<<24)) | (((c2)<<16)) | (((c3)<<8)) | (c4)) +#define B_TYPE_LARGE 0x85 + +enum { + BINDER_TYPE_BINDER = B_PACK_CHARS('s', 'b', '*', B_TYPE_LARGE), + BINDER_TYPE_WEAK_BINDER = B_PACK_CHARS('w', 'b', '*', B_TYPE_LARGE), + BINDER_TYPE_HANDLE = B_PACK_CHARS('s', 'h', '*', B_TYPE_LARGE), + BINDER_TYPE_WEAK_HANDLE = B_PACK_CHARS('w', 'h', '*', B_TYPE_LARGE), + BINDER_TYPE_FD = B_PACK_CHARS('f', 'd', '*', B_TYPE_LARGE), +}; + +enum { + FLAT_BINDER_FLAG_PRIORITY_MASK = 0xff, + FLAT_BINDER_FLAG_ACCEPTS_FDS = 0x100, +}; + +/* + * This is the flattened representation of a Binder object for transfer + * between processes. The 'offsets' supplied as part of a binder transaction + * contains offsets into the data where these structures occur. The Binder + * driver takes care of re-writing the structure type and data as it moves + * between processes. + */ +struct flat_binder_object { + /* 8 bytes for large_flat_header. */ + unsigned long type; + unsigned long flags; + + /* 8 bytes of data. */ + union { + void __user *binder; /* local object */ + signed long handle; /* remote object */ + }; + + /* extra data associated with local object */ + void __user *cookie; +}; + +/* + * On 64-bit platforms where user code may run in 32-bits the driver must + * translate the buffer (and local binder) addresses appropriately. + */ + +struct binder_write_read { + signed long write_size; /* bytes to write */ + signed long write_consumed; /* bytes consumed by driver */ + unsigned long write_buffer; + signed long read_size; /* bytes to read */ + signed long read_consumed; /* bytes consumed by driver */ + unsigned long read_buffer; +}; + +/* Use with BINDER_VERSION, driver fills in fields. */ +struct binder_version { + /* driver protocol version -- increment with incompatible change */ + signed long protocol_version; +}; + +/* This is the current protocol version. */ +#define BINDER_CURRENT_PROTOCOL_VERSION 7 + +#define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read) +#define BINDER_SET_IDLE_TIMEOUT _IOW('b', 3, __s64) +#define BINDER_SET_MAX_THREADS _IOW('b', 5, size_t) +#define BINDER_SET_IDLE_PRIORITY _IOW('b', 6, __s32) +#define BINDER_SET_CONTEXT_MGR _IOW('b', 7, __s32) +#define BINDER_THREAD_EXIT _IOW('b', 8, __s32) +#define BINDER_VERSION _IOWR('b', 9, struct binder_version) + +/* + * NOTE: Two special error codes you should check for when calling + * in to the driver are: + * + * EINTR -- The operation has been interupted. This should be + * handled by retrying the ioctl() until a different error code + * is returned. + * + * ECONNREFUSED -- The driver is no longer accepting operations + * from your process. That is, the process is being destroyed. + * You should handle this by exiting from your process. Note + * that once this error code is returned, all further calls to + * the driver from any thread will return this same code. + */ + +enum transaction_flags { + TF_ONE_WAY = 0x01, /* this is a one-way call: async, no return */ + TF_ROOT_OBJECT = 0x04, /* contents are the component's root object */ + TF_STATUS_CODE = 0x08, /* contents are a 32-bit status code */ + TF_ACCEPT_FDS = 0x10, /* allow replies with file descriptors */ +}; + +struct binder_transaction_data { + /* The first two are only used for bcTRANSACTION and brTRANSACTION, + * identifying the target and contents of the transaction. + */ + union { + size_t handle; /* target descriptor of command transaction */ + void *ptr; /* target descriptor of return transaction */ + } target; + void *cookie; /* target object cookie */ + unsigned int code; /* transaction command */ + + /* General information about the transaction. */ + unsigned int flags; + pid_t sender_pid; + uid_t sender_euid; + size_t data_size; /* number of bytes of data */ + size_t offsets_size; /* number of bytes of offsets */ + + /* If this transaction is inline, the data immediately + * follows here; otherwise, it ends with a pointer to + * the data buffer. + */ + union { + struct { + /* transaction data */ + const void __user *buffer; + /* offsets from buffer to flat_binder_object structs */ + const void __user *offsets; + } ptr; + uint8_t buf[8]; + } data; +}; + +struct binder_ptr_cookie { + void *ptr; + void *cookie; +}; + +struct binder_pri_desc { + int priority; + int desc; +}; + +struct binder_pri_ptr_cookie { + int priority; + void *ptr; + void *cookie; +}; + +enum binder_driver_return_protocol { + BR_ERROR = _IOR('r', 0, int), + /* + * int: error code + */ + + BR_OK = _IO('r', 1), + /* No parameters! */ + + BR_TRANSACTION = _IOR('r', 2, struct binder_transaction_data), + BR_REPLY = _IOR('r', 3, struct binder_transaction_data), + /* + * binder_transaction_data: the received command. + */ + + BR_ACQUIRE_RESULT = _IOR('r', 4, int), + /* + * not currently supported + * int: 0 if the last bcATTEMPT_ACQUIRE was not successful. + * Else the remote object has acquired a primary reference. + */ + + BR_DEAD_REPLY = _IO('r', 5), + /* + * The target of the last transaction (either a bcTRANSACTION or + * a bcATTEMPT_ACQUIRE) is no longer with us. No parameters. + */ + + BR_TRANSACTION_COMPLETE = _IO('r', 6), + /* + * No parameters... always refers to the last transaction requested + * (including replies). Note that this will be sent even for + * asynchronous transactions. + */ + + BR_INCREFS = _IOR('r', 7, struct binder_ptr_cookie), + BR_ACQUIRE = _IOR('r', 8, struct binder_ptr_cookie), + BR_RELEASE = _IOR('r', 9, struct binder_ptr_cookie), + BR_DECREFS = _IOR('r', 10, struct binder_ptr_cookie), + /* + * void *: ptr to binder + * void *: cookie for binder + */ + + BR_ATTEMPT_ACQUIRE = _IOR('r', 11, struct binder_pri_ptr_cookie), + /* + * not currently supported + * int: priority + * void *: ptr to binder + * void *: cookie for binder + */ + + BR_NOOP = _IO('r', 12), + /* + * No parameters. Do nothing and examine the next command. It exists + * primarily so that we can replace it with a BR_SPAWN_LOOPER command. + */ + + BR_SPAWN_LOOPER = _IO('r', 13), + /* + * No parameters. The driver has determined that a process has no + * threads waiting to service incoming transactions. When a process + * receives this command, it must spawn a new service thread and + * register it via bcENTER_LOOPER. + */ + + BR_FINISHED = _IO('r', 14), + /* + * not currently supported + * stop threadpool thread + */ + + BR_DEAD_BINDER = _IOR('r', 15, void *), + /* + * void *: cookie + */ + BR_CLEAR_DEATH_NOTIFICATION_DONE = _IOR('r', 16, void *), + /* + * void *: cookie + */ + + BR_FAILED_REPLY = _IO('r', 17), + /* + * The the last transaction (either a bcTRANSACTION or + * a bcATTEMPT_ACQUIRE) failed (e.g. out of memory). No parameters. + */ +}; + +enum binder_driver_command_protocol { + BC_TRANSACTION = _IOW('c', 0, struct binder_transaction_data), + BC_REPLY = _IOW('c', 1, struct binder_transaction_data), + /* + * binder_transaction_data: the sent command. + */ + + BC_ACQUIRE_RESULT = _IOW('c', 2, int), + /* + * not currently supported + * int: 0 if the last BR_ATTEMPT_ACQUIRE was not successful. + * Else you have acquired a primary reference on the object. + */ + + BC_FREE_BUFFER = _IOW('c', 3, int), + /* + * void *: ptr to transaction data received on a read + */ + + BC_INCREFS = _IOW('c', 4, int), + BC_ACQUIRE = _IOW('c', 5, int), + BC_RELEASE = _IOW('c', 6, int), + BC_DECREFS = _IOW('c', 7, int), + /* + * int: descriptor + */ + + BC_INCREFS_DONE = _IOW('c', 8, struct binder_ptr_cookie), + BC_ACQUIRE_DONE = _IOW('c', 9, struct binder_ptr_cookie), + /* + * void *: ptr to binder + * void *: cookie for binder + */ + + BC_ATTEMPT_ACQUIRE = _IOW('c', 10, struct binder_pri_desc), + /* + * not currently supported + * int: priority + * int: descriptor + */ + + BC_REGISTER_LOOPER = _IO('c', 11), + /* + * No parameters. + * Register a spawned looper thread with the device. + */ + + BC_ENTER_LOOPER = _IO('c', 12), + BC_EXIT_LOOPER = _IO('c', 13), + /* + * No parameters. + * These two commands are sent as an application-level thread + * enters and exits the binder loop, respectively. They are + * used so the binder can have an accurate count of the number + * of looping threads it has available. + */ + + BC_REQUEST_DEATH_NOTIFICATION = _IOW('c', 14, struct binder_ptr_cookie), + /* + * void *: ptr to binder + * void *: cookie + */ + + BC_CLEAR_DEATH_NOTIFICATION = _IOW('c', 15, struct binder_ptr_cookie), + /* + * void *: ptr to binder + * void *: cookie + */ + + BC_DEAD_BINDER_DONE = _IOW('c', 16, void *), + /* + * void *: cookie + */ +}; + +#endif /* _UAPI_LINUX_BINDER_H */ + From 7fbddfd1dab3e7c64e88939d796cf60ea1dde8a2 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 7 Nov 2013 13:46:41 -0800 Subject: [PATCH 11/54] drivers: staging: android: split uapi out of sync.h and sw_sync.h Move the userspace interfaces of sync.h and sw_sync.h to drivers/staging/android/uapi/ Change-Id: I3b2598b37385bb993bd03f5faa98a8e196befe45 Signed-off-by: Colin Cross --- drivers/staging/android/sw_sync.h | 19 +---- drivers/staging/android/sync.h | 86 +---------------------- drivers/staging/android/uapi/sw_sync.h | 32 +++++++++ drivers/staging/android/uapi/sync.h | 97 ++++++++++++++++++++++++++ 4 files changed, 132 insertions(+), 102 deletions(-) create mode 100644 drivers/staging/android/uapi/sw_sync.h create mode 100644 drivers/staging/android/uapi/sync.h diff --git a/drivers/staging/android/sw_sync.h b/drivers/staging/android/sw_sync.h index aba25cbb0382..1a50669ec8a9 100644 --- a/drivers/staging/android/sw_sync.h +++ b/drivers/staging/android/sw_sync.h @@ -18,11 +18,9 @@ #define _LINUX_SW_SYNC_H #include - -#ifdef __KERNEL__ - #include #include "sync.h" +#include "uapi/sw_sync.h" struct sw_sync_timeline { struct sync_timeline obj; @@ -58,19 +56,4 @@ static inline struct sync_pt *sw_sync_pt_create(struct sw_sync_timeline *obj, } #endif /* IS_ENABLED(CONFIG_SW_SYNC) */ -#endif /* __KERNEL __ */ - -struct sw_sync_create_fence_data { - __u32 value; - char name[32]; - __s32 fence; /* fd of new fence */ -}; - -#define SW_SYNC_IOC_MAGIC 'W' - -#define SW_SYNC_IOC_CREATE_FENCE _IOWR(SW_SYNC_IOC_MAGIC, 0,\ - struct sw_sync_create_fence_data) -#define SW_SYNC_IOC_INC _IOW(SW_SYNC_IOC_MAGIC, 1, __u32) - - #endif /* _LINUX_SW_SYNC_H */ diff --git a/drivers/staging/android/sync.h b/drivers/staging/android/sync.h index 38ea986dc70f..75da9e85ac69 100644 --- a/drivers/staging/android/sync.h +++ b/drivers/staging/android/sync.h @@ -14,14 +14,14 @@ #define _LINUX_SYNC_H #include -#ifdef __KERNEL__ - #include #include #include #include #include +#include "uapi/sync.h" + struct sync_timeline; struct sync_pt; struct sync_fence; @@ -341,86 +341,4 @@ int sync_fence_cancel_async(struct sync_fence *fence, */ int sync_fence_wait(struct sync_fence *fence, long timeout); -#endif /* __KERNEL__ */ - -/** - * struct sync_merge_data - data passed to merge ioctl - * @fd2: file descriptor of second fence - * @name: name of new fence - * @fence: returns the fd of the new fence to userspace - */ -struct sync_merge_data { - __s32 fd2; /* fd of second fence */ - char name[32]; /* name of new fence */ - __s32 fence; /* fd on newly created fence */ -}; - -/** - * struct sync_pt_info - detailed sync_pt information - * @len: length of sync_pt_info including any driver_data - * @obj_name: name of parent sync_timeline - * @driver_name: name of driver implmenting the parent - * @status: status of the sync_pt 0:active 1:signaled <0:error - * @timestamp_ns: timestamp of status change in nanoseconds - * @driver_data: any driver dependant data - */ -struct sync_pt_info { - __u32 len; - char obj_name[32]; - char driver_name[32]; - __s32 status; - __u64 timestamp_ns; - - __u8 driver_data[0]; -}; - -/** - * struct sync_fence_info_data - data returned from fence info ioctl - * @len: ioctl caller writes the size of the buffer its passing in. - * ioctl returns length of sync_fence_data reutnred to userspace - * including pt_info. - * @name: name of fence - * @status: status of fence. 1: signaled 0:active <0:error - * @pt_info: a sync_pt_info struct for every sync_pt in the fence - */ -struct sync_fence_info_data { - __u32 len; - char name[32]; - __s32 status; - - __u8 pt_info[0]; -}; - -#define SYNC_IOC_MAGIC '>' - -/** - * DOC: SYNC_IOC_WAIT - wait for a fence to signal - * - * pass timeout in milliseconds. Waits indefinitely timeout < 0. - */ -#define SYNC_IOC_WAIT _IOW(SYNC_IOC_MAGIC, 0, __s32) - -/** - * DOC: SYNC_IOC_MERGE - merge two fences - * - * Takes a struct sync_merge_data. Creates a new fence containing copies of - * the sync_pts in both the calling fd and sync_merge_data.fd2. Returns the - * new fence's fd in sync_merge_data.fence - */ -#define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 1, struct sync_merge_data) - -/** - * DOC: SYNC_IOC_FENCE_INFO - get detailed information on a fence - * - * Takes a struct sync_fence_info_data with extra space allocated for pt_info. - * Caller should write the size of the buffer into len. On return, len is - * updated to reflect the total size of the sync_fence_info_data including - * pt_info. - * - * pt_info is a buffer containing sync_pt_infos for every sync_pt in the fence. - * To itterate over the sync_pt_infos, use the sync_pt_info.len field. - */ -#define SYNC_IOC_FENCE_INFO _IOWR(SYNC_IOC_MAGIC, 2,\ - struct sync_fence_info_data) - #endif /* _LINUX_SYNC_H */ diff --git a/drivers/staging/android/uapi/sw_sync.h b/drivers/staging/android/uapi/sw_sync.h new file mode 100644 index 000000000000..9b5d4869505c --- /dev/null +++ b/drivers/staging/android/uapi/sw_sync.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2012 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#ifndef _UAPI_LINUX_SW_SYNC_H +#define _UAPI_LINUX_SW_SYNC_H + +#include + +struct sw_sync_create_fence_data { + __u32 value; + char name[32]; + __s32 fence; /* fd of new fence */ +}; + +#define SW_SYNC_IOC_MAGIC 'W' + +#define SW_SYNC_IOC_CREATE_FENCE _IOWR(SW_SYNC_IOC_MAGIC, 0,\ + struct sw_sync_create_fence_data) +#define SW_SYNC_IOC_INC _IOW(SW_SYNC_IOC_MAGIC, 1, __u32) + +#endif /* _UAPI_LINUX_SW_SYNC_H */ diff --git a/drivers/staging/android/uapi/sync.h b/drivers/staging/android/uapi/sync.h new file mode 100644 index 000000000000..57fdaadc4b04 --- /dev/null +++ b/drivers/staging/android/uapi/sync.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2012 Google, Inc. + * + * 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. + * + */ + +#ifndef _UAPI_LINUX_SYNC_H +#define _UAPI_LINUX_SYNC_H + +#include +#include + +/** + * struct sync_merge_data - data passed to merge ioctl + * @fd2: file descriptor of second fence + * @name: name of new fence + * @fence: returns the fd of the new fence to userspace + */ +struct sync_merge_data { + __s32 fd2; /* fd of second fence */ + char name[32]; /* name of new fence */ + __s32 fence; /* fd on newly created fence */ +}; + +/** + * struct sync_pt_info - detailed sync_pt information + * @len: length of sync_pt_info including any driver_data + * @obj_name: name of parent sync_timeline + * @driver_name: name of driver implmenting the parent + * @status: status of the sync_pt 0:active 1:signaled <0:error + * @timestamp_ns: timestamp of status change in nanoseconds + * @driver_data: any driver dependant data + */ +struct sync_pt_info { + __u32 len; + char obj_name[32]; + char driver_name[32]; + __s32 status; + __u64 timestamp_ns; + + __u8 driver_data[0]; +}; + +/** + * struct sync_fence_info_data - data returned from fence info ioctl + * @len: ioctl caller writes the size of the buffer its passing in. + * ioctl returns length of sync_fence_data reutnred to userspace + * including pt_info. + * @name: name of fence + * @status: status of fence. 1: signaled 0:active <0:error + * @pt_info: a sync_pt_info struct for every sync_pt in the fence + */ +struct sync_fence_info_data { + __u32 len; + char name[32]; + __s32 status; + + __u8 pt_info[0]; +}; + +#define SYNC_IOC_MAGIC '>' + +/** + * DOC: SYNC_IOC_WAIT - wait for a fence to signal + * + * pass timeout in milliseconds. Waits indefinitely timeout < 0. + */ +#define SYNC_IOC_WAIT _IOW(SYNC_IOC_MAGIC, 0, __s32) + +/** + * DOC: SYNC_IOC_MERGE - merge two fences + * + * Takes a struct sync_merge_data. Creates a new fence containing copies of + * the sync_pts in both the calling fd and sync_merge_data.fd2. Returns the + * new fence's fd in sync_merge_data.fence + */ +#define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 1, struct sync_merge_data) + +/** + * DOC: SYNC_IOC_FENCE_INFO - get detailed information on a fence + * + * Takes a struct sync_fence_info_data with extra space allocated for pt_info. + * Caller should write the size of the buffer into len. On return, len is + * updated to reflect the total size of the sync_fence_info_data including + * pt_info. + * + * pt_info is a buffer containing sync_pt_infos for every sync_pt in the fence. + * To itterate over the sync_pt_infos, use the sync_pt_info.len field. + */ +#define SYNC_IOC_FENCE_INFO _IOWR(SYNC_IOC_MAGIC, 2,\ + struct sync_fence_info_data) + +#endif /* _UAPI_LINUX_SYNC_H */ From 527aae529118f2cbe99c945ffe74be1c04ceaba6 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 30 Oct 2013 13:14:12 -0700 Subject: [PATCH 12/54] mm: fix anon vma naming Fix two bugs caused by merging anon vma_naming, a typo in mempolicy.c and a bad merge in sys.c. Change-Id: Ia4ced447d50573e68195e95ea2f2b4d9456b8a90 Signed-off-by: Colin Cross --- kernel/sys.c | 6 +++--- mm/mempolicy.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/sys.c b/kernel/sys.c index 1c9090bc6746..3dcf1de0eb74 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -2368,9 +2368,6 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, else return -EINVAL; break; - case PR_SET_VMA: - error = prctl_set_vma(arg2, arg3, arg4, arg5); - break; default: return -EINVAL; } @@ -2407,6 +2404,9 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, if (arg2 || arg3 || arg4 || arg5) return -EINVAL; return current->no_new_privs ? 1 : 0; + case PR_SET_VMA: + error = prctl_set_vma(arg2, arg3, arg4, arg5); + break; default: error = -EINVAL; break; diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 7b349aafe79d..bf12a3fc120c 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -728,7 +728,7 @@ static int mbind_range(struct mm_struct *mm, unsigned long start, ((vmstart - vma->vm_start) >> PAGE_SHIFT); prev = vma_merge(mm, prev, vmstart, vmend, vma->vm_flags, vma->anon_vma, vma->vm_file, pgoff, - new_pol, vma_get_anon_name(name)); + new_pol, vma_get_anon_name(vma)); if (prev) { vma = prev; next = vma->vm_next; From d67a07b6ec961b4e14356d545040769be95ce178 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 30 Oct 2013 13:17:34 -0700 Subject: [PATCH 13/54] anonymous vma names: fix build with !MMU Disable PR_SET_VMA when building with !MMU Change-Id: I896b6979b99aa61df85caf4c3ec22eb8a8204e64 Signed-off-by: Colin Cross --- kernel/sys.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/kernel/sys.c b/kernel/sys.c index 3dcf1de0eb74..126b7c939d1f 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -2101,7 +2101,7 @@ static int prctl_get_tid_address(struct task_struct *me, int __user **tid_addr) } #endif - +#ifdef CONFIG_MMU static int prctl_update_vma_anon_name(struct vm_area_struct *vma, struct vm_area_struct **prev, unsigned long start, unsigned long end, @@ -2240,6 +2240,13 @@ static int prctl_set_vma(unsigned long opt, unsigned long start, return error; } +#else /* CONFIG_MMU */ +static int prctl_set_vma(unsigned long opt, unsigned long start, + unsigned long len_in, unsigned long arg) +{ + return -EINVAL; +} +#endif SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, unsigned long, arg4, unsigned long, arg5) From 4244575c2f5d35c56b88d3d5bd34558c111e8667 Mon Sep 17 00:00:00 2001 From: Benoit Goby Date: Fri, 8 Nov 2013 15:24:19 -0800 Subject: [PATCH 14/54] ARM: Fix dtb list when DTB_IMAGE_NAMES is empty In the 3.10 kernel, dtb-y is not defined in Makefile.boot anymore but in dts/Makefile, so it needs to be included too. Change-Id: I6d6fccf933709bcb6220ce8f12b4b9e2a7c40d63 Signed-off-by: Benoit Goby --- arch/arm/boot/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index 3310df3a0569..65285bbbf899 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile @@ -14,6 +14,7 @@ ifneq ($(MACHINE),) include $(srctree)/$(MACHINE)/Makefile.boot endif +include $(srctree)/arch/arm/boot/dts/Makefile # Note: the following conditions must always be true: # ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET) From 47e0f4d1dcbf4d84c8f7982e5f5ebaa5ba67ecc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= Date: Fri, 14 Jun 2013 19:54:40 -0700 Subject: [PATCH 15/54] ARM: Fix "Make low-level printk work" to use a separate config option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Arve Hjønnevåg --- arch/arm/Kconfig.debug | 8 ++++++++ kernel/printk.c | 10 +++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 21cc8a765988..a640f09ec842 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -690,6 +690,14 @@ config EARLY_PRINTK kernel low-level debugging functions. Add earlyprintk to your kernel parameters to enable this console. +config EARLY_PRINTK_DIRECT + bool "Early printk direct" + depends on DEBUG_LL + help + Say Y here if you want to have an early console using the + kernel low-level debugging functions and EARLY_PRINTK is + not early enough. + config OC_ETM bool "On-chip ETM and ETB" depends on ARM_AMBA diff --git a/kernel/printk.c b/kernel/printk.c index 9cb84eb1a9de..c2f720eb4283 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -51,7 +51,7 @@ #define CREATE_TRACE_POINTS #include -#ifdef CONFIG_DEBUG_LL +#ifdef CONFIG_EARLY_PRINTK_DIRECT extern void printascii(char *); #endif @@ -1556,10 +1556,6 @@ asmlinkage int vprintk_emit(int facility, int level, */ text_len = vscnprintf(text, sizeof(textbuf), fmt, args); -#ifdef CONFIG_DEBUG_LL - printascii(text); -#endif - /* mark and strip a trailing newline */ if (text_len && text[text_len-1] == '\n') { text_len--; @@ -1586,6 +1582,10 @@ asmlinkage int vprintk_emit(int facility, int level, } } +#ifdef CONFIG_EARLY_PRINTK_DIRECT + printascii(text); +#endif + if (level == -1) level = default_message_loglevel; From eec88854d8ecdab5e5d16ee50d95fb9c478114a2 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 14 Nov 2013 16:25:08 -0800 Subject: [PATCH 16/54] ion: Fix compat support to use proper compat ioctl numbers The compat support added to ion didn't provide compat ioctl numbers (who's value depends on the compat structure size). So 32bit applications would get an error when trying to make ioctl calls. This patch adds the needed COMPAT_ macros and uses them in the compat_ion_ioctl, translating them to their non-compat cmd when calling the normal ioctl call. Change-Id: I53636d4ec46d8dc5e694697aaf2d62b98bd78cb1 Signed-off-by: John Stultz --- drivers/staging/android/ion/compat_ion.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/staging/android/ion/compat_ion.c b/drivers/staging/android/ion/compat_ion.c index 0416fabfc1b9..a89b067ec051 100644 --- a/drivers/staging/android/ion/compat_ion.c +++ b/drivers/staging/android/ion/compat_ion.c @@ -35,6 +35,12 @@ struct compat_ion_custom_data { compat_ulong_t arg; }; +#define COMPAT_ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \ + struct compat_ion_allocation_data) +#define COMPAT_ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data) +#define COMPAT_ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, \ + struct compat_ion_custom_data) + static int compat_get_ion_allocation_data( struct compat_ion_allocation_data __user *data32, struct ion_allocation_data __user *data) @@ -105,7 +111,7 @@ long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return -ENOTTY; switch (cmd) { - case ION_IOC_ALLOC: + case COMPAT_ION_IOC_ALLOC: { struct compat_ion_allocation_data __user *data32; struct ion_allocation_data __user *data; @@ -119,13 +125,12 @@ long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) err = compat_get_ion_allocation_data(data32, data); if (err) return err; - - ret = filp->f_op->unlocked_ioctl(filp, cmd, + ret = filp->f_op->unlocked_ioctl(filp, ION_IOC_ALLOC, (unsigned long)data); err = compat_put_ion_allocation_data(data32, data); return ret ? ret : err; } - case ION_IOC_FREE: + case COMPAT_ION_IOC_FREE: { struct compat_ion_allocation_data __user *data32; struct ion_allocation_data __user *data; @@ -140,10 +145,10 @@ long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (err) return err; - return filp->f_op->unlocked_ioctl(filp, cmd, + return filp->f_op->unlocked_ioctl(filp, ION_IOC_FREE, (unsigned long)data); } - case ION_IOC_CUSTOM: { + case COMPAT_ION_IOC_CUSTOM: { struct compat_ion_custom_data __user *data32; struct ion_custom_data __user *data; int err; @@ -157,7 +162,7 @@ long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (err) return err; - return filp->f_op->unlocked_ioctl(filp, cmd, + return filp->f_op->unlocked_ioctl(filp, ION_IOC_CUSTOM, (unsigned long)data); } case ION_IOC_SHARE: From 33a57aa073dac709bcdcba23bc4e2e7fcc6330f6 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 5 Nov 2013 16:51:27 -0800 Subject: [PATCH 17/54] ion: hold reference to handle after ion_uhandle_get commit 1262ab1846cf76f7549c66ef709120dbfbe6d49f (ion: replace userspace handle cookies with idr) broke the locking in ion. The ION_IOC_FREE and ION_IOC_MAP ioctls were relying on ion_handle_validate to detect the case where a call raced with another ION_IOC_FREE which may have freed the struct ion_handle. Rename ion_uhandle_get to ion_handle_get_by_id, and have it take the client lock and return with an extra reference to the handle. Make each caller put its reference once it is done with the handle. Also modify users of ion_handle_validate to continue to hold the client lock after calling ion_handle_validate until they are done with the handle, and warn if ion_handle_validate is called without the client lock held. Change-Id: I56da5624fca3bed4ee24806b6ec39de903543341 Signed-off-by: Colin Cross --- drivers/staging/android/ion/ion.c | 56 ++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 5c886fc9cd7e..0e379a338105 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -383,7 +383,14 @@ static void ion_handle_get(struct ion_handle *handle) static int ion_handle_put(struct ion_handle *handle) { - return kref_put(&handle->ref, ion_handle_destroy); + struct ion_client *client = handle->client; + int ret; + + mutex_lock(&client->lock); + ret = kref_put(&handle->ref, ion_handle_destroy); + mutex_unlock(&client->lock); + + return ret; } static struct ion_handle *ion_handle_lookup(struct ion_client *client, @@ -403,14 +410,24 @@ static struct ion_handle *ion_handle_lookup(struct ion_client *client, return ERR_PTR(-EINVAL); } -static struct ion_handle *ion_uhandle_get(struct ion_client *client, int id) +static struct ion_handle *ion_handle_get_by_id(struct ion_client *client, + int id) { - return idr_find(&client->idr, id); + struct ion_handle *handle; + + mutex_lock(&client->lock); + handle = idr_find(&client->idr, id); + if (handle) + ion_handle_get(handle); + mutex_unlock(&client->lock); + + return handle ? handle : ERR_PTR(-EINVAL); } static bool ion_handle_validate(struct ion_client *client, struct ion_handle *handle) { - return (ion_uhandle_get(client, handle->id) == handle); + WARN_ON(!mutex_is_locked(&client->lock)); + return (idr_find(&client->idr, handle->id) == handle); } static int ion_handle_add(struct ion_client *client, struct ion_handle *handle) @@ -503,11 +520,11 @@ struct ion_handle *ion_alloc(struct ion_client *client, size_t len, mutex_lock(&client->lock); ret = ion_handle_add(client, handle); + mutex_unlock(&client->lock); if (ret) { ion_handle_put(handle); handle = ERR_PTR(ret); } - mutex_unlock(&client->lock); return handle; } @@ -527,8 +544,8 @@ void ion_free(struct ion_client *client, struct ion_handle *handle) mutex_unlock(&client->lock); return; } - ion_handle_put(handle); mutex_unlock(&client->lock); + ion_handle_put(handle); } EXPORT_SYMBOL(ion_free); @@ -1021,14 +1038,15 @@ struct dma_buf *ion_share_dma_buf(struct ion_client *client, mutex_lock(&client->lock); valid_handle = ion_handle_validate(client, handle); - mutex_unlock(&client->lock); if (!valid_handle) { WARN(1, "%s: invalid handle passed to share.\n", __func__); + mutex_unlock(&client->lock); return ERR_PTR(-EINVAL); } - buffer = handle->buffer; ion_buffer_get(buffer); + mutex_unlock(&client->lock); + dmabuf = dma_buf_export(buffer, &dma_buf_ops, buffer->size, O_RDWR); if (IS_ERR(dmabuf)) { ion_buffer_put(buffer); @@ -1081,18 +1099,24 @@ struct ion_handle *ion_import_dma_buf(struct ion_client *client, int fd) handle = ion_handle_lookup(client, buffer); if (!IS_ERR(handle)) { ion_handle_get(handle); + mutex_unlock(&client->lock); goto end; } + mutex_unlock(&client->lock); + handle = ion_handle_create(client, buffer); if (IS_ERR(handle)) goto end; + + mutex_lock(&client->lock); ret = ion_handle_add(client, handle); + mutex_unlock(&client->lock); if (ret) { ion_handle_put(handle); handle = ERR_PTR(ret); } + end: - mutex_unlock(&client->lock); dma_buf_put(dmabuf); return handle; } @@ -1156,12 +1180,11 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (copy_from_user(&data, (void __user *)arg, sizeof(struct ion_handle_data))) return -EFAULT; - mutex_lock(&client->lock); - handle = ion_uhandle_get(client, data.handle); - mutex_unlock(&client->lock); - if (!handle) - return -EINVAL; + handle = ion_handle_get_by_id(client, data.handle); + if (IS_ERR(handle)) + return PTR_ERR(handle); ion_free(client, handle); + ion_handle_put(handle); break; } case ION_IOC_SHARE: @@ -1172,8 +1195,11 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (copy_from_user(&data, (void __user *)arg, sizeof(data))) return -EFAULT; - handle = ion_uhandle_get(client, data.handle); + handle = ion_handle_get_by_id(client, data.handle); + if (IS_ERR(handle)) + return PTR_ERR(handle); data.fd = ion_share_dma_buf_fd(client, handle); + ion_handle_put(handle); if (copy_to_user((void __user *)arg, &data, sizeof(data))) return -EFAULT; if (data.fd < 0) From 49bdc418a3c1129d49fe92d89cf77111584fb51f Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 13 Nov 2013 14:44:53 -0800 Subject: [PATCH 18/54] ion: fix crash when alloc len is -1 If userspace passes a length between -4095 and -1 to allocate it will pass the len != 0 check, but when len is page aligned it will be 0. Check len after page aligning. Drop the warning as well, userspace shouldn't be able to trigger a warning in the kernel. Change-Id: I96c7142637638991f3a9af9be7cfbb50f79f3803 Signed-off-by: Colin Cross --- drivers/staging/android/ion/ion.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 0e379a338105..a8d4735b462c 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -485,11 +485,11 @@ struct ion_handle *ion_alloc(struct ion_client *client, size_t len, * request of the caller allocate from it. Repeat until allocate has * succeeded or all heaps have been tried */ - if (WARN_ON(!len)) - return ERR_PTR(-EINVAL); - len = PAGE_ALIGN(len); + if (!len) + return ERR_PTR(-EINVAL); + down_read(&dev->lock); plist_for_each_entry(heap, &dev->heaps, node) { /* if the caller didn't specify this heap id */ From 51e3580bf9da57da9c860330293b73b0dbb296e0 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 18 Sep 2013 12:30:20 -0500 Subject: [PATCH 19/54] ion: fix dma APIs __dma_page_cpu_to_dev is a private ARM api that is not available on 3.10 and was never available on other architectures. We can get the same behavior by calling dma_sync_sg_for_device with a scatterlist containing a single page. It's still not quite a kosher use of the dma apis, we still conflate physical addresses with bus addresses, but it should at least compile on all platforms, and work on any platform that doesn't have a physical to bus address translation. Change-Id: I8451c2dae4bf85841015c016640684ac28430a5a Signed-off-by: Colin Cross --- drivers/staging/android/ion/ion.c | 20 ++++++++++++++++++- drivers/staging/android/ion/ion_chunk_heap.c | 15 +++++++------- drivers/staging/android/ion/ion_page_pool.c | 9 ++------- drivers/staging/android/ion/ion_priv.h | 12 +++++++++++ drivers/staging/android/ion/ion_system_heap.c | 5 ++--- 5 files changed, 42 insertions(+), 19 deletions(-) diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index a8d4735b462c..38e3d6ff3a3e 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -840,6 +840,22 @@ static void ion_unmap_dma_buf(struct dma_buf_attachment *attachment, { } +void ion_pages_sync_for_device(struct device *dev, struct page *page, + size_t size, enum dma_data_direction dir) +{ + struct scatterlist sg; + + sg_init_table(&sg, 1); + sg_set_page(&sg, page, size, 0); + /* + * This is not correct - sg_dma_address needs a dma_addr_t that is valid + * for the the targeted device, but this works on the currently targeted + * hardware. + */ + sg_dma_address(&sg) = page_to_phys(page); + dma_sync_sg_for_device(dev, &sg, 1, dir); +} + struct ion_vma_list { struct list_head list; struct vm_area_struct *vma; @@ -864,7 +880,9 @@ static void ion_buffer_sync_for_device(struct ion_buffer *buffer, struct page *page = buffer->pages[i]; if (ion_buffer_page_is_dirty(page)) - __dma_page_cpu_to_dev(page, 0, PAGE_SIZE, dir); + ion_pages_sync_for_device(dev, ion_buffer_page(page), + PAGE_SIZE, dir); + ion_buffer_page_clean(buffer->pages + i); } list_for_each_entry(vma_list, &buffer->vmas, list) { diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c index a2b2e1b7af38..c16350e9ffcc 100644 --- a/drivers/staging/android/ion/ion_chunk_heap.c +++ b/drivers/staging/android/ion/ion_chunk_heap.c @@ -106,11 +106,11 @@ static void ion_chunk_heap_free(struct ion_buffer *buffer) ion_heap_buffer_zero(buffer); + if (ion_buffer_cached(buffer)) + dma_sync_sg_for_device(NULL, table->sgl, table->nents, + DMA_BIDIRECTIONAL); + for_each_sg(table->sgl, sg, table->nents, i) { - if (ion_buffer_cached(buffer)) - arm_dma_ops.sync_single_for_device(NULL, - pfn_to_dma(NULL, page_to_pfn(sg_page(sg))), - sg_dma_len(sg), DMA_BIDIRECTIONAL); gen_pool_free(chunk_heap->pool, page_to_phys(sg_page(sg)), sg_dma_len(sg)); } @@ -148,7 +148,6 @@ struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data) pgprot_t pgprot = pgprot_writecombine(PAGE_KERNEL); int i, ret; - chunk_heap = kzalloc(sizeof(struct ion_chunk_heap), GFP_KERNEL); if (!chunk_heap) return ERR_PTR(-ENOMEM); @@ -181,9 +180,9 @@ struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data) } free_vm_area(vm_struct); - arm_dma_ops.sync_single_for_device(NULL, - pfn_to_dma(NULL, page_to_pfn(phys_to_page(heap_data->base))), - heap_data->size, DMA_BIDIRECTIONAL); + ion_pages_sync_for_device(NULL, pfn_to_page(PFN_DOWN(heap_data->base)), + heap_data->size, DMA_BIDIRECTIONAL); + gen_pool_add(chunk_heap->pool, chunk_heap->base, heap_data->size, -1); chunk_heap->heap.ops = &chunk_heap_ops; chunk_heap->heap.type = ION_HEAP_TYPE_CHUNK; diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/ion_page_pool.c index 7e00f51292e1..b052ff6bf383 100644 --- a/drivers/staging/android/ion/ion_page_pool.c +++ b/drivers/staging/android/ion/ion_page_pool.c @@ -34,13 +34,8 @@ static void *ion_page_pool_alloc_pages(struct ion_page_pool *pool) if (!page) return NULL; - /* this is only being used to flush the page for dma, - this api is not really suitable for calling from a driver - but no better way to flush a page for dma exist at this time */ - arm_dma_ops.sync_single_for_device(NULL, - pfn_to_dma(NULL, page_to_pfn(page)), - PAGE_SIZE << pool->order, - DMA_BIDIRECTIONAL); + ion_pages_sync_for_device(NULL, page, PAGE_SIZE << pool->order, + DMA_BIDIRECTIONAL); return page; } diff --git a/drivers/staging/android/ion/ion_priv.h b/drivers/staging/android/ion/ion_priv.h index 0ccf409cde7d..ea87b54987e7 100644 --- a/drivers/staging/android/ion/ion_priv.h +++ b/drivers/staging/android/ion/ion_priv.h @@ -17,6 +17,7 @@ #ifndef _ION_PRIV_H #define _ION_PRIV_H +#include #include #include #include @@ -357,4 +358,15 @@ void ion_page_pool_free(struct ion_page_pool *, struct page *); int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask, int nr_to_scan); +/** + * ion_pages_sync_for_device - cache flush pages for use with the specified + * device + * @dev: the device the pages will be used with + * @page: the first page to be flushed + * @size: size in bytes of region to be flushed + * @dir: direction of dma transfer + */ +void ion_pages_sync_for_device(struct device *dev, struct page *page, + size_t size, enum dma_data_direction dir); + #endif /* _ION_PRIV_H */ diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index 06e0702396a4..90b2e04157ca 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -77,9 +77,8 @@ static struct page *alloc_buffer_page(struct ion_system_heap *heap, page = ion_heap_alloc_pages(buffer, gfp_flags, order); if (!page) return 0; - arm_dma_ops.sync_single_for_device(NULL, - pfn_to_dma(NULL, page_to_pfn(page)), - PAGE_SIZE << order, DMA_BIDIRECTIONAL); + ion_pages_sync_for_device(NULL, page, PAGE_SIZE << order, + DMA_BIDIRECTIONAL); } if (!page) return 0; From c1d3cea1d0b985a78a87675a07c2dab865a416f1 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 12 Nov 2013 15:28:08 -0800 Subject: [PATCH 20/54] ion: convert sg_dma_len(sg) to sg->length ion is always dealing with the allocation and not the mapping, so it should always be using sg->length and not sg->dma_length. Change-Id: Id9b07f1196b2bafe04636fa1aa46dfc84d003cf0 Signed-off-by: Colin Cross --- drivers/staging/android/ion/ion.c | 2 +- drivers/staging/android/ion/ion_chunk_heap.c | 4 ++-- drivers/staging/android/ion/ion_heap.c | 12 ++++++------ drivers/staging/android/ion/ion_system_heap.c | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 38e3d6ff3a3e..4d19716cabd2 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -224,7 +224,7 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap, for_each_sg(table->sgl, sg, table->nents, i) { struct page *page = sg_page(sg); - for (j = 0; j < sg_dma_len(sg) / PAGE_SIZE; j++) + for (j = 0; j < sg->length / PAGE_SIZE; j++) buffer->pages[k++] = page++; } diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c index c16350e9ffcc..19e13ecaa1c1 100644 --- a/drivers/staging/android/ion/ion_chunk_heap.c +++ b/drivers/staging/android/ion/ion_chunk_heap.c @@ -84,7 +84,7 @@ static int ion_chunk_heap_allocate(struct ion_heap *heap, sg = table->sgl; for (i -= 1; i >= 0; i--) { gen_pool_free(chunk_heap->pool, page_to_phys(sg_page(sg)), - sg_dma_len(sg)); + sg->length); sg = sg_next(sg); } sg_free_table(table); @@ -112,7 +112,7 @@ static void ion_chunk_heap_free(struct ion_buffer *buffer) for_each_sg(table->sgl, sg, table->nents, i) { gen_pool_free(chunk_heap->pool, page_to_phys(sg_page(sg)), - sg_dma_len(sg)); + sg->length); } chunk_heap->allocated -= allocated_size; sg_free_table(table); diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c index 9be246f50a01..f32f4e69765a 100644 --- a/drivers/staging/android/ion/ion_heap.c +++ b/drivers/staging/android/ion/ion_heap.c @@ -46,7 +46,7 @@ void *ion_heap_map_kernel(struct ion_heap *heap, pgprot = pgprot_writecombine(PAGE_KERNEL); for_each_sg(table->sgl, sg, table->nents, i) { - int npages_this_entry = PAGE_ALIGN(sg_dma_len(sg)) / PAGE_SIZE; + int npages_this_entry = PAGE_ALIGN(sg->length) / PAGE_SIZE; struct page *page = sg_page(sg); BUG_ON(i >= npages); for (j = 0; j < npages_this_entry; j++) { @@ -80,14 +80,14 @@ int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, for_each_sg(table->sgl, sg, table->nents, i) { struct page *page = sg_page(sg); unsigned long remainder = vma->vm_end - addr; - unsigned long len = sg_dma_len(sg); + unsigned long len = sg->length; - if (offset >= sg_dma_len(sg)) { - offset -= sg_dma_len(sg); + if (offset >= sg->length) { + offset -= sg->length; continue; } else if (offset) { page += offset / PAGE_SIZE; - len = sg_dma_len(sg) - offset; + len = sg->length - offset; offset = 0; } len = min(len, remainder); @@ -119,7 +119,7 @@ int ion_heap_buffer_zero(struct ion_buffer *buffer) for_each_sg(table->sgl, sg, table->nents, i) { struct page *page = sg_page(sg); - unsigned long len = sg_dma_len(sg); + unsigned long len = sg->length; for (j = 0; j < len / PAGE_SIZE; j++) { struct page *sub_page = page + j; diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index 90b2e04157ca..ecae16f2109a 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -209,7 +209,7 @@ void ion_system_heap_free(struct ion_buffer *buffer) for_each_sg(table->sgl, sg, table->nents, i) free_buffer_page(sys_heap, buffer, sg_page(sg), - get_order(sg_dma_len(sg))); + get_order(sg->length)); sg_free_table(table); kfree(table); } From 47128ea67fb2978b432c488bd1babb3e4eb16805 Mon Sep 17 00:00:00 2001 From: Greg Hackmann Date: Thu, 7 Nov 2013 10:12:00 -0800 Subject: [PATCH 21/54] video: adf: make device node names less hierarchical adf/foobar/device -> adf0 adf/foobar/interface1 -> adf-interface0.1 adf/foobar/overlay-engine1 -> adf-overlay-engine0.1 Change-Id: I7af7f84ce3f101ecb02f448070c200ff3e03f2ec Signed-off-by: Greg Hackmann --- drivers/video/adf/adf.c | 28 +++++++++++++--------------- drivers/video/adf/adf_sysfs.c | 16 +++++----------- 2 files changed, 18 insertions(+), 26 deletions(-) diff --git a/drivers/video/adf/adf.c b/drivers/video/adf/adf.c index fd5bcde87850..933e74ac8098 100644 --- a/drivers/video/adf/adf.c +++ b/drivers/video/adf/adf.c @@ -37,6 +37,8 @@ #define ADF_SHORT_FENCE_TIMEOUT (1 * MSEC_PER_SEC) #define ADF_LONG_FENCE_TIMEOUT (10 * MSEC_PER_SEC) +static DEFINE_IDR(adf_devices); + static void adf_fence_wait(struct adf_device *dev, struct sync_fence *fence) { /* sync_fence_wait() dumps debug information on timeout. Experience @@ -455,23 +457,20 @@ static int adf_obj_init(struct adf_obj *obj, enum adf_obj_type type, struct idr *idr, struct adf_device *parent, const struct adf_obj_ops *ops, const char *fmt, va_list args) { + int ret; + if (ops && ops->supports_event && !ops->set_event) { pr_err("%s: %s implements supports_event but not set_event\n", __func__, adf_obj_type_str(type)); return -EINVAL; } - if (idr) { - int ret = idr_alloc(idr, obj, 0, 0, GFP_KERNEL); - if (ret < 0) { - pr_err("%s: allocating object id failed: %d\n", - __func__, ret); - return ret; - } - obj->id = ret; - } else { - obj->id = -1; + ret = idr_alloc(idr, obj, 0, 0, GFP_KERNEL); + if (ret < 0) { + pr_err("%s: allocating object id failed: %d\n", __func__, ret); + return ret; } + obj->id = ret; vscnprintf(obj->name, sizeof(obj->name), fmt, args); @@ -498,8 +497,7 @@ static void adf_obj_destroy(struct adf_obj *obj, struct idr *idr) } mutex_destroy(&obj->event_lock); - if (idr) - idr_remove(idr, obj->id); + idr_remove(idr, obj->id); } /** @@ -543,8 +541,8 @@ int adf_device_init(struct adf_device *dev, struct device *parent, memset(dev, 0, sizeof(*dev)); va_start(args, fmt); - ret = adf_obj_init(&dev->base, ADF_OBJ_DEVICE, NULL, dev, &ops->base, - fmt, args); + ret = adf_obj_init(&dev->base, ADF_OBJ_DEVICE, &adf_devices, dev, + &ops->base, fmt, args); va_end(args); if (ret < 0) return ret; @@ -612,7 +610,7 @@ void adf_device_destroy(struct adf_device *dev) } mutex_destroy(&dev->post_lock); mutex_destroy(&dev->client_lock); - adf_obj_destroy(&dev->base, NULL); + adf_obj_destroy(&dev->base, &adf_devices); } EXPORT_SYMBOL(adf_device_destroy); diff --git a/drivers/video/adf/adf_sysfs.c b/drivers/video/adf/adf_sysfs.c index 076ccbd0cd88..8c659c71ffa8 100644 --- a/drivers/video/adf/adf_sysfs.c +++ b/drivers/video/adf/adf_sysfs.c @@ -105,11 +105,6 @@ static struct device_attribute adf_interface_attrs[] = { __ATTR_RO(vsync_timestamp), }; -static char *adf_devnode(struct device *dev, umode_t *mode) -{ - return kasprintf(GFP_KERNEL, "adf/%s", dev_name(dev)); -} - int adf_obj_sysfs_init(struct adf_obj *obj, struct device *parent) { int ret = idr_alloc(&adf_minors, obj, 0, 0, GFP_KERNEL); @@ -142,7 +137,7 @@ static char *adf_device_devnode(struct device *dev, umode_t *mode, kuid_t *uid, kgid_t *gid) { struct adf_obj *obj = container_of(dev, struct adf_obj, dev); - return kasprintf(GFP_KERNEL, "adf/%s/device", obj->name); + return kasprintf(GFP_KERNEL, "adf%d", obj->id); } static char *adf_interface_devnode(struct device *dev, umode_t *mode, @@ -151,8 +146,8 @@ static char *adf_interface_devnode(struct device *dev, umode_t *mode, struct adf_obj *obj = container_of(dev, struct adf_obj, dev); struct adf_interface *intf = adf_obj_to_interface(obj); struct adf_device *parent = adf_interface_parent(intf); - return kasprintf(GFP_KERNEL, "adf/%s/interface%d", - parent->base.name, intf->base.id); + return kasprintf(GFP_KERNEL, "adf-interface%d.%d", + parent->base.id, intf->base.id); } static char *adf_overlay_engine_devnode(struct device *dev, umode_t *mode, @@ -161,8 +156,8 @@ static char *adf_overlay_engine_devnode(struct device *dev, umode_t *mode, struct adf_obj *obj = container_of(dev, struct adf_obj, dev); struct adf_overlay_engine *eng = adf_obj_to_overlay_engine(obj); struct adf_device *parent = adf_overlay_engine_parent(eng); - return kasprintf(GFP_KERNEL, "adf/%s/overlay-engine%d", - parent->base.name, eng->base.id); + return kasprintf(GFP_KERNEL, "adf-overlay-engine%d.%d", + parent->base.id, eng->base.id); } static void adf_noop_release(struct device *dev) @@ -285,7 +280,6 @@ int adf_sysfs_init(void) goto err_chrdev; } - class->devnode = adf_devnode; adf_class = class; adf_major = ret; return 0; From b95f5c534f2ca5c2dfd341732afadce10b306ecd Mon Sep 17 00:00:00 2001 From: Greg Hackmann Date: Wed, 20 Nov 2013 14:02:09 -0800 Subject: [PATCH 22/54] video: adf: remove PAGE_SIZE from userspace-facing header Systems may define PAGE_SIZE in userspace limits.h but don't have to. PAGE_SIZE was picked as an arbitrary "reasonable" limit so just use 4096 instead. Change-Id: I9555e39aba64a3a70f61eb6ded2a4129ab236ce0 Signed-off-by: Greg Hackmann --- include/uapi/video/adf.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/uapi/video/adf.h b/include/uapi/video/adf.h index 2ba345ca458b..73cb936e0da9 100644 --- a/include/uapi/video/adf.h +++ b/include/uapi/video/adf.h @@ -22,7 +22,7 @@ #include #define ADF_NAME_LEN 32 -#define ADF_MAX_CUSTOM_DATA_SIZE PAGE_SIZE +#define ADF_MAX_CUSTOM_DATA_SIZE 4096 enum adf_interface_type { ADF_INTF_DSI = 0, @@ -126,7 +126,7 @@ struct adf_buffer_config { __s64 acquire_fence; }; -#define ADF_MAX_BUFFERS (PAGE_SIZE / sizeof(struct adf_buffer_config)) +#define ADF_MAX_BUFFERS (4096 / sizeof(struct adf_buffer_config)) /** * struct adf_post_config - request to flip to a new set of buffers @@ -152,7 +152,7 @@ struct adf_post_config { __s64 complete_fence; }; -#define ADF_MAX_INTERFACES (PAGE_SIZE / sizeof(__u32)) +#define ADF_MAX_INTERFACES (4096 / sizeof(__u32)) /** * struct adf_simple_buffer_allocate - request to allocate a "simple" buffer @@ -233,7 +233,7 @@ struct adf_device_data { size_t custom_data_size; void __user *custom_data; }; -#define ADF_MAX_ATTACHMENTS (PAGE_SIZE / sizeof(struct adf_attachment)) +#define ADF_MAX_ATTACHMENTS (4096 / sizeof(struct adf_attachment)) /** * struct adf_device_data - describes a display interface @@ -273,7 +273,7 @@ struct adf_interface_data { size_t custom_data_size; void __user *custom_data; }; -#define ADF_MAX_MODES (PAGE_SIZE / sizeof(struct drm_mode_modeinfo)) +#define ADF_MAX_MODES (4096 / sizeof(struct drm_mode_modeinfo)) /** * struct adf_overlay_engine_data - describes an overlay engine @@ -293,7 +293,7 @@ struct adf_overlay_engine_data { size_t custom_data_size; void __user *custom_data; }; -#define ADF_MAX_SUPPORTED_FORMATS (PAGE_SIZE / sizeof(__u32)) +#define ADF_MAX_SUPPORTED_FORMATS (4096 / sizeof(__u32)) #define ADF_SET_EVENT _IOW('D', 0, struct adf_set_event) #define ADF_BLANK _IOW('D', 1, __u8) From ccf0b45b743f5075143beccf8beca8fd9e988ef1 Mon Sep 17 00:00:00 2001 From: Greg Hackmann Date: Mon, 11 Nov 2013 14:31:12 -0800 Subject: [PATCH 23/54] video: adf: fix ADF_MAX_ATTACHMENTS declaration Userspace-facing ADF_MAX_ATTACHMENTS must be in terms of userspace-facing struct adf_attachment_config Change-Id: Iaaddcd6366f13b3e52eb3911efcfff8a61e0b225 Signed-off-by: Greg Hackmann --- include/uapi/video/adf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/uapi/video/adf.h b/include/uapi/video/adf.h index 73cb936e0da9..38458f6428b5 100644 --- a/include/uapi/video/adf.h +++ b/include/uapi/video/adf.h @@ -233,7 +233,7 @@ struct adf_device_data { size_t custom_data_size; void __user *custom_data; }; -#define ADF_MAX_ATTACHMENTS (4096 / sizeof(struct adf_attachment)) +#define ADF_MAX_ATTACHMENTS (4096 / sizeof(struct adf_attachment_config)) /** * struct adf_device_data - describes a display interface From 55fefddeea4afb286f1c6fafa3a05ce4dea541a1 Mon Sep 17 00:00:00 2001 From: Greg Hackmann Date: Wed, 20 Nov 2013 12:10:35 -0800 Subject: [PATCH 24/54] video: adf: validate dpms state passed to blank Change-Id: I3a4228d50fc4a2553b3e92e5675a94cbc6e71b8a Signed-off-by: Greg Hackmann --- drivers/video/adf/adf_client.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/video/adf/adf_client.c b/drivers/video/adf/adf_client.c index e4a792135072..bba873d34bbb 100644 --- a/drivers/video/adf/adf_client.c +++ b/drivers/video/adf/adf_client.c @@ -49,6 +49,9 @@ int adf_interface_blank(struct adf_interface *intf, u8 state) if (!intf->ops || !intf->ops->blank) return -EOPNOTSUPP; + if (state > DRM_MODE_DPMS_OFF) + return -EINVAL; + mutex_lock(&dev->client_lock); if (state != DRM_MODE_DPMS_ON) flush_kthread_worker(&dev->post_worker); From f2ec29aa62924e6b1ce5edb3bfc7dcd206023740 Mon Sep 17 00:00:00 2001 From: Greg Hackmann Date: Fri, 22 Nov 2013 13:50:24 -0800 Subject: [PATCH 25/54] video: adf: fix fbdev blank -> dpms state mapping Change-Id: I96132a1b7275d389a6d0ba8899c6be838b63c422 Signed-off-by: Greg Hackmann --- drivers/video/adf/adf_fbdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/adf/adf_fbdev.c b/drivers/video/adf/adf_fbdev.c index 477abd63ccc2..cac34d14cbc2 100644 --- a/drivers/video/adf/adf_fbdev.c +++ b/drivers/video/adf/adf_fbdev.c @@ -519,10 +519,10 @@ int adf_fbdev_blank(int blank, struct fb_info *info) dpms_state = DRM_MODE_DPMS_STANDBY; break; case FB_BLANK_VSYNC_SUSPEND: - dpms_state = DRM_MODE_DPMS_STANDBY; + dpms_state = DRM_MODE_DPMS_SUSPEND; break; case FB_BLANK_HSYNC_SUSPEND: - dpms_state = DRM_MODE_DPMS_SUSPEND; + dpms_state = DRM_MODE_DPMS_STANDBY; break; case FB_BLANK_POWERDOWN: dpms_state = DRM_MODE_DPMS_OFF; From 2c06cb20454795a38876be5bd93dd6a8ddcc9d98 Mon Sep 17 00:00:00 2001 From: Greg Hackmann Date: Wed, 4 Dec 2013 17:39:27 -0800 Subject: [PATCH 26/54] netfilter: xt_qtaguid: fix memory leak in seq_file handlers Change-Id: I15b21230d52479d008a00d9e2191dda020f00925 Signed-off-by: Greg Hackmann --- net/netfilter/xt_qtaguid.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c index e476b88f9d68..4a16829969a6 100644 --- a/net/netfilter/xt_qtaguid.c +++ b/net/netfilter/xt_qtaguid.c @@ -1496,7 +1496,7 @@ static const struct file_operations proc_iface_stat_fmt_fops = { .open = proc_iface_stat_fmt_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = seq_release_private, }; static int __init iface_stat_init(struct proc_dir_entry *parent_procdir) @@ -2904,7 +2904,7 @@ static const struct file_operations proc_qtaguid_ctrl_fops = { .read = seq_read, .write = qtaguid_ctrl_proc_write, .llseek = seq_lseek, - .release = seq_release, + .release = seq_release_private, }; static const struct seq_operations proc_qtaguid_stats_seqops = { From da3b36172d546200a851f165bf574d6090f4ff4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= Date: Mon, 24 Jun 2013 18:02:05 -0700 Subject: [PATCH 27/54] ARM: fiq_glue: Add custom fiq return handler api. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I5ff2764e85151ca0a88576542fda07c2d33dd065 Signed-off-by: Arve Hjønnevåg --- arch/arm/common/fiq_glue.S | 25 +++++++++------ arch/arm/common/fiq_glue_setup.c | 53 ++++++++++++++++++++++++++++++-- arch/arm/include/asm/fiq_glue.h | 3 ++ 3 files changed, 69 insertions(+), 12 deletions(-) diff --git a/arch/arm/common/fiq_glue.S b/arch/arm/common/fiq_glue.S index 9e3455a09f8f..24b42cec4813 100644 --- a/arch/arm/common/fiq_glue.S +++ b/arch/arm/common/fiq_glue.S @@ -22,13 +22,14 @@ /* fiq stack: r0-r15,cpsr,spsr of interrupted mode */ ENTRY(fiq_glue) - /* store pc, cpsr from previous mode */ + /* store pc, cpsr from previous mode, reserve space for spsr */ mrs r12, spsr - sub r11, lr, #4 + sub lr, lr, #4 subs r10, #1 bne nested_fiq - stmfd sp!, {r11-r12, lr} + str r12, [sp, #-8]! + str lr, [sp, #-4]! /* store r8-r14 from previous mode */ sub sp, sp, #(7 * 4) @@ -85,12 +86,15 @@ fiq_from_usr_mode_exit: msr cpsr_c, #(FIQ_MODE | PSR_I_BIT | PSR_F_BIT) ldmfd sp!, {r0-r7} - add sp, sp, #(7 * 4) - ldmfd sp!, {r11-r12, lr} + ldr lr, [sp, #(4 * 7)] + ldr r12, [sp, #(4 * 8)] + add sp, sp, #(10 * 4) exit_fiq: msr spsr_cxsf, r12 add r10, #1 - movs pc, r11 + cmp r11, #0 + moveqs pc, lr + bx r11 /* jump to custom fiq return function */ nested_fiq: orr r12, r12, #(PSR_F_BIT) @@ -98,14 +102,17 @@ nested_fiq: fiq_glue_end: -ENTRY(fiq_glue_setup) /* func, data, sp */ - mrs r3, cpsr +ENTRY(fiq_glue_setup) /* func, data, sp, smc call number */ + stmfd sp!, {r4} + mrs r4, cpsr msr cpsr_c, #(FIQ_MODE | PSR_I_BIT | PSR_F_BIT) movs r8, r0 mov r9, r1 mov sp, r2 + mov r11, r3 moveq r10, #0 movne r10, #1 - msr cpsr_c, r3 + msr cpsr_c, r4 + ldmfd sp!, {r4} bx lr diff --git a/arch/arm/common/fiq_glue_setup.c b/arch/arm/common/fiq_glue_setup.c index 4044c7db95c8..8cb1b611c6d5 100644 --- a/arch/arm/common/fiq_glue_setup.c +++ b/arch/arm/common/fiq_glue_setup.c @@ -18,20 +18,23 @@ #include extern unsigned char fiq_glue, fiq_glue_end; -extern void fiq_glue_setup(void *func, void *data, void *sp); +extern void fiq_glue_setup(void *func, void *data, void *sp, + fiq_return_handler_t fiq_return_handler); static struct fiq_handler fiq_debbuger_fiq_handler = { .name = "fiq_glue", }; DEFINE_PER_CPU(void *, fiq_stack); static struct fiq_glue_handler *current_handler; +static fiq_return_handler_t fiq_return_handler; static DEFINE_MUTEX(fiq_glue_lock); static void fiq_glue_setup_helper(void *info) { struct fiq_glue_handler *handler = info; fiq_glue_setup(handler->fiq, handler, - __get_cpu_var(fiq_stack) + THREAD_START_SP); + __get_cpu_var(fiq_stack) + THREAD_START_SP, + fiq_return_handler); } int fiq_glue_register_handler(struct fiq_glue_handler *handler) @@ -80,6 +83,49 @@ int fiq_glue_register_handler(struct fiq_glue_handler *handler) return ret; } +static void fiq_glue_update_return_handler(void (*fiq_return)(void)) +{ + fiq_return_handler = fiq_return; + if (current_handler) + on_each_cpu(fiq_glue_setup_helper, current_handler, true); +} + +int fiq_glue_set_return_handler(void (*fiq_return)(void)) +{ + int ret; + + mutex_lock(&fiq_glue_lock); + if (fiq_return_handler) { + ret = -EBUSY; + goto err_busy; + } + fiq_glue_update_return_handler(fiq_return); + ret = 0; +err_busy: + mutex_unlock(&fiq_glue_lock); + + return ret; +} +EXPORT_SYMBOL(fiq_glue_set_return_handler); + +int fiq_glue_clear_return_handler(void (*fiq_return)(void)) +{ + int ret; + + mutex_lock(&fiq_glue_lock); + if (WARN_ON(fiq_return_handler != fiq_return)) { + ret = -EINVAL; + goto err_inval; + } + fiq_glue_update_return_handler(NULL); + ret = 0; +err_inval: + mutex_unlock(&fiq_glue_lock); + + return ret; +} +EXPORT_SYMBOL(fiq_glue_clear_return_handler); + /** * fiq_glue_resume - Restore fiqs after suspend or low power idle states * @@ -93,7 +139,8 @@ void fiq_glue_resume(void) if (!current_handler) return; fiq_glue_setup(current_handler->fiq, current_handler, - __get_cpu_var(fiq_stack) + THREAD_START_SP); + __get_cpu_var(fiq_stack) + THREAD_START_SP, + fiq_return_handler); if (current_handler->resume) current_handler->resume(current_handler); } diff --git a/arch/arm/include/asm/fiq_glue.h b/arch/arm/include/asm/fiq_glue.h index d54c29db97a8..a9e244f9f197 100644 --- a/arch/arm/include/asm/fiq_glue.h +++ b/arch/arm/include/asm/fiq_glue.h @@ -18,8 +18,11 @@ struct fiq_glue_handler { void (*fiq)(struct fiq_glue_handler *h, void *regs, void *svc_sp); void (*resume)(struct fiq_glue_handler *h); }; +typedef void (*fiq_return_handler_t)(void); int fiq_glue_register_handler(struct fiq_glue_handler *handler); +int fiq_glue_set_return_handler(fiq_return_handler_t fiq_return); +int fiq_glue_clear_return_handler(fiq_return_handler_t fiq_return); #ifdef CONFIG_FIQ_GLUE void fiq_glue_resume(void); From e8f7f42cdcbe3ae4c4bf719847369ddac44219a9 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 13 Nov 2013 14:46:06 -0800 Subject: [PATCH 28/54] ion: check invalid values in ion_system_heap ion_system_heap can only satisfy page alignment, and ion_system_contig_heap can only satisify alignment to the allocation size. Neither can support faulting user mappings because they use slab pages. Change-Id: I895c2d4184c672f647f83a17aeb862985dc92f2c Signed-off-by: Colin Cross --- drivers/staging/android/ion/ion_system_heap.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index ecae16f2109a..4eb0ae8c6756 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -150,6 +150,12 @@ static int ion_system_heap_allocate(struct ion_heap *heap, long size_remaining = PAGE_ALIGN(size); unsigned int max_order = orders[0]; + if (align > PAGE_SIZE) + return -EINVAL; + + if (ion_buffer_fault_user_mappings(buffer)) + return -EINVAL; + INIT_LIST_HEAD(&pages); while (size_remaining > 0) { info = alloc_largest_available(sys_heap, buffer, size_remaining, max_order); @@ -362,6 +368,14 @@ static int ion_system_contig_heap_allocate(struct ion_heap *heap, unsigned long align, unsigned long flags) { + int order = get_order(len); + + if (align > (PAGE_SIZE << order)) + return -EINVAL; + + if (ion_buffer_fault_user_mappings(buffer)) + return -EINVAL; + buffer->priv_virt = kzalloc(len, GFP_KERNEL); if (!buffer->priv_virt) return -ENOMEM; From 5c31b87cef4e03eea5b417a6e3f7c9b781aacf96 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 8 Nov 2013 16:32:47 -0800 Subject: [PATCH 29/54] ion: add test device for unit tests to interact with dma_bufs Add a /dev/ion-test device that will be created if CONFIG_ION_TEST is set. The device accepts a dma_buf fd and allows reading and writing to the backing memory using DMA-like apis or kernel mapping apis. Can be used to test the dma_buf mapping ops, including the ion implementations, from userspace. Change-Id: I30703ba69cd75bdfe7767ac642e5f0cacd8d0478 Signed-off-by: Colin Cross --- drivers/staging/android/ion/Kconfig | 7 + drivers/staging/android/ion/Makefile | 1 + drivers/staging/android/ion/ion_test.c | 281 ++++++++++++++++++++++++ drivers/staging/android/uapi/ion_test.h | 71 ++++++ 4 files changed, 360 insertions(+) create mode 100644 drivers/staging/android/ion/ion_test.c create mode 100644 drivers/staging/android/uapi/ion_test.h diff --git a/drivers/staging/android/ion/Kconfig b/drivers/staging/android/ion/Kconfig index c62f2cbb9e89..6a5d8cfe7935 100644 --- a/drivers/staging/android/ion/Kconfig +++ b/drivers/staging/android/ion/Kconfig @@ -6,6 +6,13 @@ menuconfig ION help Chose this option to enable the ION Memory Manager. +config ION_TEST + tristate "Ion Test Device" + depends on ION + help + Choose this option to create a device that can be used to test the + kernel and device side ION functions. + config ION_TEGRA tristate "Ion for Tegra" depends on ARCH_TEGRA && ION diff --git a/drivers/staging/android/ion/Makefile b/drivers/staging/android/ion/Makefile index 9c956659124b..75039b98eebb 100644 --- a/drivers/staging/android/ion/Makefile +++ b/drivers/staging/android/ion/Makefile @@ -1,5 +1,6 @@ obj-$(CONFIG_ION) += ion.o ion_heap.o ion_page_pool.o ion_system_heap.o \ ion_carveout_heap.o ion_chunk_heap.o ion_cma_heap.o +obj-$(CONFIG_ION_TEST) += ion_test.o ifdef CONFIG_COMPAT obj-$(CONFIG_ION) += compat_ion.o endif diff --git a/drivers/staging/android/ion/ion_test.c b/drivers/staging/android/ion/ion_test.c new file mode 100644 index 000000000000..3e20349baf7c --- /dev/null +++ b/drivers/staging/android/ion/ion_test.c @@ -0,0 +1,281 @@ +/* + * + * Copyright (C) 2013 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#define pr_fmt(fmt) "ion-test: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ion.h" +#include "../uapi/ion_test.h" + +#define u64_to_uptr(x) ((void __user *)(unsigned long)(x)) + +struct ion_test_device { + struct miscdevice misc; +}; + +struct ion_test_data { + struct dma_buf *dma_buf; + struct device *dev; +}; + +static int ion_handle_test_dma(struct device *dev, struct dma_buf *dma_buf, + void __user *ptr, size_t offset, size_t size, bool write) +{ + int ret = 0; + struct dma_buf_attachment *attach; + struct sg_table *table; + pgprot_t pgprot = pgprot_writecombine(PAGE_KERNEL); + enum dma_data_direction dir = write ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + struct sg_page_iter sg_iter; + unsigned long offset_page; + + attach = dma_buf_attach(dma_buf, dev); + if (IS_ERR(attach)) + return PTR_ERR(attach); + + table = dma_buf_map_attachment(attach, dir); + if (IS_ERR(table)) + return PTR_ERR(table); + + offset_page = offset >> PAGE_SHIFT; + offset %= PAGE_SIZE; + + for_each_sg_page(table->sgl, &sg_iter, table->nents, offset_page) { + struct page *page = sg_page_iter_page(&sg_iter); + void *vaddr = vmap(&page, 1, VM_MAP, pgprot); + size_t to_copy = PAGE_SIZE - offset; + + to_copy = min(to_copy, size); + if (!vaddr) { + ret = -ENOMEM; + goto err; + } + + if (write) + ret = copy_from_user(vaddr + offset, ptr, to_copy); + else + ret = copy_to_user(ptr, vaddr + offset, to_copy); + + vunmap(vaddr); + if (ret) { + ret = -EFAULT; + goto err; + } + size -= to_copy; + if (!size) + break; + ptr += to_copy; + offset = 0; + } + +err: + dma_buf_unmap_attachment(attach, table, dir); + dma_buf_detach(dma_buf, attach); + return ret; +} + +static int ion_handle_test_kernel(struct dma_buf *dma_buf, void __user *ptr, + size_t offset, size_t size, bool write) +{ + int ret; + unsigned long page_offset = offset >> PAGE_SHIFT; + size_t copy_offset = offset % PAGE_SIZE; + size_t copy_size = size; + enum dma_data_direction dir = write ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + + if (offset > dma_buf->size || size > dma_buf->size - offset) + return -EINVAL; + + ret = dma_buf_begin_cpu_access(dma_buf, offset, size, dir); + if (ret) + return ret; + + while (copy_size > 0) { + size_t to_copy; + void *vaddr = dma_buf_kmap(dma_buf, page_offset); + + if (!vaddr) + goto err; + + to_copy = min_t(size_t, PAGE_SIZE - copy_offset, copy_size); + + if (write) + ret = copy_from_user(vaddr + copy_offset, ptr, to_copy); + else + ret = copy_to_user(ptr, vaddr + copy_offset, to_copy); + + dma_buf_kunmap(dma_buf, page_offset, vaddr); + if (ret) { + ret = -EFAULT; + goto err; + } + + copy_size -= to_copy; + ptr += to_copy; + page_offset++; + copy_offset = 0; + } +err: + dma_buf_end_cpu_access(dma_buf, offset, size, dir); + return ret; +} + +static long ion_test_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + struct ion_test_data *test_data = filp->private_data; + int ret = 0; + + union { + struct ion_test_rw_data test_rw; + } data; + + if (_IOC_SIZE(cmd) > sizeof(data)) + return -EINVAL; + + if (_IOC_DIR(cmd) & _IOC_WRITE) + if (copy_from_user(&data, (void __user *)arg, _IOC_SIZE(cmd))) + return -EFAULT; + + switch (cmd) { + case ION_IOC_TEST_SET_FD: + { + struct dma_buf *dma_buf = NULL; + int fd = arg; + + if (fd >= 0) { + dma_buf = dma_buf_get((int)arg); + if (IS_ERR(dma_buf)) + return PTR_ERR(dma_buf); + } + if (test_data->dma_buf) + dma_buf_put(test_data->dma_buf); + test_data->dma_buf = dma_buf; + break; + } + case ION_IOC_TEST_DMA_MAPPING: + { + ret = ion_handle_test_dma(test_data->dev, test_data->dma_buf, + u64_to_uptr(data.test_rw.ptr), + data.test_rw.offset, data.test_rw.size, + data.test_rw.write); + break; + } + case ION_IOC_TEST_KERNEL_MAPPING: + { + ret = ion_handle_test_kernel(test_data->dma_buf, + u64_to_uptr(data.test_rw.ptr), + data.test_rw.offset, data.test_rw.size, + data.test_rw.write); + break; + } + default: + return -ENOTTY; + } + + if (_IOC_DIR(cmd) & _IOC_READ) { + if (copy_to_user((void __user *)arg, &data, sizeof(data))) + return -EFAULT; + } + return ret; +} + +static int ion_test_open(struct inode *inode, struct file *file) +{ + struct ion_test_data *data; + struct miscdevice *miscdev = file->private_data; + + data = kzalloc(sizeof(struct ion_test_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->dev = miscdev->parent; + + file->private_data = data; + + return 0; +} + +static int ion_test_release(struct inode *inode, struct file *file) +{ + struct ion_test_data *data = file->private_data; + + kfree(data); + + return 0; +} + +static const struct file_operations ion_test_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = ion_test_ioctl, + .open = ion_test_open, + .release = ion_test_release, +}; + +static int __init ion_test_probe(struct platform_device *pdev) +{ + int ret; + struct ion_test_device *testdev; + + testdev = devm_kzalloc(&pdev->dev, sizeof(struct ion_test_device), + GFP_KERNEL); + if (!testdev) + return -ENOMEM; + + testdev->misc.minor = MISC_DYNAMIC_MINOR; + testdev->misc.name = "ion-test"; + testdev->misc.fops = &ion_test_fops; + testdev->misc.parent = &pdev->dev; + ret = misc_register(&testdev->misc); + if (ret) { + pr_err("failed to register misc device.\n"); + return ret; + } + + platform_set_drvdata(pdev, testdev); + + return 0; +} + +static struct platform_driver ion_test_platform_driver = { + .driver = { + .name = "ion-test", + }, +}; + +static int __init ion_test_init(void) +{ + platform_device_register_simple("ion-test", -1, NULL, 0); + return platform_driver_probe(&ion_test_platform_driver, ion_test_probe); +} + +static void __exit ion_test_exit(void) +{ + platform_driver_unregister(&ion_test_platform_driver); +} + +module_init(ion_test_init); +module_exit(ion_test_exit); diff --git a/drivers/staging/android/uapi/ion_test.h b/drivers/staging/android/uapi/ion_test.h new file mode 100644 index 000000000000..352379a02690 --- /dev/null +++ b/drivers/staging/android/uapi/ion_test.h @@ -0,0 +1,71 @@ +/* + * drivers/staging/android/uapi/ion.h + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#ifndef _UAPI_LINUX_ION_TEST_H +#define _UAPI_LINUX_ION_TEST_H + +#include +#include + +typedef int ion_user_handle_t; + +/** + * struct ion_test_rw_data - metadata passed to the kernel to read handle + * @ptr: a pointer to an area at least as large as size + * @offset: offset into the ion buffer to start reading + * @size: size to read or write + * @write: 1 to write, 0 to read + */ +struct ion_test_rw_data { + __u64 ptr; + __u64 offset; + __u64 size; + int write; +}; + +#define ION_IOC_MAGIC 'I' + +/** + * DOC: ION_IOC_TEST_SET_DMA_BUF - attach a dma buf to the test driver + * + * Attaches a dma buf fd to the test driver. Passing a second fd or -1 will + * release the first fd. + */ +#define ION_IOC_TEST_SET_FD \ + _IO(ION_IOC_MAGIC, 0xf0) + +/** + * DOC: ION_IOC_TEST_DMA_MAPPING - read or write memory from a handle as DMA + * + * Reads or writes the memory from a handle using an uncached mapping. Can be + * used by unit tests to emulate a DMA engine as close as possible. Only + * expected to be used for debugging and testing, may not always be available. + */ +#define ION_IOC_TEST_DMA_MAPPING \ + _IOW(ION_IOC_MAGIC, 0xf1, struct ion_test_rw_data) + +/** + * DOC: ION_IOC_TEST_KERNEL_MAPPING - read or write memory from a handle + * + * Reads or writes the memory from a handle using a kernel mapping. Can be + * used by unit tests to test heap map_kernel functions. Only expected to be + * used for debugging and testing, may not always be available. + */ +#define ION_IOC_TEST_KERNEL_MAPPING \ + _IOW(ION_IOC_MAGIC, 0xf2, struct ion_test_rw_data) + + +#endif /* _UAPI_LINUX_ION_H */ From acd77fc7d05a80e7ae39e64e1a3948487e2255ff Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 19 Sep 2013 14:54:56 -0500 Subject: [PATCH 30/54] ion: update idr to avoid deprecated apis Use idr_alloc instead if idr_pre_get/idr_get_new_above, and remove idr_remove_all. Change-Id: I675b789879549bd3767ed3ef2016cf108eb622d2 Signed-off-by: Colin Cross --- drivers/staging/android/ion/ion.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 4d19716cabd2..80c79455c36e 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -432,22 +432,16 @@ static bool ion_handle_validate(struct ion_client *client, struct ion_handle *ha static int ion_handle_add(struct ion_client *client, struct ion_handle *handle) { - int rc; + int id; struct rb_node **p = &client->handles.rb_node; struct rb_node *parent = NULL; struct ion_handle *entry; - do { - int id; - rc = idr_pre_get(&client->idr, GFP_KERNEL); - if (!rc) - return -ENOMEM; - rc = idr_get_new_above(&client->idr, handle, 1, &id); - handle->id = id; - } while (rc == -EAGAIN); + id = idr_alloc(&client->idr, handle, 1, 0, GFP_KERNEL); + if (id < 0) + return id; - if (rc < 0) - return rc; + handle->id = id; while (*p) { parent = *p; @@ -786,7 +780,6 @@ void ion_client_destroy(struct ion_client *client) ion_handle_destroy(&handle->ref); } - idr_remove_all(&client->idr); idr_destroy(&client->idr); down_write(&dev->lock); From c7442a7605836527b6d8e6e7ed42608f35ae85ca Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 19 Sep 2013 10:12:05 -0500 Subject: [PATCH 31/54] ion: don't use __arm_ioremap to map pages ion_heap_map_kernel already implements mapping a scatterlist of pages into the kernel, and all heaps are required to have struct pages associated with them, so delete the functions that use __arm_ioremap and use ion_heap_map_kernel instead. Change-Id: Ia2dfd8d8c6e719d7d2f68dd4c458826fdb938260 Signed-off-by: Colin Cross --- .../staging/android/ion/ion_carveout_heap.c | 42 ++----------------- drivers/staging/android/ion/ion_chunk_heap.c | 2 - 2 files changed, 3 insertions(+), 41 deletions(-) diff --git a/drivers/staging/android/ion/ion_carveout_heap.c b/drivers/staging/android/ion/ion_carveout_heap.c index 4a94b17da67e..f53e7008d6d7 100644 --- a/drivers/staging/android/ion/ion_carveout_heap.c +++ b/drivers/staging/android/ion/ion_carveout_heap.c @@ -25,8 +25,6 @@ #include "ion.h" #include "ion_priv.h" -#include - struct ion_carveout_heap { struct ion_heap heap; struct gen_pool *pool; @@ -109,49 +107,15 @@ void ion_carveout_heap_unmap_dma(struct ion_heap *heap, sg_free_table(buffer->sg_table); } -void *ion_carveout_heap_map_kernel(struct ion_heap *heap, - struct ion_buffer *buffer) -{ - void *ret; - int mtype = MT_MEMORY_NONCACHED; - - if (buffer->flags & ION_FLAG_CACHED) - mtype = MT_MEMORY; - - ret = __arm_ioremap(buffer->priv_phys, buffer->size, - mtype); - if (ret == NULL) - return ERR_PTR(-ENOMEM); - - return ret; -} - -void ion_carveout_heap_unmap_kernel(struct ion_heap *heap, - struct ion_buffer *buffer) -{ - __arm_iounmap(buffer->vaddr); - buffer->vaddr = NULL; - return; -} - -int ion_carveout_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, - struct vm_area_struct *vma) -{ - return remap_pfn_range(vma, vma->vm_start, - __phys_to_pfn(buffer->priv_phys) + vma->vm_pgoff, - vma->vm_end - vma->vm_start, - pgprot_noncached(vma->vm_page_prot)); -} - static struct ion_heap_ops carveout_heap_ops = { .allocate = ion_carveout_heap_allocate, .free = ion_carveout_heap_free, .phys = ion_carveout_heap_phys, .map_dma = ion_carveout_heap_map_dma, .unmap_dma = ion_carveout_heap_unmap_dma, - .map_user = ion_carveout_heap_map_user, - .map_kernel = ion_carveout_heap_map_kernel, - .unmap_kernel = ion_carveout_heap_unmap_kernel, + .map_user = ion_heap_map_user, + .map_kernel = ion_heap_map_kernel, + .unmap_kernel = ion_heap_unmap_kernel, }; struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data) diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c index 19e13ecaa1c1..3ca4b90424c0 100644 --- a/drivers/staging/android/ion/ion_chunk_heap.c +++ b/drivers/staging/android/ion/ion_chunk_heap.c @@ -25,8 +25,6 @@ #include "ion.h" #include "ion_priv.h" -#include - struct ion_chunk_heap { struct ion_heap heap; struct gen_pool *pool; From f26a6f2aa0beea7eeb0a2f69d44a5975ef8c887e Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 19 Sep 2013 10:13:53 -0500 Subject: [PATCH 32/54] ion: don't use phys_to_page or __phys_to_pfn phys_to_page and __phys_to_pfn don't exist on all platforms. Use a combination of pfn_to_page, PFN_DOWN, page_to_pfn, and virt_to_page to get the same results. Change-Id: I53cef26059800bc8b7fb85ae458741574c97c257 Signed-off-by: Colin Cross --- drivers/staging/android/ion/ion_carveout_heap.c | 4 ++-- drivers/staging/android/ion/ion_chunk_heap.c | 5 +++-- drivers/staging/android/ion/ion_system_heap.c | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/staging/android/ion/ion_carveout_heap.c b/drivers/staging/android/ion/ion_carveout_heap.c index f53e7008d6d7..ed2b7ae70964 100644 --- a/drivers/staging/android/ion/ion_carveout_heap.c +++ b/drivers/staging/android/ion/ion_carveout_heap.c @@ -96,8 +96,8 @@ struct sg_table *ion_carveout_heap_map_dma(struct ion_heap *heap, kfree(table); return ERR_PTR(ret); } - sg_set_page(table->sgl, phys_to_page(buffer->priv_phys), buffer->size, - 0); + sg_set_page(table->sgl, pfn_to_page(PFN_DOWN(buffer->priv_phys)), + buffer->size, 0); return table; } diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c index 3ca4b90424c0..e17b6016db54 100644 --- a/drivers/staging/android/ion/ion_chunk_heap.c +++ b/drivers/staging/android/ion/ion_chunk_heap.c @@ -71,7 +71,8 @@ static int ion_chunk_heap_allocate(struct ion_heap *heap, chunk_heap->chunk_size); if (!paddr) goto err; - sg_set_page(sg, phys_to_page(paddr), chunk_heap->chunk_size, 0); + sg_set_page(sg, pfn_to_page(PFN_DOWN(paddr)), + chunk_heap->chunk_size, 0); sg = sg_next(sg); } @@ -167,7 +168,7 @@ struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data) goto error; } for (i = 0; i < chunk_heap->size; i += PAGE_SIZE) { - struct page *page = phys_to_page(chunk_heap->base + i); + struct page *page = pfn_to_page(PFN_DOWN(chunk_heap->base + i)); struct page **pages = &page; ret = map_vm_area(vm_struct, pgprot, &pages); diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index 4eb0ae8c6756..954eb56e7157 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -426,7 +426,7 @@ int ion_system_contig_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, struct vm_area_struct *vma) { - unsigned long pfn = __phys_to_pfn(virt_to_phys(buffer->priv_virt)); + unsigned long pfn = page_to_pfn(virt_to_page(buffer->priv_virt)); return remap_pfn_range(vma, vma->vm_start, pfn + vma->vm_pgoff, vma->vm_end - vma->vm_start, vma->vm_page_prot); From 21e08b49ac311e3d1e9c7168de1bd42868176398 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 19 Sep 2013 09:20:23 -0500 Subject: [PATCH 33/54] ion: fix printk warnings Use %z for size_t and %pa for dma_addr_t to avoid warnings in printks. Change-Id: I2c72874acd0b69cb35fca691928783817deb9394 Signed-off-by: Colin Cross --- drivers/staging/android/ion/ion.c | 23 ++++++++++---------- drivers/staging/android/ion/ion_chunk_heap.c | 2 +- drivers/staging/android/ion/ion_cma_heap.c | 4 ++-- drivers/staging/android/ion/ion_heap.c | 2 +- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 80c79455c36e..371b04f80a24 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -471,7 +471,7 @@ struct ion_handle *ion_alloc(struct ion_client *client, size_t len, struct ion_heap *heap; int ret; - pr_debug("%s: len %d align %d heap_id_mask %u flags %x\n", __func__, + pr_debug("%s: len %zu align %zu heap_id_mask %u flags %x\n", __func__, len, align, heap_id_mask, flags); /* * traverse the list of heaps available in this system in priority @@ -688,7 +688,7 @@ static int ion_debug_client_show(struct seq_file *s, void *unused) for (i = 0; i < ION_NUM_HEAP_IDS; i++) { if (!names[i]) continue; - seq_printf(s, "%16.16s: %16u\n", names[i], sizes[i]); + seq_printf(s, "%16.16s: %16zu\n", names[i], sizes[i]); } return 0; } @@ -1336,10 +1336,10 @@ static int ion_debug_heap_show(struct seq_file *s, void *unused) char task_comm[TASK_COMM_LEN]; get_task_comm(task_comm, client->task); - seq_printf(s, "%16.s %16u %16u\n", task_comm, + seq_printf(s, "%16.s %16u %16zu\n", task_comm, client->pid, size); } else { - seq_printf(s, "%16.s %16u %16u\n", client->name, + seq_printf(s, "%16.s %16u %16zu\n", client->name, client->pid, size); } } @@ -1354,19 +1354,20 @@ static int ion_debug_heap_show(struct seq_file *s, void *unused) continue; total_size += buffer->size; if (!buffer->handle_count) { - seq_printf(s, "%16.s %16u %16u %d %d\n", buffer->task_comm, - buffer->pid, buffer->size, buffer->kmap_cnt, + seq_printf(s, "%16.s %16u %16zu %d %d\n", + buffer->task_comm, buffer->pid, + buffer->size, buffer->kmap_cnt, atomic_read(&buffer->ref.refcount)); total_orphaned_size += buffer->size; } } mutex_unlock(&dev->buffer_lock); seq_printf(s, "----------------------------------------------------\n"); - seq_printf(s, "%16.s %16u\n", "total orphaned", + seq_printf(s, "%16.s %16zu\n", "total orphaned", total_orphaned_size); - seq_printf(s, "%16.s %16u\n", "total ", total_size); + seq_printf(s, "%16.s %16zu\n", "total ", total_size); if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) - seq_printf(s, "%16.s %16u\n", "deferred free", + seq_printf(s, "%16.s %16zu\n", "deferred free", heap->free_list_size); seq_printf(s, "----------------------------------------------------\n"); @@ -1522,11 +1523,11 @@ void __init ion_reserve(struct ion_platform_data *data) int ret = memblock_reserve(data->heaps[i].base, data->heaps[i].size); if (ret) - pr_err("memblock reserve of %x@%lx failed\n", + pr_err("memblock reserve of %zx@%lx failed\n", data->heaps[i].size, data->heaps[i].base); } - pr_info("%s: %s reserved base %lx size %d\n", __func__, + pr_info("%s: %s reserved base %lx size %zu\n", __func__, data->heaps[i].name, data->heaps[i].base, data->heaps[i].size); diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c index e17b6016db54..60952a8aa795 100644 --- a/drivers/staging/android/ion/ion_chunk_heap.c +++ b/drivers/staging/android/ion/ion_chunk_heap.c @@ -186,7 +186,7 @@ struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data) chunk_heap->heap.ops = &chunk_heap_ops; chunk_heap->heap.type = ION_HEAP_TYPE_CHUNK; chunk_heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE; - pr_info("%s: base %lu size %u align %ld\n", __func__, chunk_heap->base, + pr_info("%s: base %lu size %zu align %ld\n", __func__, chunk_heap->base, heap_data->size, heap_data->align); return &chunk_heap->heap; diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c index 55d6003f546c..f8a8090bf89a 100644 --- a/drivers/staging/android/ion/ion_cma_heap.c +++ b/drivers/staging/android/ion/ion_cma_heap.c @@ -128,8 +128,8 @@ static int ion_cma_phys(struct ion_heap *heap, struct ion_buffer *buffer, struct device *dev = cma_heap->dev; struct ion_cma_buffer_info *info = buffer->priv_virt; - dev_dbg(dev, "Return buffer %p physical address 0x%x\n", buffer, - info->handle); + dev_dbg(dev, "Return buffer %p physical address 0x%pa\n", buffer, + &info->handle); *addr = info->handle; *len = buffer->size; diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c index f32f4e69765a..5a93a0273faa 100644 --- a/drivers/staging/android/ion/ion_heap.c +++ b/drivers/staging/android/ion/ion_heap.c @@ -281,7 +281,7 @@ struct ion_heap *ion_heap_create(struct ion_platform_heap *heap_data) } if (IS_ERR_OR_NULL(heap)) { - pr_err("%s: error creating heap %s type %d base %lu size %u\n", + pr_err("%s: error creating heap %s type %d base %lu size %zu\n", __func__, heap_data->name, heap_data->type, heap_data->base, heap_data->size); return ERR_PTR(-EINVAL); From 30b7bee7c585c7eb0b2797c38241fa9f5797982f Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 7 Nov 2013 12:18:57 -0800 Subject: [PATCH 34/54] gpu: ion: remove unnecessary function from system heap ion_system_contig_heap buffers have an sglist, just call ion_heap_map_user to map it. Change-Id: I6dea383955834613fa8833659b31533c957c2b0b Signed-off-by: Colin Cross --- drivers/staging/android/ion/ion_system_heap.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index 954eb56e7157..5b9c0e0da5e7 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -422,17 +422,6 @@ void ion_system_contig_heap_unmap_dma(struct ion_heap *heap, kfree(buffer->sg_table); } -int ion_system_contig_heap_map_user(struct ion_heap *heap, - struct ion_buffer *buffer, - struct vm_area_struct *vma) -{ - unsigned long pfn = page_to_pfn(virt_to_page(buffer->priv_virt)); - return remap_pfn_range(vma, vma->vm_start, pfn + vma->vm_pgoff, - vma->vm_end - vma->vm_start, - vma->vm_page_prot); - -} - static struct ion_heap_ops kmalloc_ops = { .allocate = ion_system_contig_heap_allocate, .free = ion_system_contig_heap_free, @@ -441,7 +430,7 @@ static struct ion_heap_ops kmalloc_ops = { .unmap_dma = ion_system_contig_heap_unmap_dma, .map_kernel = ion_heap_map_kernel, .unmap_kernel = ion_heap_unmap_kernel, - .map_user = ion_system_contig_heap_map_user, + .map_user = ion_heap_map_user, }; struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *unused) From b2ee33eb98bd8240787f6b3a6acffdbab40653dc Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 8 Nov 2013 16:55:35 -0800 Subject: [PATCH 35/54] ion: clean up ioctls Convert the ion ioctls to use _IOW instead of _IOWR where appropriate, and factor out the copy_from_user and copy_to_user based on the _IOC_DIR bits. For the existing incorrect ioctls, add a function to wrap _IOC_DIR to return the corrected value. Change-Id: I3cc34c84b9c52305bdbec27a9224447b102fadcd Signed-off-by: Colin Cross --- drivers/staging/android/ion/ion.c | 110 ++++++++++++++++-------------- 1 file changed, 59 insertions(+), 51 deletions(-) diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 371b04f80a24..fb3459759379 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -1157,41 +1157,65 @@ static int ion_sync_for_device(struct ion_client *client, int fd) return 0; } +/* fix up the cases where the ioctl direction bits are incorrect */ +static unsigned int ion_ioctl_dir(unsigned int cmd) +{ + switch (cmd) { + case ION_IOC_SYNC: + case ION_IOC_FREE: + case ION_IOC_CUSTOM: + return _IOC_WRITE; + default: + return _IOC_DIR(cmd); + } +} + static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct ion_client *client = filp->private_data; + struct ion_device *dev = client->dev; + struct ion_handle *cleanup_handle = NULL; + int ret = 0; + unsigned int dir; + + union { + struct ion_fd_data fd; + struct ion_allocation_data allocation; + struct ion_handle_data handle; + struct ion_custom_data custom; + } data; + + dir = ion_ioctl_dir(cmd); + + if (_IOC_SIZE(cmd) > sizeof(data)) + return -EINVAL; + + if (dir & _IOC_WRITE) + if (copy_from_user(&data, (void __user *)arg, _IOC_SIZE(cmd))) + return -EFAULT; switch (cmd) { case ION_IOC_ALLOC: { - struct ion_allocation_data data; struct ion_handle *handle; - if (copy_from_user(&data, (void __user *)arg, sizeof(data))) - return -EFAULT; - handle = ion_alloc(client, data.len, data.align, - data.heap_id_mask, data.flags); - + handle = ion_alloc(client, data.allocation.len, + data.allocation.align, + data.allocation.heap_id_mask, + data.allocation.flags); if (IS_ERR(handle)) return PTR_ERR(handle); - data.handle = handle->id; + data.allocation.handle = handle->id; - if (copy_to_user((void __user *)arg, &data, sizeof(data))) { - ion_free(client, handle); - return -EFAULT; - } + cleanup_handle = handle; break; } case ION_IOC_FREE: { - struct ion_handle_data data; struct ion_handle *handle; - if (copy_from_user(&data, (void __user *)arg, - sizeof(struct ion_handle_data))) - return -EFAULT; - handle = ion_handle_get_by_id(client, data.handle); + handle = ion_handle_get_by_id(client, data.handle.handle); if (IS_ERR(handle)) return PTR_ERR(handle); ion_free(client, handle); @@ -1201,68 +1225,52 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) case ION_IOC_SHARE: case ION_IOC_MAP: { - struct ion_fd_data data; struct ion_handle *handle; - if (copy_from_user(&data, (void __user *)arg, sizeof(data))) - return -EFAULT; - handle = ion_handle_get_by_id(client, data.handle); + handle = ion_handle_get_by_id(client, data.handle.handle); if (IS_ERR(handle)) return PTR_ERR(handle); - data.fd = ion_share_dma_buf_fd(client, handle); + data.fd.fd = ion_share_dma_buf_fd(client, handle); ion_handle_put(handle); - if (copy_to_user((void __user *)arg, &data, sizeof(data))) - return -EFAULT; - if (data.fd < 0) - return data.fd; + if (data.fd.fd < 0) + ret = data.fd.fd; break; } case ION_IOC_IMPORT: { - struct ion_fd_data data; struct ion_handle *handle; - int ret = 0; - if (copy_from_user(&data, (void __user *)arg, - sizeof(struct ion_fd_data))) - return -EFAULT; - handle = ion_import_dma_buf(client, data.fd); + handle = ion_import_dma_buf(client, data.fd.fd); if (IS_ERR(handle)) ret = PTR_ERR(handle); else - data.handle = handle->id; - - if (copy_to_user((void __user *)arg, &data, - sizeof(struct ion_fd_data))) - return -EFAULT; - if (ret < 0) - return ret; + data.handle.handle = handle->id; break; } case ION_IOC_SYNC: { - struct ion_fd_data data; - if (copy_from_user(&data, (void __user *)arg, - sizeof(struct ion_fd_data))) - return -EFAULT; - ion_sync_for_device(client, data.fd); + ret = ion_sync_for_device(client, data.fd.fd); break; } case ION_IOC_CUSTOM: { - struct ion_device *dev = client->dev; - struct ion_custom_data data; - if (!dev->custom_ioctl) return -ENOTTY; - if (copy_from_user(&data, (void __user *)arg, - sizeof(struct ion_custom_data))) - return -EFAULT; - return dev->custom_ioctl(client, data.cmd, data.arg); + ret = dev->custom_ioctl(client, data.custom.cmd, + data.custom.arg); + break; } default: return -ENOTTY; } - return 0; + + if (dir & _IOC_READ) { + if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(cmd))) { + if (cleanup_handle) + ion_free(client, cleanup_handle); + return -EFAULT; + } + } + return ret; } static int ion_release(struct inode *inode, struct file *file) From 9273153e861f3db897798ec0dc15f70d1aae9410 Mon Sep 17 00:00:00 2001 From: Mitchel Humpherys Date: Tue, 6 Aug 2013 11:19:42 -0700 Subject: [PATCH 36/54] gpu: ion: fix use-after-free in ion_heap_freelist_drain The `buffer' variable is being used after being freed. Fix this. Change-Id: Iea3471fa7dc7535bbf0620c1639fea2008d7cf19 Signed-off-by: Mitchel Humpherys --- drivers/staging/android/ion/ion_heap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c index 5a93a0273faa..e061b266330d 100644 --- a/drivers/staging/android/ion/ion_heap.c +++ b/drivers/staging/android/ion/ion_heap.c @@ -200,9 +200,9 @@ size_t ion_heap_freelist_drain(struct ion_heap *heap, size_t size) if (total_drained >= size) break; list_del(&buffer->list); - ion_buffer_destroy(buffer); heap->free_list_size -= buffer->size; total_drained += buffer->size; + ion_buffer_destroy(buffer); } rt_mutex_unlock(&heap->lock); From 818017a0caa6b7b3bb6e96697a2c35806e08f6a4 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Fri, 22 Nov 2013 15:36:27 -0800 Subject: [PATCH 37/54] ion: Fix two small issues in system_heap allocation In testing ion system heap allocations, I ran across two issues: 1) Not k*z*allocing the sg table. This can cause trouble if we end up trying call sg_alloc_table() with too many entries, then sg_alloc_table() internally fails and tries to free what it thinks is internal table structure, which causes bad pointer traversals. 2) The second list_for_each_entry probably should be _safe, since I was seeing strange lock warnings and oopses on occasion. This seems to resolve it, but could use some extra checking. Change-Id: I59d4c90104a8cf23dc4ae814d0b17348f1b68ac0 Signed-off-by: John Stultz --- drivers/staging/android/ion/ion_system_heap.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index 5b9c0e0da5e7..5926be9d0fdf 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -166,8 +166,7 @@ static int ion_system_heap_allocate(struct ion_heap *heap, max_order = info->order; i++; } - - table = kmalloc(sizeof(struct sg_table), GFP_KERNEL); + table = kzalloc(sizeof(struct sg_table), GFP_KERNEL); if (!table) goto err; @@ -189,7 +188,7 @@ static int ion_system_heap_allocate(struct ion_heap *heap, err1: kfree(table); err: - list_for_each_entry(info, &pages, list) { + list_for_each_entry_safe(info, tmp_info, &pages, list) { free_buffer_page(sys_heap, buffer, info->page, info->order); kfree(info); } From 8af13473b7ca01524862df8e8dae97892ea548ad Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 22 Nov 2013 22:48:42 -0800 Subject: [PATCH 38/54] ion: drop dependency on ARM Ion will compile and run on other platforms now, remove the dependency on ARM. Change-Id: I9da0ab686708bdab575a021031392b4402cce090 Signed-off-by: Colin Cross --- drivers/staging/android/ion/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/android/ion/Kconfig b/drivers/staging/android/ion/Kconfig index 6a5d8cfe7935..3215bd8fb458 100644 --- a/drivers/staging/android/ion/Kconfig +++ b/drivers/staging/android/ion/Kconfig @@ -1,6 +1,5 @@ menuconfig ION tristate "Ion Memory Manager" - depends on ARM select GENERIC_ALLOCATOR select DMA_SHARED_BUFFER help From 63ddadde39e91931890798084ef023ebab4b4a90 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 26 Nov 2013 13:43:29 -0800 Subject: [PATCH 39/54] ion: add alignment check to carveout heap Change-Id: I25c752b3eacb48cccea5be2df319634b3affd331 Signed-off-by: Colin Cross --- drivers/staging/android/ion/ion_carveout_heap.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/android/ion/ion_carveout_heap.c b/drivers/staging/android/ion/ion_carveout_heap.c index ed2b7ae70964..128ee115e60e 100644 --- a/drivers/staging/android/ion/ion_carveout_heap.c +++ b/drivers/staging/android/ion/ion_carveout_heap.c @@ -70,6 +70,9 @@ static int ion_carveout_heap_allocate(struct ion_heap *heap, unsigned long size, unsigned long align, unsigned long flags) { + if (align > PAGE_SIZE) + return -EINVAL; + buffer->priv_phys = ion_carveout_allocate(heap, size, align); return buffer->priv_phys == ION_CARVEOUT_ALLOCATE_FAIL ? -ENOMEM : 0; } From fc04e484c319b8df647886d4cf17f7c450453d1d Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Mon, 25 Nov 2013 13:32:51 -0800 Subject: [PATCH 40/54] ion: optimize ion_heap_buffer_zero ion_heap_buffer_zero can spend a long time in unmap_kernel_range if it has to broadcast a tlb flush to every cpu for every page. Modify it to batch pages into a larger region to clear using a single mapping. This may cause the mapping size to change if the buffer size is not a multiple of the mapping size, so switch to allocating the address space for each chunk. This allows us to use vm_map_ram to handle the allocation and mapping together. The number of pages to zero using a single mapping is set to 32 to hit the fastpath in vm_map_ram. Change-Id: I1accfe67b285cbc9e95e387bea4246864197827d Signed-off-by: Colin Cross --- drivers/staging/android/ion/ion_heap.c | 36 ++++++++++++++++---------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c index e061b266330d..0d30f9f7eeb7 100644 --- a/drivers/staging/android/ion/ion_heap.c +++ b/drivers/staging/android/ion/ion_heap.c @@ -100,40 +100,48 @@ int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, return 0; } +static int ion_heap_clear_pages(struct page **pages, int num, pgprot_t pgprot) +{ + void *addr = vm_map_ram(pages, num, -1, pgprot); + if (!addr) + return -ENOMEM; + memset(addr, 0, PAGE_SIZE * num); + vm_unmap_ram(addr, num); + + return 0; +} + int ion_heap_buffer_zero(struct ion_buffer *buffer) { struct sg_table *table = buffer->sg_table; pgprot_t pgprot; struct scatterlist *sg; - struct vm_struct *vm_struct; int i, j, ret = 0; + struct page *pages[32]; + int k = 0; if (buffer->flags & ION_FLAG_CACHED) pgprot = PAGE_KERNEL; else pgprot = pgprot_writecombine(PAGE_KERNEL); - vm_struct = get_vm_area(PAGE_SIZE, VM_ALLOC); - if (!vm_struct) - return -ENOMEM; - for_each_sg(table->sgl, sg, table->nents, i) { struct page *page = sg_page(sg); unsigned long len = sg->length; for (j = 0; j < len / PAGE_SIZE; j++) { - struct page *sub_page = page + j; - struct page **pages = &sub_page; - ret = map_vm_area(vm_struct, pgprot, &pages); - if (ret) - goto end; - memset(vm_struct->addr, 0, PAGE_SIZE); - unmap_kernel_range((unsigned long)vm_struct->addr, - PAGE_SIZE); + pages[k++] = page + j; + if (k == ARRAY_SIZE(pages)) { + ret = ion_heap_clear_pages(pages, k, pgprot); + if (ret) + goto end; + k = 0; + } } + if (k) + ret = ion_heap_clear_pages(pages, k, pgprot); } end: - free_vm_area(vm_struct); return ret; } From b928ad649cd32b4ca5ba7429bfe897433d37dfea Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 21 Nov 2013 18:56:37 -0800 Subject: [PATCH 41/54] ion: free low memory from page pools first When the shrinkers are called with GFP_HIGH free low memory first, it is more important to have free than high memory. Change-Id: I7ad8a9c133830f04d429c3d87b781b3e862ccedb Signed-off-by: Colin Cross --- drivers/staging/android/ion/ion_page_pool.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/ion_page_pool.c index b052ff6bf383..5a0e629c188b 100644 --- a/drivers/staging/android/ion/ion_page_pool.c +++ b/drivers/staging/android/ion/ion_page_pool.c @@ -143,10 +143,10 @@ int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask, struct page *page; mutex_lock(&pool->mutex); - if (high && pool->high_count) { - page = ion_page_pool_remove(pool, true); - } else if (pool->low_count) { + if (pool->low_count) { page = ion_page_pool_remove(pool, false); + } else if (high && pool->high_count) { + page = ion_page_pool_remove(pool, true); } else { mutex_unlock(&pool->mutex); break; From 3b8da00c6c5e42af7b532dbf51b2d5007095d844 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 26 Nov 2013 15:34:50 -0800 Subject: [PATCH 42/54] ion: check return value from remap_pfn_range Check the return value of remap_pfn_range and return an error if it fails. Change-Id: I206cf95a24607ebe1c80274e3ed15cc7c076d007 Signed-off-by: Colin Cross --- drivers/staging/android/ion/ion_heap.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c index 0d30f9f7eeb7..403fdc7d7453 100644 --- a/drivers/staging/android/ion/ion_heap.c +++ b/drivers/staging/android/ion/ion_heap.c @@ -76,6 +76,7 @@ int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, unsigned long offset = vma->vm_pgoff * PAGE_SIZE; struct scatterlist *sg; int i; + int ret; for_each_sg(table->sgl, sg, table->nents, i) { struct page *page = sg_page(sg); @@ -91,8 +92,10 @@ int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, offset = 0; } len = min(len, remainder); - remap_pfn_range(vma, addr, page_to_pfn(page), len, + ret = remap_pfn_range(vma, addr, page_to_pfn(page), len, vma->vm_page_prot); + if (ret) + return ret; addr += len; if (addr >= vma->vm_end) return 0; From ed6cfafce575cc6baa099212c69b56c0132f598d Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 26 Nov 2013 15:05:46 -0800 Subject: [PATCH 43/54] ion: use vm_insert_pfn for faulted pages Most ion userspace mappings are created with remap_pfn_range. Use vm_insert_pfn instead of vm_insert_page to make faulted cached mappings look more like uncached mappings. Change-Id: I9ec5cad3fef54f3b80be8b306d7ff2f1fe3f0e66 Signed-off-by: Colin Cross --- drivers/staging/android/ion/ion.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index fb3459759379..4ccdda706f3c 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -890,14 +890,15 @@ static void ion_buffer_sync_for_device(struct ion_buffer *buffer, int ion_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct ion_buffer *buffer = vma->vm_private_data; + unsigned long pfn; int ret; mutex_lock(&buffer->lock); ion_buffer_page_dirty(buffer->pages + vmf->pgoff); - BUG_ON(!buffer->pages || !buffer->pages[vmf->pgoff]); - ret = vm_insert_page(vma, (unsigned long)vmf->virtual_address, - ion_buffer_page(buffer->pages[vmf->pgoff])); + + pfn = page_to_pfn(ion_buffer_page(buffer->pages[vmf->pgoff])); + ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn); mutex_unlock(&buffer->lock); if (ret) return VM_FAULT_ERROR; @@ -956,6 +957,8 @@ static int ion_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) } if (ion_buffer_fault_user_mappings(buffer)) { + vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | + VM_DONTDUMP; vma->vm_private_data = buffer; vma->vm_ops = &ion_vma_ops; ion_vm_open(vma); From d671290eae60f4a77ab2aef79cfaed008ee0716d Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 26 Nov 2013 15:25:59 -0800 Subject: [PATCH 44/54] ion: remove ion_heap_alloc_pages Now that ion_vm_fault doesn't need a struct page with a nonzero refcount, there is no need allocate heap memory for cached pages using split_page. Remove the ion_heap_alloc_pages and ion_heap_free_pages helpers in favor of direct calls to alloc_pages and __free_pages, and remove the special handling in the system heap. Change-Id: I5966a798f48df2d56642e662a69c1495944f6509 Signed-off-by: Colin Cross --- drivers/staging/android/ion/ion_heap.c | 27 ------------------- drivers/staging/android/ion/ion_priv.h | 13 --------- drivers/staging/android/ion/ion_system_heap.c | 7 +---- 3 files changed, 1 insertion(+), 46 deletions(-) diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c index 403fdc7d7453..24d7e3284ae5 100644 --- a/drivers/staging/android/ion/ion_heap.c +++ b/drivers/staging/android/ion/ion_heap.c @@ -148,33 +148,6 @@ int ion_heap_buffer_zero(struct ion_buffer *buffer) return ret; } -struct page *ion_heap_alloc_pages(struct ion_buffer *buffer, gfp_t gfp_flags, - unsigned int order) -{ - struct page *page = alloc_pages(gfp_flags, order); - - if (!page) - return page; - - if (ion_buffer_fault_user_mappings(buffer)) - split_page(page, order); - - return page; -} - -void ion_heap_free_pages(struct ion_buffer *buffer, struct page *page, - unsigned int order) -{ - int i; - - if (!ion_buffer_fault_user_mappings(buffer)) { - __free_pages(page, order); - return; - } - for (i = 0; i < (1 << order); i++) - __free_page(page + i); -} - void ion_heap_freelist_add(struct ion_heap *heap, struct ion_buffer * buffer) { rt_mutex_lock(&heap->lock); diff --git a/drivers/staging/android/ion/ion_priv.h b/drivers/staging/android/ion/ion_priv.h index ea87b54987e7..399ec692921d 100644 --- a/drivers/staging/android/ion/ion_priv.h +++ b/drivers/staging/android/ion/ion_priv.h @@ -216,19 +216,6 @@ int ion_heap_map_user(struct ion_heap *, struct ion_buffer *, struct vm_area_struct *); int ion_heap_buffer_zero(struct ion_buffer *buffer); -/** - * ion_heap_alloc_pages - allocate pages from alloc_pages - * @buffer: the buffer to allocate for, used to extract the flags - * @gfp_flags: the gfp_t for the allocation - * @order: the order of the allocatoin - * - * This funciton allocations from alloc pages and also does any other - * necessary operations based on the buffer->flags. For buffers which - * will be faulted in the pages are split using split_page - */ -struct page *ion_heap_alloc_pages(struct ion_buffer *buffer, gfp_t gfp_flags, - unsigned int order); - /** * ion_heap_init_deferred_free -- initialize deferred free functionality * @heap: the heap diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index 5926be9d0fdf..e3aec597554d 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -74,7 +74,7 @@ static struct page *alloc_buffer_page(struct ion_system_heap *heap, if (order > 4) gfp_flags = high_order_gfp_flags; - page = ion_heap_alloc_pages(buffer, gfp_flags, order); + page = alloc_pages(gfp_flags, order); if (!page) return 0; ion_pages_sync_for_device(NULL, page, PAGE_SIZE << order, @@ -91,15 +91,10 @@ static void free_buffer_page(struct ion_system_heap *heap, unsigned int order) { bool cached = ion_buffer_cached(buffer); - bool split_pages = ion_buffer_fault_user_mappings(buffer); - int i; if (!cached) { struct ion_page_pool *pool = heap->pools[order_to_index(order)]; ion_page_pool_free(pool, page); - } else if (split_pages) { - for (i = 0; i < (1 << order); i++) - __free_page(page + i); } else { __free_pages(page, order); } From 1f67f7520303192e46e1621639097007ab076b90 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 26 Nov 2013 15:33:33 -0800 Subject: [PATCH 45/54] ion: allow cached mappings of chunk and system heap buffers Now that ion_vm_fault uses vm_insert_pfn instead of vm_insert_page cached buffers can be supported in any heap. Remove the checks in the chunk and system heaps. Change-Id: I371a44c400ed8a342c3b0eed90d0fb7060537697 Signed-off-by: Colin Cross --- drivers/staging/android/ion/ion_chunk_heap.c | 3 --- drivers/staging/android/ion/ion_system_heap.c | 3 --- 2 files changed, 6 deletions(-) diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c index 60952a8aa795..03af672d1f3e 100644 --- a/drivers/staging/android/ion/ion_chunk_heap.c +++ b/drivers/staging/android/ion/ion_chunk_heap.c @@ -47,9 +47,6 @@ static int ion_chunk_heap_allocate(struct ion_heap *heap, unsigned long num_chunks; unsigned long allocated_size; - if (ion_buffer_fault_user_mappings(buffer)) - return -ENOMEM; - allocated_size = ALIGN(size, chunk_heap->chunk_size); num_chunks = allocated_size / chunk_heap->chunk_size; diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index e3aec597554d..2930eb1d9aa8 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -148,9 +148,6 @@ static int ion_system_heap_allocate(struct ion_heap *heap, if (align > PAGE_SIZE) return -EINVAL; - if (ion_buffer_fault_user_mappings(buffer)) - return -EINVAL; - INIT_LIST_HEAD(&pages); while (size_remaining > 0) { info = alloc_largest_available(sys_heap, buffer, size_remaining, max_order); From 5d68d972728717ee85162bd50122901b7fe8cc6d Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 26 Nov 2013 15:35:29 -0800 Subject: [PATCH 46/54] ion: use alloc_pages in system contig heap There is no reason to use kzalloc, just call alloc_pages directly. Change the GFP from GFP_KERNEL to include __GFP_HIGH, to allow it to return contiguous pages from highmem. virt_to_* functions aren't valid on highmem pages, so store the struct page * in an sg_table in buffer->priv_virt like most other heaps, and replace virt_to_* with page_to_*. Change-Id: Ida78888b101f080883716e1fa5038dfc4dbabd16 Signed-off-by: Colin Cross --- drivers/staging/android/ion/ion_system_heap.c | 71 +++++++++++++------ 1 file changed, 48 insertions(+), 23 deletions(-) diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index 2930eb1d9aa8..d397aa023aef 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -360,29 +360,69 @@ static int ion_system_contig_heap_allocate(struct ion_heap *heap, unsigned long flags) { int order = get_order(len); + struct page *page; + struct sg_table *table; + unsigned long i; + int ret; if (align > (PAGE_SIZE << order)) return -EINVAL; - if (ion_buffer_fault_user_mappings(buffer)) - return -EINVAL; - - buffer->priv_virt = kzalloc(len, GFP_KERNEL); - if (!buffer->priv_virt) + page = alloc_pages(low_order_gfp_flags, order); + if (!page) return -ENOMEM; + + split_page(page, order); + + len = PAGE_ALIGN(len); + for (i = len >> PAGE_SHIFT; i < (1 << order); i++) + __free_page(page + i); + + table = kzalloc(sizeof(struct sg_table), GFP_KERNEL); + if (!table) { + ret = -ENOMEM; + goto out; + } + + ret = sg_alloc_table(table, 1, GFP_KERNEL); + if (ret) + goto out; + + sg_set_page(table->sgl, page, len, 0); + + buffer->priv_virt = table; + + ion_pages_sync_for_device(NULL, page, len, DMA_BIDIRECTIONAL); + return 0; + +out: + for (i = 0; i < len >> PAGE_SHIFT; i++) + __free_page(page + i); + kfree(table); + return ret; } void ion_system_contig_heap_free(struct ion_buffer *buffer) { - kfree(buffer->priv_virt); + struct sg_table *table = buffer->priv_virt; + struct page *page = sg_page(table->sgl); + unsigned long pages = PAGE_ALIGN(buffer->size) >> PAGE_SHIFT; + unsigned long i; + + for (i = 0; i < pages; i++) + __free_page(page + i); + sg_free_table(table); + kfree(table); } static int ion_system_contig_heap_phys(struct ion_heap *heap, struct ion_buffer *buffer, ion_phys_addr_t *addr, size_t *len) { - *addr = virt_to_phys(buffer->priv_virt); + struct sg_table *table = buffer->priv_virt; + struct page *page = sg_page(table->sgl); + *addr = page_to_phys(page); *len = buffer->size; return 0; } @@ -390,27 +430,12 @@ static int ion_system_contig_heap_phys(struct ion_heap *heap, struct sg_table *ion_system_contig_heap_map_dma(struct ion_heap *heap, struct ion_buffer *buffer) { - struct sg_table *table; - int ret; - - table = kzalloc(sizeof(struct sg_table), GFP_KERNEL); - if (!table) - return ERR_PTR(-ENOMEM); - ret = sg_alloc_table(table, 1, GFP_KERNEL); - if (ret) { - kfree(table); - return ERR_PTR(ret); - } - sg_set_page(table->sgl, virt_to_page(buffer->priv_virt), buffer->size, - 0); - return table; + return buffer->priv_virt; } void ion_system_contig_heap_unmap_dma(struct ion_heap *heap, struct ion_buffer *buffer) { - sg_free_table(buffer->sg_table); - kfree(buffer->sg_table); } static struct ion_heap_ops kmalloc_ops = { From 6db8a1c0c9817d6ebd61c47110554aa34729e9a7 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 26 Nov 2013 21:25:47 -0800 Subject: [PATCH 47/54] ion: fix sparse warnings Fix sparse warnings in ion. Change-Id: Icbadf2ca53bea20914f608f619568629c178eae3 Signed-off-by: Colin Cross --- drivers/staging/android/ion/ion.c | 8 ++--- .../staging/android/ion/ion_carveout_heap.c | 8 ++--- drivers/staging/android/ion/ion_chunk_heap.c | 8 ++--- drivers/staging/android/ion/ion_cma_heap.c | 15 +++++----- drivers/staging/android/ion/ion_heap.c | 4 +-- drivers/staging/android/ion/ion_page_pool.c | 2 +- drivers/staging/android/ion/ion_system_heap.c | 30 +++++++++---------- 7 files changed, 37 insertions(+), 38 deletions(-) diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 4ccdda706f3c..426094c5ea3f 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -669,7 +669,7 @@ static int ion_debug_client_show(struct seq_file *s, void *unused) struct ion_client *client = s->private; struct rb_node *n; size_t sizes[ION_NUM_HEAP_IDS] = {0}; - const char *names[ION_NUM_HEAP_IDS] = {0}; + const char *names[ION_NUM_HEAP_IDS] = {NULL}; int i; mutex_lock(&client->lock); @@ -887,7 +887,7 @@ static void ion_buffer_sync_for_device(struct ion_buffer *buffer, mutex_unlock(&buffer->lock); } -int ion_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +static int ion_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct ion_buffer *buffer = vma->vm_private_data; unsigned long pfn; @@ -939,7 +939,7 @@ static void ion_vm_close(struct vm_area_struct *vma) mutex_unlock(&buffer->lock); } -struct vm_operations_struct ion_vma_ops = { +static struct vm_operations_struct ion_vma_ops = { .open = ion_vm_open, .close = ion_vm_close, .fault = ion_vm_fault, @@ -1030,7 +1030,7 @@ static void ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, size_t start, mutex_unlock(&buffer->lock); } -struct dma_buf_ops dma_buf_ops = { +static struct dma_buf_ops dma_buf_ops = { .map_dma_buf = ion_map_dma_buf, .unmap_dma_buf = ion_unmap_dma_buf, .mmap = ion_mmap, diff --git a/drivers/staging/android/ion/ion_carveout_heap.c b/drivers/staging/android/ion/ion_carveout_heap.c index 128ee115e60e..bf53c2656e70 100644 --- a/drivers/staging/android/ion/ion_carveout_heap.c +++ b/drivers/staging/android/ion/ion_carveout_heap.c @@ -85,8 +85,8 @@ static void ion_carveout_heap_free(struct ion_buffer *buffer) buffer->priv_phys = ION_CARVEOUT_ALLOCATE_FAIL; } -struct sg_table *ion_carveout_heap_map_dma(struct ion_heap *heap, - struct ion_buffer *buffer) +static struct sg_table *ion_carveout_heap_map_dma(struct ion_heap *heap, + struct ion_buffer *buffer) { struct sg_table *table; int ret; @@ -104,8 +104,8 @@ struct sg_table *ion_carveout_heap_map_dma(struct ion_heap *heap, return table; } -void ion_carveout_heap_unmap_dma(struct ion_heap *heap, - struct ion_buffer *buffer) +static void ion_carveout_heap_unmap_dma(struct ion_heap *heap, + struct ion_buffer *buffer) { sg_free_table(buffer->sg_table); } diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c index 03af672d1f3e..9ca54586a515 100644 --- a/drivers/staging/android/ion/ion_chunk_heap.c +++ b/drivers/staging/android/ion/ion_chunk_heap.c @@ -115,14 +115,14 @@ static void ion_chunk_heap_free(struct ion_buffer *buffer) kfree(table); } -struct sg_table *ion_chunk_heap_map_dma(struct ion_heap *heap, - struct ion_buffer *buffer) +static struct sg_table *ion_chunk_heap_map_dma(struct ion_heap *heap, + struct ion_buffer *buffer) { return buffer->priv_virt; } -void ion_chunk_heap_unmap_dma(struct ion_heap *heap, - struct ion_buffer *buffer) +static void ion_chunk_heap_unmap_dma(struct ion_heap *heap, + struct ion_buffer *buffer) { return; } diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c index f8a8090bf89a..58c497c197c7 100644 --- a/drivers/staging/android/ion/ion_cma_heap.c +++ b/drivers/staging/android/ion/ion_cma_heap.c @@ -44,8 +44,8 @@ struct ion_cma_buffer_info { * This function could be replaced by dma_common_get_sgtable * as soon as it will avalaible. */ -int ion_cma_get_sgtable(struct device *dev, struct sg_table *sgt, - void *cpu_addr, dma_addr_t handle, size_t size) +static int ion_cma_get_sgtable(struct device *dev, struct sg_table *sgt, + void *cpu_addr, dma_addr_t handle, size_t size) { struct page *page = virt_to_page(cpu_addr); int ret; @@ -137,16 +137,16 @@ static int ion_cma_phys(struct ion_heap *heap, struct ion_buffer *buffer, return 0; } -struct sg_table *ion_cma_heap_map_dma(struct ion_heap *heap, - struct ion_buffer *buffer) +static struct sg_table *ion_cma_heap_map_dma(struct ion_heap *heap, + struct ion_buffer *buffer) { struct ion_cma_buffer_info *info = buffer->priv_virt; return info->table; } -void ion_cma_heap_unmap_dma(struct ion_heap *heap, - struct ion_buffer *buffer) +static void ion_cma_heap_unmap_dma(struct ion_heap *heap, + struct ion_buffer *buffer) { return; } @@ -162,7 +162,8 @@ static int ion_cma_mmap(struct ion_heap *mapper, struct ion_buffer *buffer, buffer->size); } -void *ion_cma_map_kernel(struct ion_heap *heap, struct ion_buffer *buffer) +static void *ion_cma_map_kernel(struct ion_heap *heap, + struct ion_buffer *buffer) { struct ion_cma_buffer_info *info = buffer->priv_virt; /* kernel memory mapping has been done at allocation time */ diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c index 24d7e3284ae5..4d69da55f891 100644 --- a/drivers/staging/android/ion/ion_heap.c +++ b/drivers/staging/android/ion/ion_heap.c @@ -38,7 +38,7 @@ void *ion_heap_map_kernel(struct ion_heap *heap, struct page **tmp = pages; if (!pages) - return 0; + return NULL; if (buffer->flags & ION_FLAG_CACHED) pgprot = PAGE_KERNEL; @@ -193,7 +193,7 @@ size_t ion_heap_freelist_drain(struct ion_heap *heap, size_t size) return total_drained; } -int ion_heap_deferred_free(void *data) +static int ion_heap_deferred_free(void *data) { struct ion_heap *heap = data; diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/ion_page_pool.c index 5a0e629c188b..50e68945b1bb 100644 --- a/drivers/staging/android/ion/ion_page_pool.c +++ b/drivers/staging/android/ion/ion_page_pool.c @@ -134,7 +134,7 @@ int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask, int i; bool high; - high = gfp_mask & __GFP_HIGHMEM; + high = !!(gfp_mask & __GFP_HIGHMEM); if (nr_to_scan == 0) return ion_page_pool_total(pool, high); diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index d397aa023aef..e824c0863bfa 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -26,11 +26,9 @@ #include "ion.h" #include "ion_priv.h" -static unsigned int high_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO | - __GFP_NOWARN | __GFP_NORETRY) & - ~__GFP_WAIT; -static unsigned int low_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO | - __GFP_NOWARN); +static gfp_t high_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN | + __GFP_NORETRY) & ~__GFP_WAIT; +static gfp_t low_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN); static const unsigned int orders[] = {8, 4, 0}; static const int num_orders = ARRAY_SIZE(orders); static int order_to_index(unsigned int order) @@ -76,12 +74,12 @@ static struct page *alloc_buffer_page(struct ion_system_heap *heap, gfp_flags = high_order_gfp_flags; page = alloc_pages(gfp_flags, order); if (!page) - return 0; + return NULL; ion_pages_sync_for_device(NULL, page, PAGE_SIZE << order, DMA_BIDIRECTIONAL); } if (!page) - return 0; + return NULL; return page; } @@ -187,7 +185,7 @@ static int ion_system_heap_allocate(struct ion_heap *heap, return -ENOMEM; } -void ion_system_heap_free(struct ion_buffer *buffer) +static void ion_system_heap_free(struct ion_buffer *buffer) { struct ion_heap *heap = buffer->heap; struct ion_system_heap *sys_heap = container_of(heap, @@ -211,14 +209,14 @@ void ion_system_heap_free(struct ion_buffer *buffer) kfree(table); } -struct sg_table *ion_system_heap_map_dma(struct ion_heap *heap, - struct ion_buffer *buffer) +static struct sg_table *ion_system_heap_map_dma(struct ion_heap *heap, + struct ion_buffer *buffer) { return buffer->priv_virt; } -void ion_system_heap_unmap_dma(struct ion_heap *heap, - struct ion_buffer *buffer) +static void ion_system_heap_unmap_dma(struct ion_heap *heap, + struct ion_buffer *buffer) { return; } @@ -403,7 +401,7 @@ static int ion_system_contig_heap_allocate(struct ion_heap *heap, return ret; } -void ion_system_contig_heap_free(struct ion_buffer *buffer) +static void ion_system_contig_heap_free(struct ion_buffer *buffer) { struct sg_table *table = buffer->priv_virt; struct page *page = sg_page(table->sgl); @@ -427,14 +425,14 @@ static int ion_system_contig_heap_phys(struct ion_heap *heap, return 0; } -struct sg_table *ion_system_contig_heap_map_dma(struct ion_heap *heap, +static struct sg_table *ion_system_contig_heap_map_dma(struct ion_heap *heap, struct ion_buffer *buffer) { return buffer->priv_virt; } -void ion_system_contig_heap_unmap_dma(struct ion_heap *heap, - struct ion_buffer *buffer) +static void ion_system_contig_heap_unmap_dma(struct ion_heap *heap, + struct ion_buffer *buffer) { } From 1ebba641fb19e38541e30666de8f26b7971949dc Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 26 Nov 2013 21:36:54 -0800 Subject: [PATCH 48/54] ion: carveout heap: zero buffers on free, fix memory leak The carveout heap wasn't zeroing its buffers after use. Create the sg_table during allocate instead of map_dma, to allow using the sg_table during free, and call ion_heap_buffer_zero during free. Also fixes a missing kfree when destroying the table. Change-Id: I318a8493cce32580250884cae336dd2e2c28e73b Signed-off-by: Colin Cross --- .../staging/android/ion/ion_carveout_heap.c | 69 +++++++++++++------ 1 file changed, 48 insertions(+), 21 deletions(-) diff --git a/drivers/staging/android/ion/ion_carveout_heap.c b/drivers/staging/android/ion/ion_carveout_heap.c index bf53c2656e70..3f0e5a08fcf1 100644 --- a/drivers/staging/android/ion/ion_carveout_heap.c +++ b/drivers/staging/android/ion/ion_carveout_heap.c @@ -14,7 +14,7 @@ * */ #include - +#include #include #include #include @@ -60,7 +60,11 @@ static int ion_carveout_heap_phys(struct ion_heap *heap, struct ion_buffer *buffer, ion_phys_addr_t *addr, size_t *len) { - *addr = buffer->priv_phys; + struct sg_table *table = buffer->priv_virt; + struct page *page = sg_page(table->sgl); + ion_phys_addr_t paddr = PFN_PHYS(page_to_pfn(page)); + + *addr = paddr; *len = buffer->size; return 0; } @@ -70,44 +74,66 @@ static int ion_carveout_heap_allocate(struct ion_heap *heap, unsigned long size, unsigned long align, unsigned long flags) { + struct sg_table *table; + ion_phys_addr_t paddr; + int ret; + if (align > PAGE_SIZE) return -EINVAL; - buffer->priv_phys = ion_carveout_allocate(heap, size, align); - return buffer->priv_phys == ION_CARVEOUT_ALLOCATE_FAIL ? -ENOMEM : 0; + table = kzalloc(sizeof(struct sg_table), GFP_KERNEL); + if (!table) + return -ENOMEM; + ret = sg_alloc_table(table, 1, GFP_KERNEL); + if (ret) + goto err_free; + + paddr = ion_carveout_allocate(heap, size, align); + if (paddr == ION_CARVEOUT_ALLOCATE_FAIL) { + ret = -ENOMEM; + goto err_free_table; + } + + sg_set_page(table->sgl, pfn_to_page(PFN_DOWN(paddr)), size, 0); + buffer->priv_virt = table; + + return 0; + +err_free_table: + sg_free_table(table); +err_free: + kfree(table); + return ret; } static void ion_carveout_heap_free(struct ion_buffer *buffer) { struct ion_heap *heap = buffer->heap; + struct sg_table *table = buffer->priv_virt; + struct page *page = sg_page(table->sgl); + ion_phys_addr_t paddr = PFN_PHYS(page_to_pfn(page)); - ion_carveout_free(heap, buffer->priv_phys, buffer->size); - buffer->priv_phys = ION_CARVEOUT_ALLOCATE_FAIL; + ion_heap_buffer_zero(buffer); + + if (ion_buffer_cached(buffer)) + dma_sync_sg_for_device(NULL, table->sgl, table->nents, + DMA_BIDIRECTIONAL); + + ion_carveout_free(heap, paddr, buffer->size); + sg_free_table(table); + kfree(table); } static struct sg_table *ion_carveout_heap_map_dma(struct ion_heap *heap, struct ion_buffer *buffer) { - struct sg_table *table; - int ret; - - table = kzalloc(sizeof(struct sg_table), GFP_KERNEL); - if (!table) - return ERR_PTR(-ENOMEM); - ret = sg_alloc_table(table, 1, GFP_KERNEL); - if (ret) { - kfree(table); - return ERR_PTR(ret); - } - sg_set_page(table->sgl, pfn_to_page(PFN_DOWN(buffer->priv_phys)), - buffer->size, 0); - return table; + return buffer->priv_virt; } static void ion_carveout_heap_unmap_dma(struct ion_heap *heap, struct ion_buffer *buffer) { - sg_free_table(buffer->sg_table); + return; } static struct ion_heap_ops carveout_heap_ops = { @@ -139,6 +165,7 @@ struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data) -1); carveout_heap->heap.ops = &carveout_heap_ops; carveout_heap->heap.type = ION_HEAP_TYPE_CARVEOUT; + carveout_heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE; return &carveout_heap->heap; } From 049ca90450f8de6bff6c326d6c20ba2959db2e00 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 27 Nov 2013 15:51:02 -0800 Subject: [PATCH 49/54] ion: add helper to zero contiguous region of pages Add ion_heap_pages_zero for ion heaps to use to zero pages during initialization or allocation, when a struct ion_buffer may not be available. Use it from the chunk heap and carveout heaps. Change-Id: Ic6c921943a8820cf9896da5164f2d9794d0fe91f Signed-off-by: Colin Cross --- .../staging/android/ion/ion_carveout_heap.c | 13 +++++ drivers/staging/android/ion/ion_chunk_heap.c | 39 +++++--------- drivers/staging/android/ion/ion_heap.c | 53 +++++++++++-------- drivers/staging/android/ion/ion_priv.h | 1 + 4 files changed, 58 insertions(+), 48 deletions(-) diff --git a/drivers/staging/android/ion/ion_carveout_heap.c b/drivers/staging/android/ion/ion_carveout_heap.c index 3f0e5a08fcf1..5165de2ce343 100644 --- a/drivers/staging/android/ion/ion_carveout_heap.c +++ b/drivers/staging/android/ion/ion_carveout_heap.c @@ -150,6 +150,19 @@ static struct ion_heap_ops carveout_heap_ops = { struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data) { struct ion_carveout_heap *carveout_heap; + int ret; + + struct page *page; + size_t size; + + page = pfn_to_page(PFN_DOWN(heap_data->base)); + size = heap_data->size; + + ion_pages_sync_for_device(NULL, page, size, DMA_BIDIRECTIONAL); + + ret = ion_heap_pages_zero(page, size, pgprot_writecombine(PAGE_KERNEL)); + if (ret) + return ERR_PTR(ret); carveout_heap = kzalloc(sizeof(struct ion_carveout_heap), GFP_KERNEL); if (!carveout_heap) diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c index 9ca54586a515..8671f12df131 100644 --- a/drivers/staging/android/ion/ion_chunk_heap.c +++ b/drivers/staging/android/ion/ion_chunk_heap.c @@ -140,9 +140,18 @@ static struct ion_heap_ops chunk_heap_ops = { struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data) { struct ion_chunk_heap *chunk_heap; - struct vm_struct *vm_struct; - pgprot_t pgprot = pgprot_writecombine(PAGE_KERNEL); - int i, ret; + int ret; + struct page *page; + size_t size; + + page = pfn_to_page(PFN_DOWN(heap_data->base)); + size = heap_data->size; + + ion_pages_sync_for_device(NULL, page, size, DMA_BIDIRECTIONAL); + + ret = ion_heap_pages_zero(page, size, pgprot_writecombine(PAGE_KERNEL)); + if (ret) + return ERR_PTR(ret); chunk_heap = kzalloc(sizeof(struct ion_chunk_heap), GFP_KERNEL); if (!chunk_heap) @@ -159,26 +168,6 @@ struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data) chunk_heap->size = heap_data->size; chunk_heap->allocated = 0; - vm_struct = get_vm_area(PAGE_SIZE, VM_ALLOC); - if (!vm_struct) { - ret = -ENOMEM; - goto error; - } - for (i = 0; i < chunk_heap->size; i += PAGE_SIZE) { - struct page *page = pfn_to_page(PFN_DOWN(chunk_heap->base + i)); - struct page **pages = &page; - - ret = map_vm_area(vm_struct, pgprot, &pages); - if (ret) - goto error_map_vm_area; - memset(vm_struct->addr, 0, PAGE_SIZE); - unmap_kernel_range((unsigned long)vm_struct->addr, PAGE_SIZE); - } - free_vm_area(vm_struct); - - ion_pages_sync_for_device(NULL, pfn_to_page(PFN_DOWN(heap_data->base)), - heap_data->size, DMA_BIDIRECTIONAL); - gen_pool_add(chunk_heap->pool, chunk_heap->base, heap_data->size, -1); chunk_heap->heap.ops = &chunk_heap_ops; chunk_heap->heap.type = ION_HEAP_TYPE_CHUNK; @@ -188,10 +177,6 @@ struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data) return &chunk_heap->heap; -error_map_vm_area: - free_vm_area(vm_struct); -error: - gen_pool_destroy(chunk_heap->pool); error_gen_pool_create: kfree(chunk_heap); return ERR_PTR(ret); diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c index 4d69da55f891..6c0c089e03e4 100644 --- a/drivers/staging/android/ion/ion_heap.c +++ b/drivers/staging/android/ion/ion_heap.c @@ -114,38 +114,49 @@ static int ion_heap_clear_pages(struct page **pages, int num, pgprot_t pgprot) return 0; } +static int ion_heap_sglist_zero(struct scatterlist *sgl, unsigned int nents, + pgprot_t pgprot) +{ + int p = 0; + int ret = 0; + struct sg_page_iter piter; + struct page *pages[32]; + + for_each_sg_page(sgl, &piter, nents, 0) { + pages[p++] = sg_page_iter_page(&piter); + if (p == ARRAY_SIZE(pages)) { + ret = ion_heap_clear_pages(pages, p, pgprot); + if (ret) + return ret; + p = 0; + } + } + if (p) + ret = ion_heap_clear_pages(pages, p, pgprot); + + return ret; +} + int ion_heap_buffer_zero(struct ion_buffer *buffer) { struct sg_table *table = buffer->sg_table; pgprot_t pgprot; - struct scatterlist *sg; - int i, j, ret = 0; - struct page *pages[32]; - int k = 0; if (buffer->flags & ION_FLAG_CACHED) pgprot = PAGE_KERNEL; else pgprot = pgprot_writecombine(PAGE_KERNEL); - for_each_sg(table->sgl, sg, table->nents, i) { - struct page *page = sg_page(sg); - unsigned long len = sg->length; + return ion_heap_sglist_zero(table->sgl, table->nents, pgprot); +} - for (j = 0; j < len / PAGE_SIZE; j++) { - pages[k++] = page + j; - if (k == ARRAY_SIZE(pages)) { - ret = ion_heap_clear_pages(pages, k, pgprot); - if (ret) - goto end; - k = 0; - } - } - if (k) - ret = ion_heap_clear_pages(pages, k, pgprot); - } -end: - return ret; +int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot) +{ + struct scatterlist sg; + + sg_init_table(&sg, 1); + sg_set_page(&sg, page, size, 0); + return ion_heap_sglist_zero(&sg, 1, pgprot); } void ion_heap_freelist_add(struct ion_heap *heap, struct ion_buffer * buffer) diff --git a/drivers/staging/android/ion/ion_priv.h b/drivers/staging/android/ion/ion_priv.h index 399ec692921d..5b59f58f4b8e 100644 --- a/drivers/staging/android/ion/ion_priv.h +++ b/drivers/staging/android/ion/ion_priv.h @@ -215,6 +215,7 @@ void ion_heap_unmap_kernel(struct ion_heap *, struct ion_buffer *); int ion_heap_map_user(struct ion_heap *, struct ion_buffer *, struct vm_area_struct *); int ion_heap_buffer_zero(struct ion_buffer *buffer); +int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot); /** * ion_heap_init_deferred_free -- initialize deferred free functionality From 1b1cbed2f4cd92b9ccfd28b985983e2d217ecd2e Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 27 Nov 2013 15:53:01 -0800 Subject: [PATCH 50/54] ion: add alignment check to chunk heap Change-Id: I4be12b9545a81f9b46339a905f00e1e64896b3ed Signed-off-by: Colin Cross --- drivers/staging/android/ion/ion_chunk_heap.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c index 8671f12df131..9c0eb5431f87 100644 --- a/drivers/staging/android/ion/ion_chunk_heap.c +++ b/drivers/staging/android/ion/ion_chunk_heap.c @@ -47,6 +47,9 @@ static int ion_chunk_heap_allocate(struct ion_heap *heap, unsigned long num_chunks; unsigned long allocated_size; + if (align > chunk_heap->chunk_size) + return -EINVAL; + allocated_size = ALIGN(size, chunk_heap->chunk_size); num_chunks = allocated_size / chunk_heap->chunk_size; From 8069739d23200f68b59570f6c4c5a8ec66f38fab Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 27 Nov 2013 15:53:21 -0800 Subject: [PATCH 51/54] ion: fix bugs in cma heap Implement ion_cma_unmap_kernel, ion will call it unconditionally. Use correct gfp flags when calling dma_alloc_coherent so it doesn't try to use atomic DMA memory. Check for invalid alignment when allocating. Reject cached allocations - the cpu address returned by dma_alloc_coherent is always going to be an uncached mapping, so map_kernel will not see data written by a cached userspace mapping. Change-Id: I2ea03f28fae3749f6de0b89700b69da3845926ea Signed-off-by: Colin Cross --- drivers/staging/android/ion/ion_cma_heap.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c index 58c497c197c7..4418bda76474 100644 --- a/drivers/staging/android/ion/ion_cma_heap.c +++ b/drivers/staging/android/ion/ion_cma_heap.c @@ -69,13 +69,20 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer, dev_dbg(dev, "Request buffer allocation len %ld\n", len); + if (buffer->flags & ION_FLAG_CACHED) + return -EINVAL; + + if (align > PAGE_SIZE) + return -EINVAL; + info = kzalloc(sizeof(struct ion_cma_buffer_info), GFP_KERNEL); if (!info) { dev_err(dev, "Can't allocate buffer info\n"); return ION_CMA_ALLOCATE_FAILED; } - info->cpu_addr = dma_alloc_coherent(dev, len, &(info->handle), 0); + info->cpu_addr = dma_alloc_coherent(dev, len, &(info->handle), + GFP_HIGHUSER | __GFP_ZERO); if (!info->cpu_addr) { dev_err(dev, "Fail to allocate buffer\n"); @@ -170,6 +177,11 @@ static void *ion_cma_map_kernel(struct ion_heap *heap, return info->cpu_addr; } +static void ion_cma_unmap_kernel(struct ion_heap *heap, + struct ion_buffer *buffer) +{ +} + static struct ion_heap_ops ion_cma_ops = { .allocate = ion_cma_allocate, .free = ion_cma_free, @@ -178,6 +190,7 @@ static struct ion_heap_ops ion_cma_ops = { .phys = ion_cma_phys, .map_user = ion_cma_mmap, .map_kernel = ion_cma_map_kernel, + .unmap_kernel = ion_cma_unmap_kernel, }; struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *data) From 191b477931f7a9b20caea9269f4f340ca76e5a2e Mon Sep 17 00:00:00 2001 From: JP Abgrall Date: Fri, 22 Nov 2013 14:07:03 -0800 Subject: [PATCH 52/54] android: configs: Reorder config fragments, update README Change-Id: I5ee4b794dcc00f74f26562e49a406ea292af63ee (cherry picked from commit 9ebedefd06142c9bc812bfa23401031525002a76) --- android/configs/README | 2 ++ android/configs/android-base.cfg | 1 + android/configs/android-recommended.cfg | 9 +++++---- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/android/configs/README b/android/configs/README index 391dffa6f85f..8798731f8904 100644 --- a/android/configs/README +++ b/android/configs/README @@ -11,3 +11,5 @@ way to enable these options would be: This will generate a .config that can then be used to save a new defconfig or compile a new kernel with Android features enabled. +Because there is no tool to consistently generate these config fragments, +lets keep them alphabetically sorted instead of random. diff --git a/android/configs/android-base.cfg b/android/configs/android-base.cfg index 2b98436550cf..25162024f889 100644 --- a/android/configs/android-base.cfg +++ b/android/configs/android-base.cfg @@ -1,3 +1,4 @@ +# KEEP ALPHABETICALLY SORTED # CONFIG_INET_LRO is not set # CONFIG_MODULES is not set # CONFIG_OABI_COMPAT is not set diff --git a/android/configs/android-recommended.cfg b/android/configs/android-recommended.cfg index 546c37f552bc..b0120f678cc4 100644 --- a/android/configs/android-recommended.cfg +++ b/android/configs/android-recommended.cfg @@ -1,7 +1,4 @@ -CONFIG_PANIC_TIMEOUT=5 -CONFIG_KALLSYMS_ALL=y -CONFIG_PERF_EVENTS=y -CONFIG_COMPACTION=y +# KEEP ALPHABETICALLY SORTED # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_LEGACY_PTYS is not set @@ -14,6 +11,7 @@ CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_COMPACTION=y CONFIG_DM_UEVENT=y CONFIG_DRAGONRISE_FF=y CONFIG_EXT4_FS=y @@ -81,6 +79,7 @@ CONFIG_ION=y CONFIG_JOYSTICK_XPAD=y CONFIG_JOYSTICK_XPAD_FF=y CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_KALLSYMS_ALL=y CONFIG_KSM=y CONFIG_LOGIG940_FF=y CONFIG_LOGIRUMBLEPAD2_FF=y @@ -88,7 +87,9 @@ CONFIG_LOGITECH_FF=y CONFIG_MD=y CONFIG_MEDIA_SUPPORT=y CONFIG_MSDOS_FS=y +CONFIG_PANIC_TIMEOUT=5 CONFIG_PANTHERLORD_FF=y +CONFIG_PERF_EVENTS=y CONFIG_PM_DEBUG=y CONFIG_PM_RUNTIME=y CONFIG_PM_WAKELOCKS_LIMIT=0 From 0f9ae3f7fc853efb3f36e44b1c24ca15490e54f0 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 7 Nov 2013 19:51:09 -0800 Subject: [PATCH 53/54] ion: Cleanup whitespace issues and other checkpatch problems Just some simple cleanups to address whitespace issues and other issues found w/ checkpatch. Change-Id: I181444505627894b8f3bbf59192703b0f65736ee Signed-off-by: John Stultz --- drivers/staging/android/ion/compat_ion.c | 4 +- drivers/staging/android/ion/ion.c | 53 ++++++++++--------- drivers/staging/android/ion/ion.h | 2 +- drivers/staging/android/ion/ion_chunk_heap.c | 1 - drivers/staging/android/ion/ion_heap.c | 5 +- drivers/staging/android/ion/ion_page_pool.c | 2 +- drivers/staging/android/ion/ion_priv.h | 2 +- drivers/staging/android/ion/ion_system_heap.c | 3 +- 8 files changed, 37 insertions(+), 35 deletions(-) diff --git a/drivers/staging/android/ion/compat_ion.c b/drivers/staging/android/ion/compat_ion.c index a89b067ec051..e9a8132cd56f 100644 --- a/drivers/staging/android/ion/compat_ion.c +++ b/drivers/staging/android/ion/compat_ion.c @@ -91,8 +91,8 @@ static int compat_get_ion_custom_data( struct compat_ion_custom_data __user *data32, struct ion_custom_data __user *data) { - compat_uint_t cmd; - compat_ulong_t arg; + compat_uint_t cmd; + compat_ulong_t arg; int err; err = get_user(cmd, &data32->cmd); diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 426094c5ea3f..7522b0be1749 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -110,8 +110,8 @@ struct ion_handle { bool ion_buffer_fault_user_mappings(struct ion_buffer *buffer) { - return ((buffer->flags & ION_FLAG_CACHED) && - !(buffer->flags & ION_FLAG_CACHED_NEEDS_SYNC)); + return (buffer->flags & ION_FLAG_CACHED) && + !(buffer->flags & ION_FLAG_CACHED_NEEDS_SYNC); } bool ion_buffer_cached(struct ion_buffer *buffer) @@ -202,7 +202,8 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap, buffer->size = len; table = heap->ops->map_dma(heap, buffer); - if (WARN_ONCE(table == NULL, "heap->ops->map_dma should return ERR_PTR on error")) + if (WARN_ONCE(table == NULL, + "heap->ops->map_dma should return ERR_PTR on error")) table = ERR_PTR(-EINVAL); if (IS_ERR(table)) { heap->ops->free(buffer); @@ -424,7 +425,8 @@ static struct ion_handle *ion_handle_get_by_id(struct ion_client *client, return handle ? handle : ERR_PTR(-EINVAL); } -static bool ion_handle_validate(struct ion_client *client, struct ion_handle *handle) +static bool ion_handle_validate(struct ion_client *client, + struct ion_handle *handle) { WARN_ON(!mutex_is_locked(&client->lock)); return (idr_find(&client->idr, handle->id) == handle); @@ -578,7 +580,8 @@ static void *ion_buffer_kmap_get(struct ion_buffer *buffer) return buffer->vaddr; } vaddr = buffer->heap->ops->map_kernel(buffer->heap, buffer); - if (WARN_ONCE(vaddr == NULL, "heap->ops->map_kernel should return ERR_PTR on error")) + if (WARN_ONCE(vaddr == NULL, + "heap->ops->map_kernel should return ERR_PTR on error")) return ERR_PTR(-EINVAL); if (IS_ERR(vaddr)) return vaddr; @@ -1403,39 +1406,39 @@ static const struct file_operations debug_heap_fops = { #ifdef DEBUG_HEAP_SHRINKER static int debug_shrink_set(void *data, u64 val) { - struct ion_heap *heap = data; - struct shrink_control sc; - int objs; + struct ion_heap *heap = data; + struct shrink_control sc; + int objs; - sc.gfp_mask = -1; - sc.nr_to_scan = 0; + sc.gfp_mask = -1; + sc.nr_to_scan = 0; - if (!val) - return 0; + if (!val) + return 0; - objs = heap->shrinker.shrink(&heap->shrinker, &sc); - sc.nr_to_scan = objs; + objs = heap->shrinker.shrink(&heap->shrinker, &sc); + sc.nr_to_scan = objs; - heap->shrinker.shrink(&heap->shrinker, &sc); - return 0; + heap->shrinker.shrink(&heap->shrinker, &sc); + return 0; } static int debug_shrink_get(void *data, u64 *val) { - struct ion_heap *heap = data; - struct shrink_control sc; - int objs; + struct ion_heap *heap = data; + struct shrink_control sc; + int objs; - sc.gfp_mask = -1; - sc.nr_to_scan = 0; + sc.gfp_mask = -1; + sc.nr_to_scan = 0; - objs = heap->shrinker.shrink(&heap->shrinker, &sc); - *val = objs; - return 0; + objs = heap->shrinker.shrink(&heap->shrinker, &sc); + *val = objs; + return 0; } DEFINE_SIMPLE_ATTRIBUTE(debug_shrink_fops, debug_shrink_get, - debug_shrink_set, "%llu\n"); + debug_shrink_set, "%llu\n"); #endif void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap) diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h index 962e1c58d362..dcd2a0cdb192 100644 --- a/drivers/staging/android/ion/ion.h +++ b/drivers/staging/android/ion/ion.h @@ -38,7 +38,7 @@ struct ion_buffer; * struct ion_platform_heap - defines a heap in the given platform * @type: type of the heap from ion_heap_type enum * @id: unique identifier for heap. When allocating higher numbers - * will be allocated from first. At allocation these are passed + * will be allocated from first. At allocation these are passed * as a bit mask and therefore can not exceed ION_NUM_HEAP_IDS. * @name: used for debug purposes * @base: base address of heap in physical memory if applicable diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c index 9c0eb5431f87..ca20d6279602 100644 --- a/drivers/staging/android/ion/ion_chunk_heap.c +++ b/drivers/staging/android/ion/ion_chunk_heap.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. * */ -//#include #include #include #include diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c index 6c0c089e03e4..5b01e9e30a4f 100644 --- a/drivers/staging/android/ion/ion_heap.c +++ b/drivers/staging/android/ion/ion_heap.c @@ -49,9 +49,8 @@ void *ion_heap_map_kernel(struct ion_heap *heap, int npages_this_entry = PAGE_ALIGN(sg->length) / PAGE_SIZE; struct page *page = sg_page(sg); BUG_ON(i >= npages); - for (j = 0; j < npages_this_entry; j++) { + for (j = 0; j < npages_this_entry; j++) *(tmp++) = page++; - } } vaddr = vmap(pages, npages, VM_MAP, pgprot); vfree(pages); @@ -159,7 +158,7 @@ int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot) return ion_heap_sglist_zero(&sg, 1, pgprot); } -void ion_heap_freelist_add(struct ion_heap *heap, struct ion_buffer * buffer) +void ion_heap_freelist_add(struct ion_heap *heap, struct ion_buffer *buffer) { rt_mutex_lock(&heap->lock); list_add(&buffer->list, &heap->free_list); diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/ion_page_pool.c index 50e68945b1bb..f087a02770a8 100644 --- a/drivers/staging/android/ion/ion_page_pool.c +++ b/drivers/staging/android/ion/ion_page_pool.c @@ -108,7 +108,7 @@ void *ion_page_pool_alloc(struct ion_page_pool *pool) return page; } -void ion_page_pool_free(struct ion_page_pool *pool, struct page* page) +void ion_page_pool_free(struct ion_page_pool *pool, struct page *page) { int ret; diff --git a/drivers/staging/android/ion/ion_priv.h b/drivers/staging/android/ion/ion_priv.h index 5b59f58f4b8e..19691c0d24c7 100644 --- a/drivers/staging/android/ion/ion_priv.h +++ b/drivers/staging/android/ion/ion_priv.h @@ -230,7 +230,7 @@ int ion_heap_init_deferred_free(struct ion_heap *heap); /** * ion_heap_freelist_add - add a buffer to the deferred free list * @heap: the heap - * @buffer: the buffer + * @buffer: the buffer * * Adds an item to the deferred freelist. */ diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index e824c0863bfa..05e9dc93980f 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -148,7 +148,8 @@ static int ion_system_heap_allocate(struct ion_heap *heap, INIT_LIST_HEAD(&pages); while (size_remaining > 0) { - info = alloc_largest_available(sys_heap, buffer, size_remaining, max_order); + info = alloc_largest_available(sys_heap, buffer, size_remaining, + max_order); if (!info) goto err; list_add_tail(&info->list, &pages); From 8f1c42284159ebd6851e1e75507f2ad6fba87d0f Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 7 Nov 2013 19:58:41 -0800 Subject: [PATCH 54/54] ion: Improve ION config description Mostly just to quiet checkpatch warnings, be more verbose in describing the ION config option. Change-Id: I194235f1a68623dca15ae6e658fc99d00943a827 Signed-off-by: John Stultz --- drivers/staging/android/ion/Kconfig | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/staging/android/ion/Kconfig b/drivers/staging/android/ion/Kconfig index 3215bd8fb458..a342d96ee4f0 100644 --- a/drivers/staging/android/ion/Kconfig +++ b/drivers/staging/android/ion/Kconfig @@ -2,8 +2,12 @@ menuconfig ION tristate "Ion Memory Manager" select GENERIC_ALLOCATOR select DMA_SHARED_BUFFER - help - Chose this option to enable the ION Memory Manager. + ---help--- + Chose this option to enable the ION Memory Manager, + used by Android to efficiently allocate buffers + from userspace that can be shared between drivers. + If you're not using Android its probably safe to + say N here. config ION_TEST tristate "Ion Test Device"