/*
 * Copyright (C) 2012 CERN (www.cern.ch)
 * Author: Alessandro Rubini <rubini@gnudd.com>
 *
 * Released according to the GNU GPL, version 2 or any later version.
 *
 * This work is part of the White Rabbit project, a research effort led
 * by CERN, the European Institute for Nuclear Research.
 */
#include <linux/module.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/spinlock.h>
#include <linux/fmc.h>
#include <linux/uaccess.h>

static LIST_HEAD(fc_devices);
static DEFINE_SPINLOCK(fc_lock);

struct fc_instance {
	struct list_head list;
	struct fmc_device *fmc;
	struct miscdevice misc;
};

/* at open time, we must identify our device */
static int fc_open(struct inode *ino, struct file *f)
{
	struct fmc_device *fmc;
	struct fc_instance *fc;
	int minor = iminor(ino);

	list_for_each_entry(fc, &fc_devices, list)
		if (fc->misc.minor == minor)
			break;
	if (fc->misc.minor != minor)
		return -ENODEV;
	fmc = fc->fmc;
	if (try_module_get(fmc->owner) == 0)
		return -ENODEV;

	f->private_data = fmc;
	return 0;
}

static int fc_release(struct inode *ino, struct file *f)
{
	struct fmc_device *fmc = f->private_data;
	module_put(fmc->owner);
	return 0;
}

/* read and write are simple after the default llseek has been used */
static ssize_t fc_read(struct file *f, char __user *buf, size_t count,
		       loff_t *offp)
{
	struct fmc_device *fmc = f->private_data;
	unsigned long addr;
	uint32_t val;

	if (count < sizeof(val))
		return -EINVAL;
	count = sizeof(val);

	addr = *offp;
	if (addr > fmc->memlen)
		return -ESPIPE; /* Illegal seek */
	val = fmc_readl(fmc, addr);
	if (copy_to_user(buf, &val, count))
		return -EFAULT;
	*offp += count;
	return count;
}

static ssize_t fc_write(struct file *f, const char __user *buf, size_t count,
			loff_t *offp)
{
	struct fmc_device *fmc = f->private_data;
	unsigned long addr;
	uint32_t val;

	if (count < sizeof(val))
		return -EINVAL;
	count = sizeof(val);

	addr = *offp;
	if (addr > fmc->memlen)
		return -ESPIPE; /* Illegal seek */
	if (copy_from_user(&val, buf, count))
		return -EFAULT;
	fmc_writel(fmc, val, addr);
	*offp += count;
	return count;
}

static const struct file_operations fc_fops = {
	.owner = THIS_MODULE,
	.open = fc_open,
	.release = fc_release,
	.llseek = generic_file_llseek,
	.read = fc_read,
	.write = fc_write,
};


/* Device part .. */
static int fc_probe(struct fmc_device *fmc);
static int fc_remove(struct fmc_device *fmc);

static struct fmc_driver fc_drv = {
	.version = FMC_VERSION,
	.driver.name = KBUILD_MODNAME,
	.probe = fc_probe,
	.remove = fc_remove,
	/* no table: we want to match everything */
};

/* We accept the generic busid parameter */
FMC_PARAM_BUSID(fc_drv);

/* probe and remove must allocate and release a misc device */
static int fc_probe(struct fmc_device *fmc)
{
	int ret;
	int index = 0;

	struct fc_instance *fc;

	if (fmc->op->validate)
		index = fmc->op->validate(fmc, &fc_drv);
	if (index < 0)
		return -EINVAL; /* not our device: invalid */

	/* Create a char device: we want to create it anew */
	fc = kzalloc(sizeof(*fc), GFP_KERNEL);
	if (!fc)
		return -ENOMEM;
	fc->fmc = fmc;
	fc->misc.minor = MISC_DYNAMIC_MINOR;
	fc->misc.fops = &fc_fops;
	fc->misc.name = kstrdup(dev_name(&fmc->dev), GFP_KERNEL);

	ret = misc_register(&fc->misc);
	if (ret < 0)
		goto out;
	spin_lock(&fc_lock);
	list_add(&fc->list, &fc_devices);
	spin_unlock(&fc_lock);
	dev_info(&fc->fmc->dev, "Created misc device \"%s\"\n",
		 fc->misc.name);
	return 0;

out:
	kfree(fc->misc.name);
	kfree(fc);
	return ret;
}

static int fc_remove(struct fmc_device *fmc)
{
	struct fc_instance *fc;

	list_for_each_entry(fc, &fc_devices, list)
		if (fc->fmc == fmc)
			break;
	if (fc->fmc != fmc) {
		dev_err(&fmc->dev, "remove called but not found\n");
		return -ENODEV;
	}

	spin_lock(&fc_lock);
	list_del(&fc->list);
	spin_unlock(&fc_lock);
	misc_deregister(&fc->misc);
	kfree(fc->misc.name);
	kfree(fc);

	return 0;
}


static int fc_init(void)
{
	int ret;

	ret = fmc_driver_register(&fc_drv);
	return ret;
}

static void fc_exit(void)
{
	fmc_driver_unregister(&fc_drv);
}

module_init(fc_init);
module_exit(fc_exit);

MODULE_LICENSE("GPL");
