// SPDX-License-Identifier: GPL-2.0+
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/io.h>
#include <linux/export.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/fs.h>
#include <linux/rwsem.h>
#include "kpc_dma_driver.h"

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Matt.Sickler@daktronics.com");

#define KPC_DMA_CHAR_MAJOR    UNNAMED_MAJOR
#define KPC_DMA_NUM_MINORS    BIT(MINORBITS)
static DEFINE_MUTEX(kpc_dma_mtx);
static int assigned_major_num;
static LIST_HEAD(kpc_dma_list);

/**********  kpc_dma_list list management  **********/
struct kpc_dma_device *kpc_dma_lookup_device(int minor)
{
	struct kpc_dma_device *c;

	mutex_lock(&kpc_dma_mtx);
	list_for_each_entry(c, &kpc_dma_list, list) {
		if (c->pldev->id == minor)
			goto out;
	}
	c = NULL; // not-found case
out:
	mutex_unlock(&kpc_dma_mtx);
	return c;
}

static void kpc_dma_add_device(struct kpc_dma_device *ldev)
{
	mutex_lock(&kpc_dma_mtx);
	list_add(&ldev->list, &kpc_dma_list);
	mutex_unlock(&kpc_dma_mtx);
}

static void kpc_dma_del_device(struct kpc_dma_device *ldev)
{
	mutex_lock(&kpc_dma_mtx);
	list_del(&ldev->list);
	mutex_unlock(&kpc_dma_mtx);
}

/**********  SysFS Attributes **********/
static ssize_t  show_engine_regs(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct kpc_dma_device *ldev;
	struct platform_device *pldev = to_platform_device(dev);

	if (!pldev)
		return 0;
	ldev = platform_get_drvdata(pldev);
	if (!ldev)
		return 0;

	return scnprintf(buf, PAGE_SIZE,
		"EngineControlStatus      = 0x%08x\n"
		"RegNextDescPtr           = 0x%08x\n"
		"RegSWDescPtr             = 0x%08x\n"
		"RegCompletedDescPtr      = 0x%08x\n"
		"desc_pool_first          = %p\n"
		"desc_pool_last           = %p\n"
		"desc_next                = %p\n"
		"desc_completed           = %p\n",
		readl(ldev->eng_regs + 1),
		readl(ldev->eng_regs + 2),
		readl(ldev->eng_regs + 3),
		readl(ldev->eng_regs + 4),
		ldev->desc_pool_first,
		ldev->desc_pool_last,
		ldev->desc_next,
		ldev->desc_completed
	);
}
static DEVICE_ATTR(engine_regs, 0444, show_engine_regs, NULL);

static const struct attribute *ndd_attr_list[] = {
	&dev_attr_engine_regs.attr,
	NULL,
};

static struct class *kpc_dma_class;

