diff options
Diffstat (limited to 'drivers/gpu/ion/sprd/compat_sprd_ion.c')
| -rw-r--r-- | drivers/gpu/ion/sprd/compat_sprd_ion.c | 336 |
1 files changed, 336 insertions, 0 deletions
diff --git a/drivers/gpu/ion/sprd/compat_sprd_ion.c b/drivers/gpu/ion/sprd/compat_sprd_ion.c new file mode 100644 index 00000000..37141596 --- /dev/null +++ b/drivers/gpu/ion/sprd/compat_sprd_ion.c @@ -0,0 +1,336 @@ +/* + * drivers/gpu/ion/compat_ion.c + * + * 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. + * + */ + +#include <linux/compat.h> +#include <linux/fs.h> +#include <linux/uaccess.h> + +#include <linux/ion.h> +#include <video/ion_sprd.h> +#include "sprd_fence.h" +#include "compat_sprd_ion.h" + +/* See kernel/include/video/ion_sprd.h for the definition of these structs */ +struct compat_ion_phys_data { + compat_int_t fd_buffer; + compat_ulong_t phys; + compat_size_t size; +}; + +struct compat_ion_msync_data { + compat_int_t fd_buffer; + compat_uptr_t vaddr; + compat_uptr_t paddr; + compat_size_t size; +}; + +struct compat_ion_mmu_data { + compat_int_t master_id; + compat_int_t fd_buffer; + compat_ulong_t iova_addr; + compat_size_t iova_size; +}; + +static int compat_get_ion_phys_data( + struct compat_ion_phys_data __user *data32, + struct ion_phys_data __user *data) +{ + compat_int_t i; + int err; + + err = get_user(i, &data32->fd_buffer); + err |= put_user(i, &data->fd_buffer); + + return err; +}; + +static int compat_put_ion_phys_data( + struct compat_ion_phys_data __user *data32, + struct ion_phys_data __user *data) +{ + compat_ulong_t ul; + compat_size_t s; + int err; + + err = get_user(ul, &data->phys); + err |= put_user(ul, &data32->phys); + err |= get_user(s, &data->size); + err |= put_user(s, &data32->size); + + return err; +}; + +static int compat_get_ion_msync_data( + struct compat_ion_msync_data __user *data32, + struct ion_msync_data __user *data) +{ + compat_int_t i; + compat_uptr_t up; + compat_size_t s; + int err; + + err = get_user(i, &data32->fd_buffer); + err |= put_user(i, &data->fd_buffer); + err |= get_user(up, &data32->vaddr); + err |= put_user(up, &data->vaddr); + err |= get_user(up, &data32->paddr); + err |= put_user(up, &data->paddr); + err |= get_user(s, &data32->size); + err |= put_user(s, &data->size); + + return err; +}; + +static int compat_get_ion_mmu_data( + struct compat_ion_mmu_data __user *data32, + struct ion_mmu_data __user *data) +{ + compat_int_t i; + compat_ulong_t ul; + compat_size_t s; + int err; + + err = get_user(i, &data32->master_id); + err |= put_user(i, &data->master_id); + err |= get_user(i, &data32->fd_buffer); + err |= put_user(i, &data->fd_buffer); + err |= get_user(ul, &data32->iova_addr); + err |= put_user(ul, &data->iova_addr); + err |= get_user(s, &data32->iova_size); + err |= put_user(s, &data->iova_size); + + return err; +}; + +static int compat_put_ion_mmu_data( + struct compat_ion_mmu_data __user *data32, + struct ion_mmu_data __user *data) +{ + compat_int_t i; + compat_ulong_t ul; + compat_size_t s; + int err; + + err = get_user(i, &data->master_id); + err |= put_user(i, &data32->master_id); + err |= get_user(i, &data->fd_buffer); + err |= put_user(i, &data32->fd_buffer); + err |= get_user(ul, &data->iova_addr); + err |= put_user(ul, &data32->iova_addr); + err |= get_user(s, &data->iova_size); + err |= put_user(s, &data32->iova_size); + + return err; +}; + +long compat_sprd_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ +#if 0 + struct ion_client *client = filp->private_data; + struct ion_device *dev = client->dev; + + if (!filp->f_op || !dev->custom_ioctl) + return -ENOTTY; +#endif + long ret; + + pr_debug("%s, cmd: %u", __FUNCTION__, cmd); + switch (cmd) { + case ION_SPRD_CUSTOM_PHYS: + { + struct compat_ion_phys_data __user *data32; + struct ion_phys_data __user *data; + int err; + + data32 = compat_ptr(arg); + data = compat_alloc_user_space(sizeof(*data)); + if (data == NULL) + return -EFAULT; + + err = compat_get_ion_phys_data(data32, data); + if (err) + return err; +#if 0 + ret = dev->custom_ioctl(client, ION_SPRD_CUSTOM_PHYS, + (unsigned long)data); +#else + ret = sprd_ion_ioctl(filp, ION_SPRD_CUSTOM_PHYS, (unsigned long)data); +#endif + err = compat_put_ion_phys_data(data32, data); + return ret ? ret : err; + } + case ION_SPRD_CUSTOM_MSYNC: + { + struct compat_ion_msync_data __user *data32; + struct ion_msync_data __user *data; + int err; + + data32 = compat_ptr(arg); + data = compat_alloc_user_space(sizeof(*data)); + if (data == NULL) + return -EFAULT; + + err = compat_get_ion_msync_data(data32, data); + if (err) + return err; +#if 0 + ret = dev->custom_ioctl(client, ION_SPRD_CUSTOM_MSYNC, + (unsigned long)data); +#else + ret = sprd_ion_ioctl(filp, ION_SPRD_CUSTOM_MSYNC, (unsigned long)data); +#endif + return ret; + } +#if defined(CONFIG_SPRD_IOMMU) + case ION_SPRD_CUSTOM_GSP_MAP: + { + struct compat_ion_mmu_data __user *data32; + struct ion_mmu_data __user *data; + int err; + + data32 = compat_ptr(arg); + data = compat_alloc_user_space(sizeof(*data)); + if (data == NULL) + return -EFAULT; + + err = compat_get_ion_mmu_data(data32, data); + if (err) + return err; +#if 0 + ret = dev->custom_ioctl(client, ION_SPRD_CUSTOM_GSP_MAP, + (unsigned long)data); +#else + ret = sprd_ion_ioctl(filp, ION_SPRD_CUSTOM_GSP_MAP, (unsigned long)data); +#endif + err = compat_put_ion_mmu_data(data32, data); + return ret ? ret : err; + } + case ION_SPRD_CUSTOM_GSP_UNMAP: + { + struct compat_ion_mmu_data __user *data32; + struct ion_mmu_data __user *data; + int err; + + data32 = compat_ptr(arg); + data = compat_alloc_user_space(sizeof(*data)); + if (data == NULL) + return -EFAULT; + + err = compat_get_ion_mmu_data(data32, data); + if (err) + return err; +#if 0 + ret = dev->custom_ioctl(client, ION_SPRD_CUSTOM_GSP_UNMAP, + (unsigned long)data); +#else + ret = sprd_ion_ioctl(filp, ION_SPRD_CUSTOM_GSP_UNMAP, (unsigned long)data); +#endif + err = compat_put_ion_mmu_data(data32, data); + return ret ? ret : err; + } + case ION_SPRD_CUSTOM_MM_MAP: + { + struct compat_ion_mmu_data __user *data32; + struct ion_mmu_data __user *data; + int err; + + data32 = compat_ptr(arg); + data = compat_alloc_user_space(sizeof(*data)); + if (data == NULL) + return -EFAULT; + + err = compat_get_ion_mmu_data(data32, data); + if (err) + return err; +#if 0 + ret = dev->custom_ioctl(client, ION_SPRD_CUSTOM_MM_MAP, + (unsigned long)data); +#else + ret = sprd_ion_ioctl(filp, ION_SPRD_CUSTOM_MM_MAP, (unsigned long)data); +#endif + err = compat_put_ion_mmu_data(data32, data); + return ret ? ret : err; + } + case ION_SPRD_CUSTOM_MM_UNMAP: + { + struct compat_ion_mmu_data __user *data32; + struct ion_mmu_data __user *data; + int err; + + data32 = compat_ptr(arg); + data = compat_alloc_user_space(sizeof(*data)); + if (data == NULL) + return -EFAULT; + + err = compat_get_ion_mmu_data(data32, data); + if (err) + return err; +#if 0 + ret = dev->custom_ioctl(client, ION_SPRD_CUSTOM_MM_UNMAP, + (unsigned long)data); +#else + ret = sprd_ion_ioctl(filp, ION_SPRD_CUSTOM_MM_UNMAP, (unsigned long)data); +#endif + err = compat_put_ion_mmu_data(data32, data); + return ret ? ret : err; + } +#endif + case ION_SPRD_CUSTOM_FENCE_CREATE: + { + int ret = -1; + struct ion_fence_data data; + + if (copy_from_user(&data, (void __user *)arg, sizeof(data))) { + pr_err("FENCE_CREATE user data is err\n"); + return -EFAULT; + } + + ret = sprd_fence_build(&data); + if (ret != 0) { + pr_err("sprd_fence_build failed\n"); + return -EFAULT; + } + + if (copy_to_user((void __user *)arg, &data, sizeof(data))) { + sprd_fence_destroy(&data); + pr_err("copy_to_user fence failed\n"); + return -EFAULT; + } + + break; + } + case ION_SPRD_CUSTOM_FENCE_SIGNAL: + { + struct ion_fence_data data; + + if (copy_from_user(&data, (void __user *)arg, sizeof(data))) { + pr_err("FENCE_CREATE user data is err\n"); + return -EFAULT; + } + + sprd_fence_signal(&data); + + break; + } + case ION_SPRD_CUSTOM_FENCE_DUP: + { + break; + + } + default: + return -ENOIOCTLCMD; + } +} |
