/* SPDX-License-Identifier: GPL-2.0+ */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <asm/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(struct kpc_dma_device), 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_nocache(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)) {
		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);
