/*
 * Driver for inter-cell links using the shared-buffer transport.
 *
 * Copyright (c) 2016 Cog Systems Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by
 * the Free Software Foundation.
 */
#include <linux/atomic.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/ioctl.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/poll.h>
#include <linux/rwsem.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/version.h>
#include <microvisor/microvisor.h>
#include <uapi/linux/okl4-link-shbuf.h>

static const char DEVICE_NAME[] = "okl4_link_shbuf";

/* Created devices will appear as /dev/<DEV_PREFIX><name> */
static const char DEV_PREFIX[] = "okl4-";

static const struct of_device_id okl4_link_shbuf_match[] = {
	{
		.compatible = "okl,microvisor-link-shbuf",
	},
	{},
};
MODULE_DEVICE_TABLE(of, okl4_link_shbuf_match);

static struct class *link_shbuf_class;
static dev_t link_shbuf_dev;

/* A lock used to protect access to link_shbuf_dev */
static spinlock_t device_number_allocate;

/* Sentinel values for indicating missing communication channels */
static const u32 NO_OUTGOING_IRQ = 0;
static const int NO_INCOMING_IRQ = -1;

/* Private data for this driver */
struct link_shbuf_data {

	/* Outgoing vIRQ */
	u32 virqline;

	/* Incoming vIRQ */
	int virq;
	atomic64_t virq_payload;
	bool virq_pending;
	wait_queue_head_t virq_wq;

	/* Shared memory region */
	void *base;
	fmode_t permissions;
	struct resource buffer;

	/* Device data */
	dev_t devt;
	struct device *dev;
	struct cdev cdev;

};

static bool link_shbuf_data_invariant(const struct link_shbuf_data *priv)
{
	if (!priv)
		return false;

	if (!priv->base || (uintptr_t)priv->base % PAGE_SIZE != 0)
		return false;

	if (resource_size(&priv->buffer) == 0)
		return false;

	if (!priv->dev)
		return false;

	return true;
}

static bool link_shbuf_valid_access(size_t size, loff_t pos, size_t count)
{
	return pos < size && count <= size && size - count >= pos;
}

static ssize_t link_shbuf_read(struct file *file, char __user *buffer,
		size_t count, loff_t *ppos)
{
	long remaining;
	const struct link_shbuf_data *priv;

	/* The file should have been opened with read access to reach here */
	if (WARN_ON(!(file->f_mode & FMODE_READ)))
		return -EINVAL;

	priv = file->private_data;
	if (WARN_ON(!link_shbuf_data_invariant(priv)))
		return -EINVAL;

	if (!link_shbuf_valid_access(resource_size(&priv->buffer), *ppos, count))
		return -EINVAL;

	remaining = copy_to_user(buffer, priv->base + *ppos, count);
	*ppos += count - remaining;
	return count - remaining;
}

static ssize_t link_shbuf_write(struct file *file, const char __user *buffer,
		size_t count, loff_t *ppos)
{
	long remaining;
	const struct link_shbuf_data *priv;

	/* The file should have been opened with write access to reach here */
	if (WARN_ON(!(file->f_mode & FMODE_WRITE)))
		return -EINVAL;

	priv = file->private_data;
	if (WARN_ON(!link_shbuf_data_invariant(priv)))
		return -EINVAL;

	if (!link_shbuf_valid_access(resource_size(&priv->buffer), *ppos, count))
		return -EINVAL;

	remaining = copy_from_user(priv->base + *ppos, buffer, count);
	*ppos += count - remaining;
	return count - remaining;
}

static unsigned int link_shbuf_poll(struct file *file, poll_table *table)
{
	struct link_shbuf_data *priv;
	unsigned int mask;

	priv = file->private_data;
	if (WARN_ON(!link_shbuf_data_invariant(priv)))
		return POLLERR;

	poll_wait(file, &priv->virq_wq, table);

	/* The shared memory is always considered ready for reading and writing. */
	mask = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM;

	if (priv->virq_pending)
		mask |= POLLPRI;

	return mask;
}

