// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright 2021 Xillybus Ltd, http://xillybus.com
 *
 * Driver for the Xillybus class
 */

#include <linux/types.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/mutex.h>

#include "xillybus_class.h"

MODULE_DESCRIPTION("Driver for Xillybus class");
MODULE_AUTHOR("Eli Billauer, Xillybus Ltd.");
MODULE_ALIAS("xillybus_class");
MODULE_LICENSE("GPL v2");

static DEFINE_MUTEX(unit_mutex);
static LIST_HEAD(unit_list);
static const struct class xillybus_class = {
	.name = "xillybus",
};

#define UNITNAMELEN 16

struct xilly_unit {
	struct list_head list_entry;
	void *private_data;

	struct cdev *cdev;
	char name[UNITNAMELEN];
	int major;
	int lowest_minor;
	int num_nodes;
};

int xillybus_init_chrdev(struct device *dev,
			 const struct file_operations *fops,
			 struct module *owner,
			 void *private_data,
			 unsigned char *idt, unsigned int len,
			 int num_nodes,
			 const char *prefix, bool enumerate)
{
	int rc;
	dev_t mdev;
	int i;
	char devname[48];

	struct device *device;
	size_t namelen;
	struct xilly_unit *unit, *u;

	unit = kzalloc(sizeof(*unit), GFP_KERNEL);

	if (!unit)
		return -ENOMEM;

	mutex_lock(&unit_mutex);

	if (!enumerate)
		snprintf(unit->name, UNITNAMELEN, "%s", prefix);

	for (i = 0; enumerate; i++) {
		snprintf(unit->name, UNITNAMELEN, "%s_%02d",
			 prefix, i);

		enumerate = false;
		list_for_each_entry(u, &unit_list, list_entry)
			if (!strcmp(unit->name, u->name)) {
				enumerate = true;
				break;
			}
	}

	rc = alloc_chrdev_region(&mdev, 0, num_nodes, unit->name);

	if (rc) {
		dev_warn(dev, "Failed to obtain major/minors");
		goto fail_obtain;
	}

	unit->major = MAJOR(mdev);
	unit->lowest_minor = MINOR(mdev);
	unit->num_nodes = num_nodes;
	unit->private_data = private_data;

	unit->cdev = cdev_alloc();
	if (!unit->cdev) {
		rc = -ENOMEM;
		goto unregister_chrdev;
	}
	unit->cdev->ops = fops;
	unit->cdev->owner = owner;

	rc = cdev_add(unit->cdev, MKDEV(unit->major, unit->lowest_minor),
		      unit->num_nodes);
	if (rc) {
		dev_err(dev, "Failed to add cdev.\n");
		/* kobject_put() is normally done by cdev_del() */
		kobject_put(&unit->cdev->kobj);
		goto unregister_chrdev;
	}

	for (i = 0; i < num_nodes; i++) {
		namelen = strnlen(idt, len);

		if (namelen == len) {
			dev_err(dev, "IDT's list of names is too short. This is exceptionally weird, because its CRC is OK\n");
			rc = -ENODEV;
			goto unroll_device_create;
		}

		snprintf(devname, sizeof(devname), "%s_%s",
			 unit->name, idt);

		len -= namelen + 1;
		idt += namelen + 1;

		device = device_create(&xillybus_class,
				       NULL,
				       MKDEV(unit->major,
					     i + unit->lowest_minor),
				       NULL,
				       "%s", devname);

		if (IS_ERR(device)) {
			dev_err(dev, "Failed to create %s device. Aborting.\n",
				devname);
			rc = -ENODEV;
			goto unroll_device_create;
		}
	}

	if (len) {
		dev_err(dev, "IDT's list of names is too long. This is exceptionally weird, because its CRC is OK\n");
		rc = -ENODEV;
		goto unroll_device_create;
	}

	list_add_tail(&unit->list_entry, &unit_list);

	dev_info(dev, "Created %d device files.\n", num_nodes);

	mutex_unlock(&unit_mutex);

	return 0;

unroll_device_create:
	for (i--; i >= 0; i--)
		device_destroy(&xillybus_class, MKDEV(unit->major,
						     i + unit->lowest_minor));

	cdev_del(unit->cdev);

unregister_chrdev:
	unregister_chrdev_region(MKDEV(unit->major, unit->lowest_minor),
				 unit->num_nodes);

fail_obtain:
	mutex_unlock(&unit_mutex);

	kfree(unit);

	return rc;
}
EXPORT_SYMBOL(xillybus_init_chrdev);

void xillybus_cleanup_chrdev(void *private_data,
			     struct device *dev)
{
	int minor;
	struct xilly_unit *unit = NULL, *iter;

	mutex_lock(&unit_mutex);

	list_for_each_entry(iter, &unit_list, list_entry)
		if (iter->private_data == private_data) {
			unit = iter;
			break;
		}

	if (!unit) {
		dev_err(dev, "Weird bug: Failed to find unit\n");
		mutex_unlock(&unit_mutex);
		return;
	}

	for (minor = unit->lowest_minor;
	     minor < (unit->lowest_minor + unit->num_nodes);
	     minor++)
		device_destroy(&xillybus_class, MKDEV(unit->major, minor));

	cdev_del(unit->cdev);

	unregister_chrdev_region(MKDEV(unit->major, unit->lowest_minor),
				 unit->num_nodes);

	dev_info(dev, "Removed %d device files.\n",
		 unit->num_nodes);

	list_del(&unit->list_entry);
	kfree(unit);

	mutex_unlock(&unit_mutex);
}
EXPORT_SYMBOL(xillybus_cleanup_chrdev);

int xillybus_find_inode(struct inode *inode,
			void **private_data, int *index)
{
	int minor = iminor(inode);
	int major = imajor(inode);
	struct xilly_unit *unit = NULL, *iter;

	mutex_lock(&unit_mutex);

	list_for_each_entry(iter, &unit_list, list_entry)
		if (iter->major == major &&
		    minor >= iter->lowest_minor &&
		    minor < (iter->lowest_minor + iter->num_nodes)) {
			unit = iter;
			break;
		}

	if (!unit) {
		mutex_unlock(&unit_mutex);
		return -ENODEV;
	}

	*private_data = unit->private_data;
	*index = minor - unit->lowest_minor;

	mutex_unlock(&unit_mutex);
	return 0;
}
EXPORT_SYMBOL(xillybus_find_inode);

static int __init xillybus_class_init(void)
{
	return class_register(&xillybus_class);
}

static void __exit xillybus_class_exit(void)
{
	class_unregister(&xillybus_class);
}

module_init(xillybus_class_init);
module_exit(xillybus_class_exit);