/**********  Platform Driver Functions  **********/
static
int  kpc_dma_probe(struct platform_device *pldev)
{
	struct resource *r = NULL;
	int rv = 0;
	dev_t dev;

	struct kpc_dma_device *ldev = kzalloc(sizeof(*ldev), GFP_KERNEL);

	if (!ldev) {
		dev_err(&pldev->dev, "%s: unable to kzalloc space for kpc_dma_device\n", __func__);
		rv = -ENOMEM;
		goto err_rv;
	}

	INIT_LIST_HEAD(&ldev->list);

	ldev->pldev = pldev;
	platform_set_drvdata(pldev, ldev);
	atomic_set(&ldev->open_count, 1);

	mutex_init(&ldev->sem);
	lock_engine(ldev);

	// Get Engine regs resource
	r = platform_get_resource(pldev, IORESOURCE_MEM, 0);
	if (!r) {
		dev_err(&ldev->pldev->dev, "%s: didn't get the engine regs resource!\n", __func__);
		rv = -ENXIO;
		goto err_kfree;
	}
	ldev->eng_regs = ioremap(r->start, resource_size(r));
	if (!ldev->eng_regs) {
		dev_err(&ldev->pldev->dev, "%s: failed to ioremap engine regs!\n", __func__);
		rv = -ENXIO;
		goto err_kfree;
	}

	r = platform_get_resource(pldev, IORESOURCE_IRQ, 0);
	if (!r) {
		dev_err(&ldev->pldev->dev, "%s: didn't get the IRQ resource!\n", __func__);
		rv = -ENXIO;
		goto err_kfree;
	}
	ldev->irq = r->start;

	// Setup miscdev struct
	dev = MKDEV(assigned_major_num, pldev->id);
	ldev->kpc_dma_dev = device_create(kpc_dma_class, &pldev->dev, dev, ldev, "kpc_dma%d", pldev->id);
	if (IS_ERR(ldev->kpc_dma_dev)) {
		rv = PTR_ERR(ldev->kpc_dma_dev);
		dev_err(&ldev->pldev->dev, "%s: device_create failed: %d\n", __func__, rv);
		goto err_kfree;
	}

	// Setup the DMA engine
	rv = setup_dma_engine(ldev, 30);
	if (rv) {
		dev_err(&ldev->pldev->dev, "%s: failed to setup_dma_engine: %d\n", __func__, rv);
		goto err_misc_dereg;
	}

	// Setup the sysfs files
	rv = sysfs_create_files(&(ldev->pldev->dev.kobj), ndd_attr_list);
	if (rv) {
		dev_err(&ldev->pldev->dev, "%s: Failed to add sysfs files: %d\n", __func__, rv);
		goto err_destroy_eng;
	}

	kpc_dma_add_device(ldev);

	return 0;

 err_destroy_eng:
	destroy_dma_engine(ldev);
 err_misc_dereg:
	device_destroy(kpc_dma_class, dev);
 err_kfree:
	kfree(ldev);
 err_rv:
	return rv;
}

static
int  kpc_dma_remove(struct platform_device *pldev)
{
	struct kpc_dma_device *ldev = platform_get_drvdata(pldev);

	if (!ldev)
		return -ENXIO;

	lock_engine(ldev);
	sysfs_remove_files(&(ldev->pldev->dev.kobj), ndd_attr_list);
	destroy_dma_engine(ldev);
	kpc_dma_del_device(ldev);
	device_destroy(kpc_dma_class, MKDEV(assigned_major_num, ldev->pldev->id));
	kfree(ldev);

	return 0;
}

/**********  Driver Functions  **********/
static struct platform_driver kpc_dma_plat_driver_i = {
	.probe        = kpc_dma_probe,
	.remove       = kpc_dma_remove,
	.driver = {
		.name   = KP_DRIVER_NAME_DMA_CONTROLLER,
	},
};

static
int __init kpc_dma_driver_init(void)
{
	int err;

	err = __register_chrdev(KPC_DMA_CHAR_MAJOR, 0, KPC_DMA_NUM_MINORS, "kpc_dma", &kpc_dma_fops);
	if (err < 0) {
		pr_err("Can't allocate a major number (%d) for kpc_dma (err = %d)\n", KPC_DMA_CHAR_MAJOR, err);
		goto fail_chrdev_register;
	}
	assigned_major_num = err;

	kpc_dma_class = class_create(THIS_MODULE, "kpc_dma");
	err = PTR_ERR(kpc_dma_class);
	if (IS_ERR(kpc_dma_class)) {
		pr_err("Can't create class kpc_dma (err = %d)\n", err);
		goto fail_class_create;
	}

	err = platform_driver_register(&kpc_dma_plat_driver_i);
	if (err) {
		pr_err("Can't register platform driver for kpc_dma (err = %d)\n", err);
		goto fail_platdriver_register;
	}

	return err;

fail_platdriver_register:
	class_destroy(kpc_dma_class);
fail_class_create:
	__unregister_chrdev(KPC_DMA_CHAR_MAJOR, 0, KPC_DMA_NUM_MINORS, "kpc_dma");
fail_chrdev_register:
	return err;
}
module_init(kpc_dma_driver_init);

static
void __exit kpc_dma_driver_exit(void)
{
	platform_driver_unregister(&kpc_dma_plat_driver_i);
	class_destroy(kpc_dma_class);
	__unregister_chrdev(KPC_DMA_CHAR_MAJOR, 0, KPC_DMA_NUM_MINORS, "kpc_dma");
}
module_exit(kpc_dma_driver_exit);
