/*
 * 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, data.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(data.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 %d 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 %d 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;
	struct adf_post_config data;
	size_t i;
	void *custom_data = NULL;
	int ret = 0;

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

	complete_fence_fd = get_unused_fd_flags(O_CLOEXEC);
	if (complete_fence_fd < 0)
		return complete_fence_fd;

	if (data.n_interfaces > ADF_MAX_INTERFACES) {
		ret = -EINVAL;
		goto err_get_user;
	}

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

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

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

	for (i = 0; i < data.n_interfaces; i++) {
		u32 intf_id;
		if (get_user(intf_id, &data.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 (data.n_bufs) {
		bufs = kzalloc(sizeof(bufs[0]) * data.n_bufs, GFP_KERNEL);
		if (!bufs) {
			ret = -ENOMEM;
			goto err_get_user;
		}
	}

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

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

		if (copy_from_user(custom_data, data.custom_data,
				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, data.n_interfaces,
			bufs, data.n_bufs, custom_data, 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 < data.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_flags(O_CLOEXEC);
	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, data.custom_data,
			&data.custom_data_size);
	mutex_unlock(&dev->client_lock);

	if (ret < 0)
		goto done;

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

	ret = adf_copy_attachment_list_to_user(data.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(data.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, data.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,
};
