// SPDX-License-Identifier: GPL-2.0
/*
 * Generic Counter interface
 * Copyright (C) 2020 William Breathitt Gray
 */
#include <linux/cdev.h>
#include <linux/counter.h>
#include <linux/device.h>
#include <linux/device/bus.h>
#include <linux/export.h>
#include <linux/fs.h>
#include <linux/gfp.h>
#include <linux/idr.h>
#include <linux/init.h>
#include <linux/kdev_t.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/wait.h>

#include "counter-chrdev.h"
#include "counter-sysfs.h"

/* Provides a unique ID for each counter device */
static DEFINE_IDA(counter_ida);

struct counter_device_allochelper {
	struct counter_device counter;

	/*
	 * This is cache line aligned to ensure private data behaves like if it
	 * were kmalloced separately.
	 */
	unsigned long privdata[] ____cacheline_aligned;
};

static void counter_device_release(struct device *dev)
{
	struct counter_device *const counter =
		container_of(dev, struct counter_device, dev);

	counter_chrdev_remove(counter);
	ida_free(&counter_ida, dev->id);

	kfree(container_of(counter, struct counter_device_allochelper, counter));
}

static struct device_type counter_device_type = {
	.name = "counter_device",
	.release = counter_device_release,
};

static struct bus_type counter_bus_type = {
	.name = "counter",
	.dev_name = "counter",
};

static dev_t counter_devt;

/**
 * counter_priv - access counter device private data
 * @counter: counter device
 *
 * Get the counter device private data
 */
void *counter_priv(const struct counter_device *const counter)
{
	struct counter_device_allochelper *ch =
		container_of(counter, struct counter_device_allochelper, counter);

	return &ch->privdata;
}
EXPORT_SYMBOL_GPL(counter_priv);

/**
 * counter_alloc - allocate a counter_device
 * @sizeof_priv: size of the driver private data
 *
 * This is part one of counter registration. The structure is allocated
 * dynamically to ensure the right lifetime for the embedded struct device.
 *
 * If this succeeds, call counter_put() to get rid of the counter_device again.
 */
struct counter_device *counter_alloc(size_t sizeof_priv)
{
	struct counter_device_allochelper *ch;
	struct counter_device *counter;
	struct device *dev;
	int err;

	ch = kzalloc(sizeof(*ch) + sizeof_priv, GFP_KERNEL);
	if (!ch)
		return NULL;

	counter = &ch->counter;
	dev = &counter->dev;

	/* Acquire unique ID */
	err = ida_alloc(&counter_ida, GFP_KERNEL);
	if (err < 0)
		goto err_ida_alloc;
	dev->id = err;

	mutex_init(&counter->ops_exist_lock);
	dev->type = &counter_device_type;
	dev->bus = &counter_bus_type;
	dev->devt = MKDEV(MAJOR(counter_devt), dev->id);

	err = counter_chrdev_add(counter);
	if (err < 0)
		goto err_chrdev_add;

	device_initialize(dev);

	return counter;

err_chrdev_add:

	ida_free(&counter_ida, dev->id);
err_ida_alloc:

	kfree(ch);

	return NULL;
}
EXPORT_SYMBOL_GPL(counter_alloc);

void counter_put(struct counter_device *counter)
{
	put_device(&counter->dev);
}
EXPORT_SYMBOL_GPL(counter_put);

/**
 * counter_add - complete registration of a counter
 * @counter: the counter to add
 *
 * This is part two of counter registration.
 *
 * If this succeeds, call counter_unregister() to get rid of the counter_device again.
 */
int counter_add(struct counter_device *counter)
{
	int err;
	struct device *dev = &counter->dev;

	if (counter->parent) {
		dev->parent = counter->parent;
		dev->of_node = counter->parent->of_node;
	}

	err = counter_sysfs_add(counter);
	if (err < 0)
		return err;

	/* implies device_add(dev) */
	return cdev_device_add(&counter->chrdev, dev);
}
EXPORT_SYMBOL_GPL(counter_add);

/**
 * counter_unregister - unregister Counter from the system
 * @counter:	pointer to Counter to unregister
 *
 * The Counter is unregistered from the system.
 */
void counter_unregister(struct counter_device *const counter)
{
	if (!counter)
		return;

	cdev_device_del(&counter->chrdev, &counter->dev);

	mutex_lock(&counter->ops_exist_lock);

	counter->ops = NULL;
	wake_up(&counter->events_wait);

	mutex_unlock(&counter->ops_exist_lock);
}
EXPORT_SYMBOL_GPL(counter_unregister);

static void devm_counter_release(void *counter)
{
	counter_unregister(counter);
}

static void devm_counter_put(void *counter)
{
	counter_put(counter);
}

/**
 * devm_counter_alloc - allocate a counter_device
 * @dev: the device to register the release callback for
 * @sizeof_priv: size of the driver private data
 *
 * This is the device managed version of counter_add(). It registers a cleanup
 * callback to care for calling counter_put().
 */
struct counter_device *devm_counter_alloc(struct device *dev, size_t sizeof_priv)
{
	struct counter_device *counter;
	int err;

	counter = counter_alloc(sizeof_priv);
	if (!counter)
		return NULL;

	err = devm_add_action_or_reset(dev, devm_counter_put, counter);
	if (err < 0)
		return NULL;

	return counter;
}
EXPORT_SYMBOL_GPL(devm_counter_alloc);

/**
 * devm_counter_add - complete registration of a counter
 * @dev: the device to register the release callback for
 * @counter: the counter to add
 *
 * This is the device managed version of counter_add(). It registers a cleanup
 * callback to care for calling counter_unregister().
 */
int devm_counter_add(struct device *dev,
		     struct counter_device *const counter)
{
	int err;

	err = counter_add(counter);
	if (err < 0)
		return err;

	return devm_add_action_or_reset(dev, devm_counter_release, counter);
}
EXPORT_SYMBOL_GPL(devm_counter_add);

#define COUNTER_DEV_MAX 256

static int __init counter_init(void)
{
	int err;

	err = bus_register(&counter_bus_type);
	if (err < 0)
		return err;

	err = alloc_chrdev_region(&counter_devt, 0, COUNTER_DEV_MAX, "counter");
	if (err < 0)
		goto err_unregister_bus;

	return 0;

err_unregister_bus:
	bus_unregister(&counter_bus_type);
	return err;
}

static void __exit counter_exit(void)
{
	unregister_chrdev_region(counter_devt, COUNTER_DEV_MAX);
	bus_unregister(&counter_bus_type);
}

subsys_initcall(counter_init);
module_exit(counter_exit);

MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
MODULE_DESCRIPTION("Generic Counter interface");
MODULE_LICENSE("GPL v2");
