/*
 * 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/bitops.h>
#include <linux/circ_buf.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/uaccess.h>

#include <video/adf_client.h>
#include <video/adf_format.h>

#include "sw_sync.h"
#include "sync.h"

#include "adf.h"
#include "adf_fops.h"
#include "adf_sysfs.h"

#ifdef CONFIG_COMPAT
#include "adf_fops32.h"
#endif

static int adf_obj_set_event(struct adf_obj *obj, struct adf_file *file,
		struct adf_set_event __user *arg)
{
	struct adf_set_event data;
	bool enabled;
	unsigned long flags;
	int err;

	if (copy_from_user(&data, arg, sizeof(data)))
		return -EFAULT;

	err = adf_obj_check_supports_event(obj, data.type);
	if (err < 0)
		return err;

	spin_lock_irqsave(&obj->file_lock, flags);
	if (data.enabled)
		enabled = test_and_set_bit(data.type,
				file->event_subscriptions);
	else
		enabled = test_and_clear_bit(data.type,
				file->event_subscriptions);
	spin_unlock_irqrestore(&obj->file_lock, flags);

	if (data.enabled == enabled)
		return -EALREADY;

	if (data.enabled)
		adf_event_get(obj, data.type);
	else
		adf_event_put(obj, data.type);

	return 0;
}

static int adf_obj_copy_custom_data_to_user(struct adf_obj *obj,
		void __user *dst, size_t *dst_size)
{
	void *custom_data;
	size_t custom_data_size;
	int ret;

	if (!obj->ops || !obj->ops->custom_data) {
		dev_dbg(&obj->dev, "%s: no custom_data op\n", __func__);
		return 0;
	}

	custom_data = kzalloc(ADF_MAX_CUSTOM_DATA_SIZE, GFP_KERNEL);
	if (!custom_data)
		return -ENOMEM;

	ret = obj->ops->custom_data(obj, custom_data, &custom_data_size);
	if (ret < 0)
		goto done;

	if (copy_to_user(dst, custom_data, min(*dst_size, custom_data_size))) {
		ret = -EFAULT;
		goto done;
	}
	*dst_size = custom_data_size;

done:
	kfree(custom_data);
	return ret;
}

static int adf_eng_get_data(struct adf_overlay_engine *eng,
		struct adf_overlay_engine_data __user *arg)
{
	struct adf_device *dev = adf_overlay_engine_parent(eng);
	struct adf_overlay_engine_data data;
	size_t n_supported_formats;
	u32 *supported_formats = NULL;
	int ret = 0;

	if (copy_from_user(&data, arg, sizeof(data)))
		return -EFAULT;

	strlcpy(data.name, eng->base.name, sizeof(data.name));

	if (data.n_supported_formats > ADF_MAX_SUPPORTED_FORMATS)
		return -EINVAL;

	n_supported_formats = data.n_supported_formats;
	data.n_supported_formats = eng->ops->n_supported_formats;

	if (n_supported_formats) {
		supported_formats = kzalloc(n_supported_formats *
				sizeof(supported_formats[0]), GFP_KERNEL);
		if (!supported_formats)
			return -ENOMEM;
	}

	memcpy(supported_formats, eng->ops->supported_formats,
			sizeof(u32) * min(n_supported_formats,
					eng->ops->n_supported_formats));

	mutex_lock(&dev->client_lock);
	ret = adf_obj_copy_custom_data_to_user(&eng->base, arg->custom_data,
			&data.custom_data_size);
	mutex_unlock(&dev->client_lock);

	if (ret < 0)
		goto done;

	if (copy_to_user(arg, &data, sizeof(data))) {
		ret = -EFAULT;
		goto done;
	}

	if (supported_formats && copy_to_user(arg->supported_formats,
			supported_formats,
			n_supported_formats * sizeof(supported_formats[0])))
		ret = -EFAULT;

done:
	kfree(supported_formats);
	return ret;
}

static int adf_buffer_import(struct adf_device *dev,
		struct adf_buffer_config __user *cfg, struct adf_buffer *buf)
{
	struct adf_buffer_config user_buf;
	size_t i;
	int ret = 0;

	if (copy_from_user(&user_buf, cfg, sizeof(user_buf)))
		return -EFAULT;

	memset(buf, 0, sizeof(*buf));

	if (user_buf.n_planes > ADF_MAX_PLANES) {
		dev_err(&dev->base.dev, "invalid plane count %u\n",
				user_buf.n_planes);
		return -EINVAL;
	}

	buf->overlay_engine = idr_find(&dev->overlay_engines,
			user_buf.overlay_engine);
	if (!buf->overlay_engine) {
		dev_err(&dev->base.dev, "invalid overlay engine id %u\n",
				user_buf.overlay_engine);
		return -ENOENT;
	}

	buf->w = user_buf.w;
	buf->h = user_buf.h;
	buf->format = user_buf.format;
	for (i = 0; i < user_buf.n_planes; i++) {
		buf->dma_bufs[i] = dma_buf_get(user_buf.fd[i]);
		if (IS_ERR(buf->dma_bufs[i])) {
			ret = PTR_ERR(buf->dma_bufs[i]);
			dev_err(&dev->base.dev, "importing dma_buf fd %llu failed: %d\n",
					user_buf.fd[i], ret);
			buf->dma_bufs[i] = NULL;
			goto done;
		}
		buf->offset[i] = user_buf.offset[i];
		buf->pitch[i] = user_buf.pitch[i];
	}
	buf->n_planes = user_buf.n_planes;

	if (user_buf.acquire_fence >= 0) {
		buf->acquire_fence = sync_fence_fdget(user_buf.acquire_fence);
		if (!buf->acquire_fence) {
			dev_err(&dev->base.dev, "getting fence fd %lld failed\n",
					user_buf.acquire_fence);
			ret = -EINVAL;
			goto done;
		}
	}

done:
	if (ret < 0)
		adf_buffer_cleanup(buf);
	return ret;
}

static int adf_device_post_config(struct adf_device *dev,
		struct adf_post_config __user *arg)
{
	struct sync_fence *complete_fence;
	int complete_fence_fd;
	struct adf_buffer *bufs = NULL;
	struct adf_interface **intfs = NULL;
	size_t n_intfs, n_bufs, i;
	void *custom_data = NULL;
	size_t custom_data_size;
	int ret = 0;

	complete_fence_fd = get_unused_fd();
	if (complete_fence_fd < 0)
		return complete_fence_fd;

	if (get_user(n_intfs, &arg->n_interfaces)) {
		ret = -EFAULT;
		goto err_get_user;
	}

	if (n_intfs > ADF_MAX_INTERFACES) {
		ret = -EINVAL;
		goto err_get_user;
	}

	if (get_user(n_bufs, &arg->n_bufs)) {
		ret = -EFAULT;
		goto err_get_user;
	}

	if (n_bufs > ADF_MAX_BUFFERS) {
		ret = -EINVAL;
		goto err_get_user;
	}

	if (get_user(custom_data_size, &arg->custom_data_size)) {
		ret = -EFAULT;
		goto err_get_user;
	}

	if (custom_data_size > ADF_MAX_CUSTOM_DATA_SIZE) {
		ret = -EINVAL;
		goto err_get_user;
	}

	if (n_intfs) {
		intfs = kmalloc(sizeof(intfs[0]) * n_intfs, GFP_KERNEL);
		if (!intfs) {
			ret = -ENOMEM;
			goto err_get_user;
		}
	}

	for (i = 0; i < n_intfs; i++) {
		u32 intf_id;
		if (get_user(intf_id, &arg->interfaces[i])) {
			ret = -EFAULT;
			goto err_get_user;
		}

		intfs[i] = idr_find(&dev->interfaces, intf_id);
		if (!intfs[i]) {
			ret = -EINVAL;
			goto err_get_user;
		}
	}

	if (n_bufs) {
		bufs = kzalloc(sizeof(bufs[0]) * n_bufs, GFP_KERNEL);
		if (!bufs) {
			ret = -ENOMEM;
			goto err_get_user;
		}
	}

	for (i = 0; i < n_bufs; i++) {
		ret = adf_buffer_import(dev, &arg->bufs[i], &bufs[i]);
		if (ret < 0) {
			memset(&bufs[i], 0, sizeof(bufs[i]));
			goto err_import;
		}
	}

	if (custom_data_size) {
		custom_data = kzalloc(custom_data_size, GFP_KERNEL);
		if (!custom_data) {
			ret = -ENOMEM;
			goto err_import;
		}

		if (copy_from_user(custom_data, arg->custom_data,
				custom_data_size)) {
			ret = -EFAULT;
			goto err_import;
		}
	}

	if (put_user(complete_fence_fd, &arg->complete_fence)) {
		ret = -EFAULT;
		goto err_import;
	}

	complete_fence = adf_device_post_nocopy(dev, intfs, n_intfs, bufs,
			n_bufs, custom_data, custom_data_size);
	if (IS_ERR(complete_fence)) {
		ret = PTR_ERR(complete_fence);
		goto err_import;
	}

	sync_fence_install(complete_fence, complete_fence_fd);
	return 0;

err_import:
	for (i = 0; i < n_bufs; i++)
		adf_buffer_cleanup(&bufs[i]);

err_get_user:
	kfree(custom_data);
	kfree(bufs);
	kfree(intfs);
	put_unused_fd(complete_fence_fd);
	return ret;
}

static int adf_intf_simple_post_config(struct adf_interface *intf,
		struct adf_simple_post_config __user *arg)
{
	struct adf_device *dev = intf->base.parent;
	struct sync_fence *complete_fence;
	int complete_fence_fd;
	struct adf_buffer buf;
	int ret = 0;

	complete_fence_fd = get_unused_fd();
	if (complete_fence_fd < 0)
		return complete_fence_fd;

	ret = adf_buffer_import(dev, &arg->buf, &buf);
	if (ret < 0)
		goto err_import;

	if (put_user(complete_fence_fd, &arg->complete_fence)) {
		ret = -EFAULT;
		goto err_put_user;
	}

	complete_fence = adf_interface_simple_post(intf, &buf);
	if (IS_ERR(complete_fence)) {
		ret = PTR_ERR(complete_fence);
		goto err_put_user;
	}

	sync_fence_install(complete_fence, complete_fence_fd);
	return 0;

err_put_user:
	adf_buffer_cleanup(&buf);
err_import:
	put_unused_fd(complete_fence_fd);
	return ret;
}

static int adf_intf_simple_buffer_alloc(struct adf_interface *intf,
		struct adf_simple_buffer_alloc __user *arg)
{
	struct adf_simple_buffer_alloc data;
	struct dma_buf *dma_buf;
	int ret = 0;

	if (copy_from_user(&data, arg, sizeof(data)))
		return -EFAULT;

	data.fd = get_unused_fd_flags(O_CLOEXEC);
	if (data.fd < 0)
		return data.fd;

	ret = adf_interface_simple_buffer_alloc(intf, data.w, data.h,
			data.format, &dma_buf, &data.offset, &data.pitch);
	if (ret < 0)
		goto err_alloc;

	if (copy_to_user(arg, &data, sizeof(*arg))) {
		ret = -EFAULT;
		goto err_copy;
	}

	fd_install(data.fd, dma_buf->file);
	return 0;

err_copy:
	dma_buf_put(dma_buf);

err_alloc:
	put_unused_fd(data.fd);
	return ret;
}

static int adf_copy_attachment_list_to_user(
		struct adf_attachment_config __user *to, size_t n_to,
		struct adf_attachment *from, size_t n_from)
{
	struct adf_attachment_config *temp;
	size_t n = min(n_to, n_from);
	size_t i;
	int ret = 0;

	if (!n)
		return 0;

	temp = kzalloc(n * sizeof(temp[0]), GFP_KERNEL);
	if (!temp)
		return -ENOMEM;

	for (i = 0; i < n; i++) {
		temp[i].interface = from[i].interface->base.id;
		temp[i].overlay_engine = from[i].overlay_engine->base.id;
	}

	if (copy_to_user(to, temp, n * sizeof(to[0]))) {
		ret = -EFAULT;
		goto done;
	}

done:
	kfree(temp);
	return ret;
}

static int adf_device_get_data(struct adf_device *dev,
		struct adf_device_data __user *arg)
{
	struct adf_device_data data;
	size_t n_attach;
	struct adf_attachment *attach = NULL;
	size_t n_allowed_attach;
	struct adf_attachment *allowed_attach = NULL;
	int ret = 0;

	if (copy_from_user(&data, arg, sizeof(data)))
		return -EFAULT;

	if (data.n_attachments > ADF_MAX_ATTACHMENTS ||
			data.n_allowed_attachments > ADF_MAX_ATTACHMENTS)
		return -EINVAL;

	strlcpy(data.name, dev->base.name, sizeof(data.name));

	if (data.n_attachments) {
		attach = kzalloc(data.n_attachments * sizeof(attach[0]),
				GFP_KERNEL);
		if (!attach)
			return -ENOMEM;
	}
	n_attach = adf_device_attachments(dev, attach, data.n_attachments);

	if (data.n_allowed_attachments) {
		allowed_attach = kzalloc(data.n_allowed_attachments *
				sizeof(allowed_attach[0]), GFP_KERNEL);
		if (!allowed_attach) {
			ret = -ENOMEM;
			goto done;
		}
	}
	n_allowed_attach = adf_device_attachments_allowed(dev, allowed_attach,
			data.n_allowed_attachments);

	mutex_lock(&dev->client_lock);
	ret = adf_obj_copy_custom_data_to_user(&dev->base, arg->custom_data,
			&data.custom_data_size);
	mutex_unlock(&dev->client_lock);

	if (ret < 0)
		goto done;

	ret = adf_copy_attachment_list_to_user(arg->attachments,
			data.n_attachments, attach, n_attach);
	if (ret < 0)
		goto done;

	ret = adf_copy_attachment_list_to_user(arg->allowed_attachments,
			data.n_allowed_attachments, allowed_attach,
			n_allowed_attach);
	if (ret < 0)
		goto done;

	data.n_attachments = n_attach;
	data.n_allowed_attachments = n_allowed_attach;

	if (copy_to_user(arg, &data, sizeof(data)))
		ret = -EFAULT;

done:
	kfree(allowed_attach);
	kfree(attach);
	return ret;
}

static int adf_device_handle_attachment(struct adf_device *dev,
		struct adf_attachment_config __user *arg, bool attach)
{
	struct adf_attachment_config data;
	struct adf_overlay_engine *eng;
	struct adf_interface *intf;

	if (copy_from_user(&data, arg, sizeof(data)))
		return -EFAULT;

	eng = idr_find(&dev->overlay_engines, data.overlay_engine);
	if (!eng) {
		dev_err(&dev->base.dev, "invalid overlay engine id %u\n",
				data.overlay_engine);
		return -EINVAL;
	}

	intf = idr_find(&dev->interfaces, data.interface);
	if (!intf) {
		dev_err(&dev->base.dev, "invalid interface id %u\n",
				data.interface);
		return -EINVAL;
	}

	if (attach)
		return adf_device_attach(dev, eng, intf);
	else
		return adf_device_detach(dev, eng, intf);
}

static int adf_intf_set_mode(struct adf_interface *intf,
		struct drm_mode_modeinfo __user *arg)
{
	struct drm_mode_modeinfo mode;

	if (copy_from_user(&mode, arg, sizeof(mode)))
		return -EFAULT;

	return adf_interface_set_mode(intf, &mode);
}

static int adf_intf_get_data(struct adf_interface *intf,
		struct adf_interface_data __user *arg)
{
	struct adf_device *dev = adf_interface_parent(intf);
	struct adf_interface_data data;
	struct drm_mode_modeinfo *modelist;
	size_t modelist_size;
	int err;
	int ret = 0;
	unsigned long flags;

	if (copy_from_user(&data, arg, sizeof(data)))
		return -EFAULT;

	strlcpy(data.name, intf->base.name, sizeof(data.name));

	data.type = intf->type;
	data.id = intf->idx;
	data.flags = intf->flags;

	err = adf_interface_get_screen_size(intf, &data.width_mm,
			&data.height_mm);
	if (err < 0) {
		data.width_mm = 0;
		data.height_mm = 0;
	}

	modelist = kmalloc(sizeof(modelist[0]) * ADF_MAX_MODES, GFP_KERNEL);
	if (!modelist)
		return -ENOMEM;

	mutex_lock(&dev->client_lock);
	read_lock_irqsave(&intf->hotplug_modelist_lock, flags);
	data.hotplug_detect = intf->hotplug_detect;
	modelist_size = min(data.n_available_modes, intf->n_modes) *
			sizeof(intf->modelist[0]);
	memcpy(modelist, intf->modelist, modelist_size);
	data.n_available_modes = intf->n_modes;
	read_unlock_irqrestore(&intf->hotplug_modelist_lock, flags);

	if (copy_to_user(arg->available_modes, modelist, modelist_size)) {
		ret = -EFAULT;
		goto done;
	}

	data.dpms_state = intf->dpms_state;
	memcpy(&data.current_mode, &intf->current_mode,
			sizeof(intf->current_mode));

	ret = adf_obj_copy_custom_data_to_user(&intf->base, arg->custom_data,
			&data.custom_data_size);
done:
	mutex_unlock(&dev->client_lock);
	kfree(modelist);

	if (ret < 0)
		return ret;

	if (copy_to_user(arg, &data, sizeof(data)))
		ret = -EFAULT;

	return ret;
}

static inline long adf_obj_custom_ioctl(struct adf_obj *obj, unsigned int cmd,
		unsigned long arg)
{
	if (obj->ops && obj->ops->ioctl)
		return obj->ops->ioctl(obj, cmd, arg);
	return -ENOTTY;
}

static long adf_overlay_engine_ioctl(struct adf_overlay_engine *eng,
		struct adf_file *file, unsigned int cmd, unsigned long arg)
{
	switch (cmd) {
	case ADF_SET_EVENT:
		return adf_obj_set_event(&eng->base, file,
				(struct adf_set_event __user *)arg);

	case ADF_GET_OVERLAY_ENGINE_DATA:
		return adf_eng_get_data(eng,
			(struct adf_overlay_engine_data __user *)arg);

	case ADF_BLANK:
	case ADF_POST_CONFIG:
	case ADF_SET_MODE:
	case ADF_GET_DEVICE_DATA:
	case ADF_GET_INTERFACE_DATA:
	case ADF_SIMPLE_POST_CONFIG:
	case ADF_SIMPLE_BUFFER_ALLOC:
	case ADF_ATTACH:
	case ADF_DETACH:
		return -EINVAL;

	default:
		return adf_obj_custom_ioctl(&eng->base, cmd, arg);
	}
}

static long adf_interface_ioctl(struct adf_interface *intf,
		struct adf_file *file, unsigned int cmd, unsigned long arg)
{
	switch (cmd) {
	case ADF_SET_EVENT:
		return adf_obj_set_event(&intf->base, file,
				(struct adf_set_event __user *)arg);

	case ADF_BLANK:
		return adf_interface_blank(intf, arg);

	case ADF_SET_MODE:
		return adf_intf_set_mode(intf,
				(struct drm_mode_modeinfo __user *)arg);

	case ADF_GET_INTERFACE_DATA:
		return adf_intf_get_data(intf,
				(struct adf_interface_data __user *)arg);

	case ADF_SIMPLE_POST_CONFIG:
		return adf_intf_simple_post_config(intf,
				(struct adf_simple_post_config __user *)arg);

	case ADF_SIMPLE_BUFFER_ALLOC:
		return adf_intf_simple_buffer_alloc(intf,
				(struct adf_simple_buffer_alloc __user *)arg);

	case ADF_POST_CONFIG:
	case ADF_GET_DEVICE_DATA:
	case ADF_GET_OVERLAY_ENGINE_DATA:
	case ADF_ATTACH:
	case ADF_DETACH:
		return -EINVAL;

	default:
		return adf_obj_custom_ioctl(&intf->base, cmd, arg);
	}
}

static long adf_device_ioctl(struct adf_device *dev, struct adf_file *file,
		unsigned int cmd, unsigned long arg)
{
	switch (cmd) {
	case ADF_SET_EVENT:
		return adf_obj_set_event(&dev->base, file,
				(struct adf_set_event __user *)arg);

	case ADF_POST_CONFIG:
		return adf_device_post_config(dev,
				(struct adf_post_config __user *)arg);

	case ADF_GET_DEVICE_DATA:
		return adf_device_get_data(dev,
				(struct adf_device_data __user *)arg);

	case ADF_ATTACH:
		return adf_device_handle_attachment(dev,
				(struct adf_attachment_config __user *)arg,
				true);

	case ADF_DETACH:
		return adf_device_handle_attachment(dev,
				(struct adf_attachment_config __user *)arg,
				false);

	case ADF_BLANK:
	case ADF_SET_MODE:
	case ADF_GET_INTERFACE_DATA:
	case ADF_GET_OVERLAY_ENGINE_DATA:
	case ADF_SIMPLE_POST_CONFIG:
	case ADF_SIMPLE_BUFFER_ALLOC:
		return -EINVAL;

	default:
		return adf_obj_custom_ioctl(&dev->base, cmd, arg);
	}
}

static int adf_file_open(struct inode *inode, struct file *file)
{
	struct adf_obj *obj;
	struct adf_file *fpriv = NULL;
	unsigned long flags;
	int ret = 0;

	obj = adf_obj_sysfs_find(iminor(inode));
	if (!obj)
		return -ENODEV;

	dev_dbg(&obj->dev, "opening %s\n", dev_name(&obj->dev));

	if (!try_module_get(obj->parent->ops->owner)) {
		dev_err(&obj->dev, "getting owner module failed\n");
		return -ENODEV;
	}

	fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
	if (!fpriv) {
		ret = -ENOMEM;
		goto done;
	}

	INIT_LIST_HEAD(&fpriv->head);
	fpriv->obj = obj;
	init_waitqueue_head(&fpriv->event_wait);

	file->private_data = fpriv;

	if (obj->ops && obj->ops->open) {
		ret = obj->ops->open(obj, inode, file);
		if (ret < 0)
			goto done;
	}

	spin_lock_irqsave(&obj->file_lock, flags);
	list_add_tail(&fpriv->head, &obj->file_list);
	spin_unlock_irqrestore(&obj->file_lock, flags);

done:
	if (ret < 0) {
		kfree(fpriv);
		module_put(obj->parent->ops->owner);
	}
	return ret;
}

static int adf_file_release(struct inode *inode, struct file *file)
{
	struct adf_file *fpriv = file->private_data;
	struct adf_obj *obj = fpriv->obj;
	enum adf_event_type event_type;
	unsigned long flags;

	if (obj->ops && obj->ops->release)
		obj->ops->release(obj, inode, file);

	spin_lock_irqsave(&obj->file_lock, flags);
	list_del(&fpriv->head);
	spin_unlock_irqrestore(&obj->file_lock, flags);

	for_each_set_bit(event_type, fpriv->event_subscriptions,
			ADF_EVENT_TYPE_MAX) {
		adf_event_put(obj, event_type);
	}

	kfree(fpriv);
	module_put(obj->parent->ops->owner);

	dev_dbg(&obj->dev, "released %s\n", dev_name(&obj->dev));
	return 0;
}

long adf_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	struct adf_file *fpriv = file->private_data;
	struct adf_obj *obj = fpriv->obj;
	long ret = -EINVAL;

	dev_dbg(&obj->dev, "%s ioctl %u\n", dev_name(&obj->dev), _IOC_NR(cmd));

	switch (obj->type) {
	case ADF_OBJ_OVERLAY_ENGINE:
		ret = adf_overlay_engine_ioctl(adf_obj_to_overlay_engine(obj),
				fpriv, cmd, arg);
		break;

	case ADF_OBJ_INTERFACE:
		ret = adf_interface_ioctl(adf_obj_to_interface(obj), fpriv, cmd,
				arg);
		break;

	case ADF_OBJ_DEVICE:
		ret = adf_device_ioctl(adf_obj_to_device(obj), fpriv, cmd, arg);
		break;
	}

	return ret;
}

static inline bool adf_file_event_available(struct adf_file *fpriv)
{
	int head = fpriv->event_head;
	int tail = fpriv->event_tail;
	return CIRC_CNT(head, tail, sizeof(fpriv->event_buf)) != 0;
}

void adf_file_queue_event(struct adf_file *fpriv, struct adf_event *event)
{
	int head = fpriv->event_head;
	int tail = fpriv->event_tail;
	size_t space = CIRC_SPACE(head, tail, sizeof(fpriv->event_buf));
	size_t space_to_end =
			CIRC_SPACE_TO_END(head, tail, sizeof(fpriv->event_buf));

	if (space < event->length) {
		dev_dbg(&fpriv->obj->dev,
				"insufficient buffer space for event %u\n",
				event->type);
		return;
	}

	if (space_to_end >= event->length) {
		memcpy(fpriv->event_buf + head, event, event->length);
	} else {
		memcpy(fpriv->event_buf + head, event, space_to_end);
		memcpy(fpriv->event_buf, (u8 *)event + space_to_end,
				event->length - space_to_end);
	}

	smp_wmb();
	fpriv->event_head = (fpriv->event_head + event->length) &
			(sizeof(fpriv->event_buf) - 1);
	wake_up_interruptible_all(&fpriv->event_wait);
}

static ssize_t adf_file_copy_to_user(struct adf_file *fpriv,
		char __user *buffer, size_t buffer_size)
{
	int head, tail;
	u8 *event_buf;
	size_t cnt, cnt_to_end, copy_size = 0;
	ssize_t ret = 0;
	unsigned long flags;

	event_buf = kmalloc(min(buffer_size, sizeof(fpriv->event_buf)),
			GFP_KERNEL);
	if (!event_buf)
		return -ENOMEM;

	spin_lock_irqsave(&fpriv->obj->file_lock, flags);

	if (!adf_file_event_available(fpriv))
		goto out;

	head = fpriv->event_head;
	tail = fpriv->event_tail;

	cnt = CIRC_CNT(head, tail, sizeof(fpriv->event_buf));
	cnt_to_end = CIRC_CNT_TO_END(head, tail, sizeof(fpriv->event_buf));
	copy_size = min(buffer_size, cnt);

	if (cnt_to_end >= copy_size) {
		memcpy(event_buf, fpriv->event_buf + tail, copy_size);
	} else {
		memcpy(event_buf, fpriv->event_buf + tail, cnt_to_end);
		memcpy(event_buf + cnt_to_end, fpriv->event_buf,
				copy_size - cnt_to_end);
	}

	fpriv->event_tail = (fpriv->event_tail + copy_size) &
			(sizeof(fpriv->event_buf) - 1);

out:
	spin_unlock_irqrestore(&fpriv->obj->file_lock, flags);
	if (copy_size) {
		if (copy_to_user(buffer, event_buf, copy_size))
			ret = -EFAULT;
		else
			ret = copy_size;
	}
	kfree(event_buf);
	return ret;
}

ssize_t adf_file_read(struct file *filp, char __user *buffer,
		 size_t count, loff_t *offset)
{
	struct adf_file *fpriv = filp->private_data;
	int err;

	err = wait_event_interruptible(fpriv->event_wait,
			adf_file_event_available(fpriv));
	if (err < 0)
		return err;

	return adf_file_copy_to_user(fpriv, buffer, count);
}

unsigned int adf_file_poll(struct file *filp, struct poll_table_struct *wait)
{
	struct adf_file *fpriv = filp->private_data;
	unsigned int mask = 0;

	poll_wait(filp, &fpriv->event_wait, wait);

	if (adf_file_event_available(fpriv))
		mask |= POLLIN | POLLRDNORM;

	return mask;
}

const struct file_operations adf_fops = {
	.owner = THIS_MODULE,
	.unlocked_ioctl = adf_file_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl = adf_file_compat_ioctl,
#endif
	.open = adf_file_open,
	.release = adf_file_release,
	.llseek = default_llseek,
	.read = adf_file_read,
	.poll = adf_file_poll,
};