static long link_shbuf_ioctl_irq_tx(const struct link_shbuf_data *priv,
		unsigned long arg)
{
	okl4_error_t err;
	u64 payload;
	const u64 __user *user_arg = (const u64 __user*)arg;

	if (priv->virqline == NO_OUTGOING_IRQ)
		return -EINVAL;

#if defined(CONFIG_ARM) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0))
	if (copy_from_user(&payload, user_arg, sizeof(payload)))
                return -EFAULT;
#else
	if (get_user(payload, user_arg))
		return -EFAULT;
#endif

	err = _okl4_sys_vinterrupt_raise(priv->virqline, payload);
	if (WARN_ON(err != OKL4_OK))
		return -EINVAL;

	return 0;
}

static long link_shbuf_ioctl_irq_clr(struct link_shbuf_data *priv,
		unsigned long arg)
{
	u64 payload;
	u64 __user *user_arg = (u64 __user*)arg;

	/*
	 * Check validity of the user pointer before clearing the interrupt to avoid
	 * races involved with having to undo the latter.
	 */
	if (!access_ok(VERIFY_WRITE, user_arg, sizeof(*user_arg)))
		return -EFAULT;

	/*
	 * Note that the clearing of the pending flag can race with the setting of
	 * this flag in the IRQ handler. It is up to the user to coordinate these
	 * actions.
	 */
	priv->virq_pending = false;
	smp_rmb();
	payload = atomic64_xchg(&priv->virq_payload, 0);

	/* We've already checked that this access is OK, so no need for put_user. */
	if (__put_user(payload, user_arg))
		return -EFAULT;

	return 0;
}

static long link_shbuf_ioctl(struct file *file, unsigned int request,
		unsigned long arg)
{
	struct link_shbuf_data *priv;

	priv = file->private_data;
	if (WARN_ON(!link_shbuf_data_invariant(priv)))
		return -EINVAL;

	/* We only support two ioctls */
	switch (request) {

	case OKL4_LINK_SHBUF_IOCTL_IRQ_TX:
		return link_shbuf_ioctl_irq_tx(priv, arg);

	case OKL4_LINK_SHBUF_IOCTL_IRQ_CLR:
		return link_shbuf_ioctl_irq_clr(priv, arg);

	}

	/*
	 * Handy for debugging when userspace is linking against ioctl headers from
	 * a different kernel revision.
	 */
	dev_dbg(priv->dev, "ioctl request 0x%x received which did not match either "
		"OKL4_LINK_SHBUF_IOCTL_IRQ_TX (0x%x) or OKL4_LINK_SHBUF_IOCTL_IRQ_CLR "
		"(0x%x)\n", request, (unsigned)OKL4_LINK_SHBUF_IOCTL_IRQ_TX,
		(unsigned)OKL4_LINK_SHBUF_IOCTL_IRQ_CLR);

	return -EINVAL;
}

static int link_shbuf_mmap(struct file *file, struct vm_area_struct *vma)
{
	const struct link_shbuf_data *priv;
	unsigned long offset, pfn, flags;
	size_t size;
	pgprot_t prot;

	/* Our caller should have taken the MM semaphore. */
	if (WARN_ON(!rwsem_is_locked(&vma->vm_mm->mmap_sem)))
		return -EINVAL;

	/*
	 * The file should have been opened with a superset of the mmap requested
	 * permissions.
	 */
	flags = vma->vm_flags;
	if (WARN_ON((flags & VM_READ) && !(file->f_mode & FMODE_READ)))
		return -EINVAL;
	if (WARN_ON((flags & VM_WRITE) && !(file->f_mode & FMODE_WRITE)))
		return -EINVAL;
	if (WARN_ON((flags & VM_EXEC) && !(file->f_mode & FMODE_EXEC)))
		return -EINVAL;

	/* Retrieve our private data. */
	priv = file->private_data;
	if (WARN_ON(!link_shbuf_data_invariant(priv)))
		return -EINVAL;

	/* Check the mmap request is within bounds. */
	size = vma->vm_end - vma->vm_start;
	offset = vma->vm_pgoff << PAGE_SHIFT;
	if (!link_shbuf_valid_access(resource_size(&priv->buffer), offset, size))
		return -EINVAL;

	pfn = (priv->buffer.start + offset) >> PAGE_SHIFT;
	prot = vm_get_page_prot(flags);

	return remap_pfn_range(vma, vma->vm_start, pfn, size, prot);
}

