/*
 * Copyright (C) 2008 Google, Inc.
 * Copyright (c) 2009, The Linux Foundation. All rights reserved.
 * Author: Iliyan Malchev <ibm@android.com>
 *
 * 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/cdev.h>
#include <linux/fs.h>
#include <linux/list.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/uaccess.h>
#include <linux/msm_adsp.h>
#include <linux/android_pmem.h>
#include <linux/export.h>
#include "adsp.h"
#include <mach/debug_mm.h>
#include <linux/slab.h>

struct adsp_pmem_info {
	int fd;
	void *vaddr;
};

struct adsp_pmem_region {
	struct hlist_node list;
	void *vaddr;
	unsigned long paddr;
	unsigned long kvaddr;
	unsigned long len;
	struct file *file;
};

struct adsp_device {
	struct msm_adsp_module *module;

	spinlock_t event_queue_lock;
	wait_queue_head_t event_wait;
	struct list_head event_queue;
	int abort;

	const char *name;
	struct device *device;
	struct cdev cdev;
};

static struct adsp_device *inode_to_device(struct inode *inode);

#define __CONTAINS(r, v, l) ({					\
	typeof(r) __r = r;					\
	typeof(v) __v = v;					\
	typeof(v) __e = __v + l;				\
	int res = __v >= __r->vaddr && 				\
		__e <= __r->vaddr + __r->len;			\
	res;							\
})

#define CONTAINS(r1, r2) ({					\
	typeof(r2) __r2 = r2;					\
	__CONTAINS(r1, __r2->vaddr, __r2->len);			\
})

#define IN_RANGE(r, v) ({					\
	typeof(r) __r = r;					\
	typeof(v) __vv = v;					\
	int res = ((__vv >= __r->vaddr) &&			\
		(__vv < (__r->vaddr + __r->len)));		\
	res;							\
})

#define OVERLAPS(r1, r2) ({					\
	typeof(r1) __r1 = r1;					\
	typeof(r2) __r2 = r2;					\
	typeof(__r2->vaddr) __v = __r2->vaddr;			\
	typeof(__v) __e = __v + __r2->len - 1;			\
	int res = (IN_RANGE(__r1, __v) || IN_RANGE(__r1, __e));	\
	res;							\
})

static int adsp_pmem_check(struct msm_adsp_module *module,
		void *vaddr, unsigned long len)
{
	struct adsp_pmem_region *region_elt;
	struct hlist_node *node;
	struct adsp_pmem_region t = { .vaddr = vaddr, .len = len };

	hlist_for_each_entry(region_elt, node, &module->pmem_regions, list) {
		if (CONTAINS(region_elt, &t) || CONTAINS(&t, region_elt) ||
		    OVERLAPS(region_elt, &t)) {
			MM_ERR("module %s:"
				" region (vaddr %p len %ld)"
				" clashes with registered region"
				" (vaddr %p paddr %p len %ld)\n",
				module->name,
				vaddr, len,
				region_elt->vaddr,
				(void *)region_elt->paddr,
				region_elt->len);
			return -EINVAL;
		}
	}

	return 0;
}

static int adsp_pmem_add(struct msm_adsp_module *module,
			 struct adsp_pmem_info *info)
{
	unsigned long paddr, kvaddr, len;
	struct file *file;
	struct adsp_pmem_region *region;
	int rc = -EINVAL;

	mutex_lock(&module->pmem_regions_lock);
	region = kmalloc(sizeof(*region), GFP_KERNEL);
	if (!region) {
		rc = -ENOMEM;
		goto end;
	}
	INIT_HLIST_NODE(&region->list);
	if (get_pmem_file(info->fd, &paddr, &kvaddr, &len, &file)) {
		kfree(region);
		goto end;
	}

	rc = adsp_pmem_check(module, info->vaddr, len);
	if (rc < 0) {
		put_pmem_file(file);
		kfree(region);
		goto end;
	}

	region->vaddr = info->vaddr;
	region->paddr = paddr;
	region->kvaddr = kvaddr;
	region->len = len;
	region->file = file;

	hlist_add_head(&region->list, &module->pmem_regions);
end:
	mutex_unlock(&module->pmem_regions_lock);
	return rc;
}

static int adsp_pmem_lookup_vaddr(struct msm_adsp_module *module, void **addr,
		     unsigned long len, struct adsp_pmem_region **region)
{
	struct hlist_node *node;
	void *vaddr = *addr;
	struct adsp_pmem_region *region_elt;

	int match_count = 0;

	*region = NULL;

	/* returns physical address or zero */
	hlist_for_each_entry(region_elt, node, &module->pmem_regions, list) {
		if (vaddr >= region_elt->vaddr &&
		    vaddr < region_elt->vaddr + region_elt->len &&
		    vaddr + len <= region_elt->vaddr + region_elt->len) {
			/* offset since we could pass vaddr inside a registerd
			 * pmem buffer
			 */

			match_count++;
			if (!*region)
				*region = region_elt;
		}
	}

	if (match_count > 1) {
		MM_ERR("module %s: "
			"multiple hits for vaddr %p, len %ld\n",
			module->name, vaddr, len);
		hlist_for_each_entry(region_elt, node,
				&module->pmem_regions, list) {
			if (vaddr >= region_elt->vaddr &&
			    vaddr < region_elt->vaddr + region_elt->len &&
			    vaddr + len <= region_elt->vaddr + region_elt->len)
				MM_ERR("%p, %ld --> %p\n",
					region_elt->vaddr,
					region_elt->len,
					(void *)region_elt->paddr);
		}
	}

	return *region ? 0 : -1;
}

