// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2012 CERN (www.cern.ch)
 * Author: Alessandro Rubini <rubini@gnudd.com>
 *
 * 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;

	index = fmc_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");