static bool link_shbuf_access_ok(fmode_t allowed, fmode_t request)
{
	static const fmode_t ACCESS_MASK = FMODE_READ|FMODE_WRITE|FMODE_EXEC;
	fmode_t relevant = request & ACCESS_MASK;
	return (relevant & allowed) == relevant;
}

static int link_shbuf_open(struct inode *inode, struct file *file)
{
	struct cdev *cdev;
	struct link_shbuf_data *priv;

	/* Retrieve a pointer to our private data */
	cdev = inode->i_cdev;
	priv = container_of(cdev, struct link_shbuf_data, cdev);
	if (WARN_ON(!link_shbuf_data_invariant(priv)))
		return -EINVAL;

	if (!link_shbuf_access_ok(priv->permissions, file->f_mode))
		return -EACCES;

	file->private_data = priv;

	return 0;
}

static const struct file_operations link_shbuf_ops = {
	.owner = THIS_MODULE,
	.read = link_shbuf_read,
	.write = link_shbuf_write,
	.poll = link_shbuf_poll,
	.unlocked_ioctl = link_shbuf_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl = link_shbuf_ioctl,
#endif
#ifdef CONFIG_MMU
	.mmap = link_shbuf_mmap,
#endif
	.open = link_shbuf_open,
};

/*
 * Interrupt handler.
 *
 * This function will be called when our link partner uses the ioctl on their
 * shared memory device to send an outgoing interrupt.
 */
static irqreturn_t link_shbuf_irq_handler(int irq, void *data)
{
	u64 payload, old, new;
	struct _okl4_sys_interrupt_get_payload_return _payload;

	/* Retrieve a pointer to our private data. */
	struct link_shbuf_data *priv = data;
	if (WARN_ON(!link_shbuf_data_invariant(priv)))
		return IRQ_NONE;

	/*
	 * We should only ever be handling a single interrupt, and only if there
	 * was an incoming interrupt in the configuration.
	 */
	if (WARN_ON(priv->virq < 0 || priv->virq != irq))
		return IRQ_NONE;

	_payload = _okl4_sys_interrupt_get_payload(irq);
	payload = (u64)_payload.payload;

	/*
	 * At this point, it is possible the pending flag is already set. It is up to
	 * the user to synchronise their transmission and acknowledgement of
	 * interrupts.
	 */

	/* We open code atomic64_or which is not universally available. */
	do {
		old = atomic64_read(&priv->virq_payload);
		new = old | payload;
	} while (atomic64_cmpxchg(&priv->virq_payload, old, new) != old);
	smp_wmb();
	priv->virq_pending = true;

	wake_up_interruptible(&priv->virq_wq);

	return IRQ_HANDLED;
}

/*
 * Allocate a unique device number for this device.
 *
 * Note that this function needs to lock its access to link_shbuf_dev as there
 * may be multiple threads attempting to acquire a new device number.
 */
static int link_shbuf_allocate_device(dev_t *devt)
{
	int ret = 0;
	dev_t next;

	spin_lock(&device_number_allocate);

	*devt = link_shbuf_dev;
	next = MKDEV(MAJOR(link_shbuf_dev), MINOR(link_shbuf_dev) + 1);
	/* Check for overflow */
	if (MINOR(next) != MINOR(link_shbuf_dev) + 1)
		ret = -ENOSPC;
	else
		link_shbuf_dev = next;

	spin_unlock(&device_number_allocate);

	return ret;
}