int adsp_pmem_fixup_kvaddr(struct msm_adsp_module *module, void **addr,
			   unsigned long *kvaddr, unsigned long len)
{
	struct adsp_pmem_region *region;
	void *vaddr = *addr;
	unsigned long *paddr = (unsigned long *)addr;
	int ret;

	ret = adsp_pmem_lookup_vaddr(module, addr, len, &region);
	if (ret) {
		MM_ERR("not patching %s (paddr & kvaddr),"
			" lookup (%p, %ld) failed\n",
			module->name, vaddr, len);
		return ret;
	}
	*paddr = region->paddr + (vaddr - region->vaddr);
	*kvaddr = region->kvaddr + (vaddr - region->vaddr);
	return 0;
}

int adsp_pmem_fixup(struct msm_adsp_module *module, void **addr,
		    unsigned long len)
{
	struct adsp_pmem_region *region;
	void *vaddr = *addr;
	unsigned long *paddr = (unsigned long *)addr;
	int ret;

	ret = adsp_pmem_lookup_vaddr(module, addr, len, &region);
	if (ret) {
		MM_ERR("not patching %s, lookup (%p, %ld) failed\n",
			module->name, vaddr, len);
		return ret;
	}

	*paddr = region->paddr + (vaddr - region->vaddr);
	return 0;
}

static int adsp_verify_cmd(struct msm_adsp_module *module,
			   unsigned int queue_id, void *cmd_data,
			   size_t cmd_size)
{
	/* call the per module verifier */
	if (module->verify_cmd)
		return module->verify_cmd(module, queue_id, cmd_data,
					     cmd_size);
	else
		MM_INFO("no packet verifying function "
				 "for task %s\n", module->name);
	return 0;
}

static long adsp_write_cmd(struct adsp_device *adev, void __user *arg)
{
	struct adsp_command_t cmd;
	unsigned char buf[256];
	void *cmd_data;
	long rc;

	if (copy_from_user(&cmd, (void __user *)arg, sizeof(cmd)))
		return -EFAULT;

	if (cmd.len > 256) {
		cmd_data = kmalloc(cmd.len, GFP_USER);
		if (!cmd_data)
			return -ENOMEM;
	} else {
		cmd_data = buf;
	}

	if (copy_from_user(cmd_data, (void __user *)(cmd.data), cmd.len)) {
		rc = -EFAULT;
		goto end;
	}

	mutex_lock(&adev->module->pmem_regions_lock);
	if (adsp_verify_cmd(adev->module, cmd.queue, cmd_data, cmd.len)) {
		MM_ERR("module %s: verify failed.\n", adev->module->name);
		rc = -EINVAL;
		goto end;
	}
	rc = msm_adsp_write(adev->module, cmd.queue, cmd_data, cmd.len);
end:
	mutex_unlock(&adev->module->pmem_regions_lock);

	if (cmd.len > 256)
		kfree(cmd_data);

	return rc;
}

static int adsp_events_pending(struct adsp_device *adev)
{
	unsigned long flags;
	int yes;
	spin_lock_irqsave(&adev->event_queue_lock, flags);
	yes = !list_empty(&adev->event_queue);
	spin_unlock_irqrestore(&adev->event_queue_lock, flags);
	return yes || adev->abort;
}

static int adsp_pmem_lookup_paddr(struct msm_adsp_module *module, void **addr,
		     struct adsp_pmem_region **region)
{
	struct hlist_node *node;
	unsigned long paddr = (unsigned long)(*addr);
	struct adsp_pmem_region *region_elt;

	hlist_for_each_entry(region_elt, node, &module->pmem_regions, list) {
		if (paddr >= region_elt->paddr &&
		    paddr < region_elt->paddr + region_elt->len) {
			*region = region_elt;
			return 0;
		}
	}
	return -1;
}

int adsp_pmem_paddr_fixup(struct msm_adsp_module *module, void **addr)
{
	struct adsp_pmem_region *region;
	unsigned long paddr = (unsigned long)(*addr);
	unsigned long *vaddr = (unsigned long *)addr;
	int ret;

	ret = adsp_pmem_lookup_paddr(module, addr, &region);
	if (ret) {
		MM_ERR("not patching %s, paddr %p lookup failed\n",
			module->name, vaddr);
		return ret;
	}

	*vaddr = (unsigned long)region->vaddr + (paddr - region->paddr);
	return 0;
}

static int adsp_patch_event(struct msm_adsp_module *module,
				struct adsp_event *event)
{
	/* call the per-module msg verifier */
	if (module->patch_event)
		return module->patch_event(module, event);
	return 0;
}

static long adsp_get_event(struct adsp_device *adev, void __user *arg)
{
	unsigned long flags;
	struct adsp_event *data = NULL;
	struct adsp_event_t evt;
	int timeout;
	long rc = 0;

	if (copy_from_user(&evt, arg, sizeof(struct adsp_event_t)))
		return -EFAULT;

	timeout = (int)evt.timeout_ms;

	if (timeout > 0) {
		rc = wait_event_interruptible_timeout(
			adev->event_wait, adsp_events_pending(adev),
			msecs_to_jiffies(timeout));
		if (rc == 0)
			return -ETIMEDOUT;
	} else {
		rc = wait_event_interruptible(
			adev->event_wait, adsp_events_pending(adev));
	}
	if (rc < 0)
		return rc;

	if (adev->abort)
		return -ENODEV;

	spin_lock_irqsave(&adev->event_queue_lock, flags);
	if (!list_empty(&adev->event_queue)) {
		data = list_first_entry(&adev->event_queue,
					struct adsp_event, list);
		list_del(&data->list);
	}
	spin_unlock_irqrestore(&adev->event_queue_lock, flags);

	if (!data)
		return -EAGAIN;

	/* DSP messages are type 0; they may contain physical addresses */
	if (data->type == 0)
		adsp_patch_event(adev->module, data);

	/* map adsp_event --> adsp_event_t */
	if (evt.len < data->size) {
		rc = -ETOOSMALL;
		goto end;
	}
	if (data->msg_id != EVENT_MSG_ID) {
		if (copy_to_user((void *)(evt.data), data->data.msg16,
					data->size)) {
			rc = -EFAULT;
			goto end;
	}
	} else {
		if (copy_to_user((void *)(evt.data), data->data.msg32,
					data->size)) {
			rc = -EFAULT;
			goto end;
		}
	}

	evt.type = data->type; /* 0 --> from aDSP, 1 --> from ARM9 */
	evt.msg_id = data->msg_id;
	evt.flags = data->is16;
	evt.len = data->size;
	if (copy_to_user(arg, &evt, sizeof(evt)))
		rc = -EFAULT;
end:
	kfree(data);
	return rc;
}

static int adsp_pmem_del(struct msm_adsp_module *module)
{
	struct hlist_node *node, *tmp;
	struct adsp_pmem_region *region;

	mutex_lock(&module->pmem_regions_lock);
	hlist_for_each_safe(node, tmp, &module->pmem_regions) {
		region = hlist_entry(node, struct adsp_pmem_region, list);
		hlist_del(node);
		put_pmem_file(region->file);
		kfree(region);
	}
	mutex_unlock(&module->pmem_regions_lock);
	BUG_ON(!hlist_empty(&module->pmem_regions));

	return 0;
}

static long adsp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	struct adsp_device *adev = filp->private_data;

	switch (cmd) {
	case ADSP_IOCTL_ENABLE:
		return msm_adsp_enable(adev->module);

	case ADSP_IOCTL_DISABLE:
		return msm_adsp_disable(adev->module);

	case ADSP_IOCTL_DISABLE_EVENT_RSP:
		return msm_adsp_disable_event_rsp(adev->module);

	case ADSP_IOCTL_DISABLE_ACK:
		MM_ERR("ADSP_IOCTL_DISABLE_ACK is not implemented\n");
		break;

	case ADSP_IOCTL_WRITE_COMMAND:
		return adsp_write_cmd(adev, (void __user *) arg);

	case ADSP_IOCTL_GET_EVENT:
		return adsp_get_event(adev, (void __user *) arg);

	case ADSP_IOCTL_SET_CLKRATE: {
		unsigned long clk_rate;
		if (copy_from_user(&clk_rate, (void *) arg, sizeof(clk_rate)))
			return -EFAULT;
		return adsp_set_clkrate(adev->module, clk_rate);
	}

	case ADSP_IOCTL_REGISTER_PMEM: {
		struct adsp_pmem_info info;
		if (copy_from_user(&info, (void *) arg, sizeof(info)))
			return -EFAULT;
		return adsp_pmem_add(adev->module, &info);
	}

	case ADSP_IOCTL_ABORT_EVENT_READ:
		adev->abort = 1;
		wake_up(&adev->event_wait);
		break;

	case ADSP_IOCTL_UNREGISTER_PMEM:
		return adsp_pmem_del(adev->module);

	default:
		break;
	}
	return -EINVAL;
}