/*
 * Discover and add a new shared-buffer link.
 *
 * In the following function, we are expecting to parse device tree entries
 * looking like the following:
 *
 *	hypervisor {
 *		...
 *		interrupt-line@1d {
 *				compatible = "okl,microvisor-interrupt-line",
 *				"okl,microvisor-capability";
 *			phandle = <0x7>;
 *			reg = <0x1d>;
 *			label = "foo_virqline";
 *		};
 *	 ;
 *
 *	foo@41003000 {
 *		compatible = "okl,microvisor-link-shbuf",
 *			"okl,microvisor-shared-memory";
 *		phandle = <0xd>;
 *		reg = <0x0 0x41003000 0x2000>;
 *		label = "foo";
 *		okl,rwx = <0x6>;
 *		okl,interrupt-line = <0x7>;
 *		interrupts = <0x0 0x4 0x1>;
 *		interrupt-parent = <0x1>;
 *	};
 */
static int link_shbuf_probe(struct platform_device *pdev)
{
	int ret;
	struct device_node *node, *virqline;
	struct link_shbuf_data *priv;
	const char *name;
	u32 permissions;

	node = pdev->dev.of_node;

	if (!node)
		return -ENODEV;

	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	/*
	 * Retrieve the outgoing vIRQ cap. Note, this is configurable and we
	 * anticipate that it may not exist.
	 */
	virqline = of_parse_phandle(node, "okl,interrupt-line", 0);
	if (!virqline) {
		priv->virqline = NO_OUTGOING_IRQ;
	} else {
		ret = of_property_read_u32(virqline, "reg", &priv->virqline);
		if (ret < 0 || priv->virqline == OKL4_KCAP_INVALID) {
			of_node_put(virqline);
			ret = -ENODEV;
			goto err_free_dev;
		}
	}
	of_node_put(virqline);

	/* Retrieve the incoming vIRQ number. Again, this is configurable and we
	 * anticipate that it may not exist.
	 */
	priv->virq = platform_get_irq(pdev, 0);
	if (priv->virq < 0)
		priv->virq = NO_INCOMING_IRQ;

	/* If we have a valid incoming vIRQ, register to handle it. */
	if (priv->virq >= 0) {
		ret = devm_request_irq(&pdev->dev, priv->virq, link_shbuf_irq_handler,
			0, dev_name(&pdev->dev), priv);
		if (ret < 0) {
			dev_err(&pdev->dev, "failed request for IRQ\n");
			goto err_free_dev;
		}
	}

	init_waitqueue_head(&priv->virq_wq);
	priv->virq_pending = false;

	/* Retrieve information about the shared memory region. */
	ret = of_address_to_resource(node, 0, &priv->buffer);
	if (ret < 0)
		goto err_free_irq;
	/*
	 * We expect the Elfweaver to have validated that we have a non-NULL,
	 * page-aligned region.
	 */
	if (WARN_ON(priv->buffer.start == 0) ||
			WARN_ON(resource_size(&priv->buffer) % PAGE_SIZE != 0))
		goto err_free_irq;
	if (!devm_request_mem_region(&pdev->dev, priv->buffer.start,
			resource_size(&priv->buffer), dev_name(&pdev->dev))) {
		ret = -ENODEV;
		goto err_free_irq;
	}
	priv->base = devm_ioremap(&pdev->dev, priv->buffer.start,
			resource_size(&priv->buffer));
	if (!priv->base)
		goto err_release_region;

	/* Read the permissions of the shared memory region. */
	ret = of_property_read_u32(node, "okl,rwx", &permissions);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to read shared memory permissions\n");
		goto err_unmap_dev;
	}
	if (permissions & ~S_IRWXO) {
		ret = -EINVAL;
		goto err_unmap_dev;
	}
	priv->permissions = ((permissions & S_IROTH) ? FMODE_READ : 0) |
			((permissions & S_IWOTH) ? FMODE_WRITE : 0) |
			((permissions & S_IXOTH) ? FMODE_EXEC : 0);
	if (WARN_ON(priv->permissions == 0)) {
		ret = -EINVAL;
		goto err_unmap_dev;
	}

	/* Retrieve the label of this device. This will be the "name" attribute of
	 * the corresponding "link" tag in the system's XML specification.
	 */
	ret = of_property_read_string(node, "label", &name);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to read label\n");
		goto err_unmap_dev;
	}

	cdev_init(&priv->cdev, &link_shbuf_ops);
	ret = cdev_add(&priv->cdev, link_shbuf_dev, 1);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to add char dev region\n");
		goto err_unmap_dev;
	}

	ret = link_shbuf_allocate_device(&priv->devt);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to allocate new device number\n");
		goto err_unmap_dev;
	}

	/* We're now ready to create the device itself. */
	BUG_ON(name == NULL);
	priv->dev = device_create(link_shbuf_class, &pdev->dev, priv->devt,
		priv, "%s%s", DEV_PREFIX, name);
	if (IS_ERR(priv->dev)) {
		dev_err(&pdev->dev, "failed to create device\n");
		ret = PTR_ERR(priv->dev);
		goto err_del_dev;
	}

	dev_set_drvdata(&pdev->dev, priv);

	return 0;