static int adsp_release(struct inode *inode, struct file *filp)
{
	struct adsp_device *adev = filp->private_data;
	struct msm_adsp_module *module = adev->module;
	int rc = 0;

	MM_INFO("release '%s'\n", adev->name);

	/* clear module before putting it to avoid race with open() */
	adev->module = NULL;

	rc = adsp_pmem_del(module);

	msm_adsp_put(module);
	return rc;
}

static void adsp_event(void *driver_data, unsigned id, size_t len,
		       void (*getevent)(void *ptr, size_t len))
{
	struct adsp_device *adev = driver_data;
	struct adsp_event *event;
	unsigned long flags;

	if (len > ADSP_EVENT_MAX_SIZE) {
		MM_ERR("event too large (%d bytes)\n", len);
		return;
	}

	event = kmalloc(sizeof(*event), GFP_ATOMIC);
	if (!event) {
		MM_ERR("cannot allocate buffer\n");
		return;
	}

	if (id != EVENT_MSG_ID) {
		event->type = 0;
		event->is16 = 0;
		event->msg_id = id;
		event->size = len;

		getevent(event->data.msg16, len);
	} else {
		event->type = 1;
		event->is16 = 1;
		event->msg_id = id;
		event->size = len;
		getevent(event->data.msg32, len);
	}

	spin_lock_irqsave(&adev->event_queue_lock, flags);
	list_add_tail(&event->list, &adev->event_queue);
	spin_unlock_irqrestore(&adev->event_queue_lock, flags);
	wake_up(&adev->event_wait);
}

static struct msm_adsp_ops adsp_ops = {
	.event = adsp_event,
};

static int adsp_open(struct inode *inode, struct file *filp)
{
	struct adsp_device *adev;
	int rc;

	rc = nonseekable_open(inode, filp);
	if (rc < 0)
		return rc;

	adev = inode_to_device(inode);
	if (!adev)
		return -ENODEV;

	MM_INFO("open '%s'\n", adev->name);

	rc = msm_adsp_get(adev->name, &adev->module, &adsp_ops, adev);
	if (rc)
		return rc;

	MM_INFO("opened module '%s' adev %p\n", adev->name, adev);
	filp->private_data = adev;
	adev->abort = 0;
	INIT_HLIST_HEAD(&adev->module->pmem_regions);
	mutex_init(&adev->module->pmem_regions_lock);

	return 0;
}

static unsigned adsp_device_count;
static struct adsp_device *adsp_devices;

static struct adsp_device *inode_to_device(struct inode *inode)
{
	unsigned n = MINOR(inode->i_rdev);
	if (n < adsp_device_count) {
		if (adsp_devices[n].device)
			return adsp_devices + n;
	}
	return NULL;
}

static dev_t adsp_devno;
static struct class *adsp_class;

static const struct file_operations adsp_fops = {
	.owner = THIS_MODULE,
	.open = adsp_open,
	.unlocked_ioctl = adsp_ioctl,
	.release = adsp_release,
};

static void adsp_create(struct adsp_device *adev, const char *name,
			struct device *parent, dev_t devt)
{
	struct device *dev;
	int rc;

	dev = device_create(adsp_class, parent, devt, "%s", name);
	if (IS_ERR(dev))
		return;

	init_waitqueue_head(&adev->event_wait);
	INIT_LIST_HEAD(&adev->event_queue);
	spin_lock_init(&adev->event_queue_lock);

	cdev_init(&adev->cdev, &adsp_fops);
	adev->cdev.owner = THIS_MODULE;

	rc = cdev_add(&adev->cdev, devt, 1);
	if (rc < 0) {
		device_destroy(adsp_class, devt);
	} else {
		adev->device = dev;
		adev->name = name;
	}
}

void msm_adsp_publish_cdevs(struct msm_adsp_module *modules, unsigned n)
{
	int rc;

	adsp_devices = kzalloc(sizeof(struct adsp_device) * n, GFP_KERNEL);
	if (!adsp_devices)
		return;

	adsp_class = class_create(THIS_MODULE, "adsp");
	if (IS_ERR(adsp_class))
		goto fail_create_class;

	rc = alloc_chrdev_region(&adsp_devno, 0, n, "adsp");
	if (rc < 0)
		goto fail_alloc_region;

	adsp_device_count = n;
	for (n = 0; n < adsp_device_count; n++) {
		adsp_create(adsp_devices + n,
			    modules[n].name, &modules[n].pdev.dev,
			    MKDEV(MAJOR(adsp_devno), n));
	}

	return;

fail_alloc_region:
	class_unregister(adsp_class);
fail_create_class:
	kfree(adsp_devices);
}