err_del_dev:
	cdev_del(&priv->cdev);
err_unmap_dev:
	devm_iounmap(&pdev->dev, priv->base);
err_release_region:
	devm_release_mem_region(&pdev->dev, priv->buffer.start,
			resource_size(&priv->buffer));
err_free_irq:
	if (priv->virq != NO_INCOMING_IRQ)
		devm_free_irq(&pdev->dev, priv->virq, priv);
err_free_dev:
	devm_kfree(&pdev->dev, priv);
	return ret;
}

static int link_shbuf_remove(struct platform_device *pdev)
{
	struct link_shbuf_data *priv;

	priv = dev_get_drvdata(&pdev->dev);
	WARN_ON(!link_shbuf_data_invariant(priv));

	device_destroy(link_shbuf_class, priv->devt);

	cdev_del(&priv->cdev);

	/*
	 * None of the following is strictly required, as these are all managed
	 * resources, but we clean it up anyway for clarity.
	 */

	devm_iounmap(&pdev->dev, priv->base);

	devm_release_mem_region(&pdev->dev, priv->buffer.start,
			resource_size(&priv->buffer));

	if (priv->virq != NO_INCOMING_IRQ)
		devm_free_irq(&pdev->dev, priv->virq, priv);

	devm_kfree(&pdev->dev, priv);

	return 0;
}

static struct platform_driver of_plat_link_shbuf_driver = {
	.driver = {
		.name = "okl4-shbuf",
		.owner = THIS_MODULE,
		.of_match_table = okl4_link_shbuf_match,
	},
	.probe = link_shbuf_probe,
	.remove = link_shbuf_remove,
};

/* Maximum number of minor device numbers */
enum {
	MAX_MINOR = 1 << MINORBITS,
};

static int __init okl4_link_shbuf_init(void)
{
	int ret;

	link_shbuf_class = class_create(THIS_MODULE, DEVICE_NAME);
	if (IS_ERR(link_shbuf_class)) {
		pr_err("failed to create class\n");
		ret = PTR_ERR(link_shbuf_class);
		return ret;
	}

	ret = alloc_chrdev_region(&link_shbuf_dev, 0, MAX_MINOR, DEVICE_NAME);
	if (ret < 0) {
		pr_err("failed to allocate char dev region\n");
		goto err_destroy_class;
	}

	ret = platform_driver_register(&of_plat_link_shbuf_driver);
	if (ret < 0) {
		pr_err("failed to register driver\n");
		goto err_unregister_dev_region;
	}

	spin_lock_init(&device_number_allocate);

	return 0;

err_unregister_dev_region:
	unregister_chrdev_region(link_shbuf_dev, MAX_MINOR);
err_destroy_class:
	class_destroy(link_shbuf_class);
	return ret;
}
module_init(okl4_link_shbuf_init);

static void __exit okl4_link_shbuf_exit(void)
{
	platform_driver_unregister(&of_plat_link_shbuf_driver);
	unregister_chrdev_region(link_shbuf_dev, MAX_MINOR);
	class_destroy(link_shbuf_class);
}
module_exit(okl4_link_shbuf_exit);

MODULE_DESCRIPTION("OKL4 shared buffer link driver");
MODULE_AUTHOR("Cog Systems Pty Ltd");
