// SPDX-License-Identifier: GPL-2.0
/*
 * Generic Counter character device interface
 * Copyright (C) 2020 William Breathitt Gray
 */
#include <linux/cdev.h>
#include <linux/counter.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/export.h>
#include <linux/fs.h>
#include <linux/kfifo.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/nospec.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/timekeeping.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include <linux/wait.h>

#include "counter-chrdev.h"

struct counter_comp_node {
	struct list_head l;
	struct counter_component component;
	struct counter_comp comp;
	void *parent;
};

#define counter_comp_read_is_equal(a, b) \
	(a.action_read == b.action_read || \
	a.device_u8_read == b.device_u8_read || \
	a.count_u8_read == b.count_u8_read || \
	a.signal_u8_read == b.signal_u8_read || \
	a.device_u32_read == b.device_u32_read || \
	a.count_u32_read == b.count_u32_read || \
	a.signal_u32_read == b.signal_u32_read || \
	a.device_u64_read == b.device_u64_read || \
	a.count_u64_read == b.count_u64_read || \
	a.signal_u64_read == b.signal_u64_read || \
	a.signal_array_u32_read == b.signal_array_u32_read || \
	a.device_array_u64_read == b.device_array_u64_read || \
	a.count_array_u64_read == b.count_array_u64_read || \
	a.signal_array_u64_read == b.signal_array_u64_read)

#define counter_comp_read_is_set(comp) \
	(comp.action_read || \
	comp.device_u8_read || \
	comp.count_u8_read || \
	comp.signal_u8_read || \
	comp.device_u32_read || \
	comp.count_u32_read || \
	comp.signal_u32_read || \
	comp.device_u64_read || \
	comp.count_u64_read || \
	comp.signal_u64_read || \
	comp.signal_array_u32_read || \
	comp.device_array_u64_read || \
	comp.count_array_u64_read || \
	comp.signal_array_u64_read)

static ssize_t counter_chrdev_read(struct file *filp, char __user *buf,
				   size_t len, loff_t *f_ps)
{
	struct counter_device *const counter = filp->private_data;
	int err;
	unsigned int copied;

	if (!counter->ops)
		return -ENODEV;

	if (len < sizeof(struct counter_event))
		return -EINVAL;

	do {
		if (kfifo_is_empty(&counter->events)) {
			if (filp->f_flags & O_NONBLOCK)
				return -EAGAIN;

			err = wait_event_interruptible(counter->events_wait,
					!kfifo_is_empty(&counter->events) ||
					!counter->ops);
			if (err < 0)
				return err;
			if (!counter->ops)
				return -ENODEV;
		}

		if (mutex_lock_interruptible(&counter->events_out_lock))
			return -ERESTARTSYS;
		err = kfifo_to_user(&counter->events, buf, len, &copied);
		mutex_unlock(&counter->events_out_lock);
		if (err < 0)
			return err;
	} while (!copied);

	return copied;
}

static __poll_t counter_chrdev_poll(struct file *filp,
				    struct poll_table_struct *pollt)
{
	struct counter_device *const counter = filp->private_data;
	__poll_t events = 0;

	if (!counter->ops)
		return events;

	poll_wait(filp, &counter->events_wait, pollt);

	if (!kfifo_is_empty(&counter->events))
		events = EPOLLIN | EPOLLRDNORM;

	return events;
}

static void counter_events_list_free(struct list_head *const events_list)
{
	struct counter_event_node *p, *n;
	struct counter_comp_node *q, *o;

	list_for_each_entry_safe(p, n, events_list, l) {
		/* Free associated component nodes */
		list_for_each_entry_safe(q, o, &p->comp_list, l) {
			list_del(&q->l);
			kfree(q);
		}

		/* Free event node */
		list_del(&p->l);
		kfree(p);
	}
}

static int counter_set_event_node(struct counter_device *const counter,
				  struct counter_watch *const watch,
				  const struct counter_comp_node *const cfg)
{
	struct counter_event_node *event_node;
	int err = 0;
	struct counter_comp_node *comp_node;

	/* Search for event in the list */
	list_for_each_entry(event_node, &counter->next_events_list, l)
		if (event_node->event == watch->event &&
		    event_node->channel == watch->channel)
			break;

	/* If event is not already in the list */
	if (&event_node->l == &counter->next_events_list) {
		/* Allocate new event node */
		event_node = kmalloc_obj(*event_node);
		if (!event_node)
			return -ENOMEM;

		/* Configure event node and add to the list */
		event_node->event = watch->event;
		event_node->channel = watch->channel;
		INIT_LIST_HEAD(&event_node->comp_list);
		list_add(&event_node->l, &counter->next_events_list);
	}

	/* Check if component watch has already been set before */
	list_for_each_entry(comp_node, &event_node->comp_list, l)
		if (comp_node->parent == cfg->parent &&
		    counter_comp_read_is_equal(comp_node->comp, cfg->comp)) {
			err = -EINVAL;
			goto exit_free_event_node;
		}

	/* Allocate component node */
	comp_node = kmalloc_obj(*comp_node);
	if (!comp_node) {
		err = -ENOMEM;
		goto exit_free_event_node;
	}
	*comp_node = *cfg;

	/* Add component node to event node */
	list_add_tail(&comp_node->l, &event_node->comp_list);

exit_free_event_node:
	/* Free event node if no one else is watching */
	if (list_empty(&event_node->comp_list)) {
		list_del(&event_node->l);
		kfree(event_node);
	}

	return err;
}

static int counter_enable_events(struct counter_device *const counter)
{
	unsigned long flags;
	int err = 0;

	mutex_lock(&counter->n_events_list_lock);
	spin_lock_irqsave(&counter->events_list_lock, flags);

	counter_events_list_free(&counter->events_list);
	list_replace_init(&counter->next_events_list,
			  &counter->events_list);

	if (counter->ops->events_configure)
		err = counter->ops->events_configure(counter);

	spin_unlock_irqrestore(&counter->events_list_lock, flags);
	mutex_unlock(&counter->n_events_list_lock);

	return err;
}

static int counter_disable_events(struct counter_device *const counter)
{
	unsigned long flags;
	int err = 0;

	spin_lock_irqsave(&counter->events_list_lock, flags);

	counter_events_list_free(&counter->events_list);

	if (counter->ops->events_configure)
		err = counter->ops->events_configure(counter);

	spin_unlock_irqrestore(&counter->events_list_lock, flags);

	mutex_lock(&counter->n_events_list_lock);

	counter_events_list_free(&counter->next_events_list);

	mutex_unlock(&counter->n_events_list_lock);

	return err;
}

static int counter_get_ext(const struct counter_comp *const ext,
			   const size_t num_ext, const size_t component_id,
			   size_t *const ext_idx, size_t *const id)
{
	struct counter_array *element;

	*id = 0;
	for (*ext_idx = 0; *ext_idx < num_ext; (*ext_idx)++) {
		if (*id == component_id)
			return 0;

		if (ext[*ext_idx].type == COUNTER_COMP_ARRAY) {
			element = ext[*ext_idx].priv;

			if (component_id - *id < element->length)
				return 0;

			*id += element->length;
		} else
			(*id)++;
	}

	return -EINVAL;
}

static int counter_add_watch(struct counter_device *const counter,
			     const unsigned long arg)
{
	void __user *const uwatch = (void __user *)arg;
	struct counter_watch watch;
	struct counter_comp_node comp_node = {};
	size_t parent, id;
	struct counter_comp *ext;
	size_t num_ext;
	size_t ext_idx, ext_id;
	int err = 0;

	if (copy_from_user(&watch, uwatch, sizeof(watch)))
		return -EFAULT;

	if (watch.component.type == COUNTER_COMPONENT_NONE)
		goto no_component;

	parent = watch.component.parent;

	/* Configure parent component info for comp node */
	switch (watch.component.scope) {
	case COUNTER_SCOPE_DEVICE:
		ext = counter->ext;
		num_ext = counter->num_ext;
		break;
	case COUNTER_SCOPE_SIGNAL:
		if (parent >= counter->num_signals)
			return -EINVAL;
		parent = array_index_nospec(parent, counter->num_signals);

		comp_node.parent = counter->signals + parent;

		ext = counter->signals[parent].ext;
		num_ext = counter->signals[parent].num_ext;
		break;
	case COUNTER_SCOPE_COUNT:
		if (parent >= counter->num_counts)
			return -EINVAL;
		parent = array_index_nospec(parent, counter->num_counts);

		comp_node.parent = counter->counts + parent;

		ext = counter->counts[parent].ext;
		num_ext = counter->counts[parent].num_ext;
		break;
	default:
		return -EINVAL;
	}

	id = watch.component.id;

	/* Configure component info for comp node */
	switch (watch.component.type) {
	case COUNTER_COMPONENT_SIGNAL:
		if (watch.component.scope != COUNTER_SCOPE_SIGNAL)
			return -EINVAL;

		comp_node.comp.type = COUNTER_COMP_SIGNAL_LEVEL;
		comp_node.comp.signal_u32_read = counter->ops->signal_read;
		break;
	case COUNTER_COMPONENT_COUNT:
		if (watch.component.scope != COUNTER_SCOPE_COUNT)
			return -EINVAL;

		comp_node.comp.type = COUNTER_COMP_U64;
		comp_node.comp.count_u64_read = counter->ops->count_read;
		break;
	case COUNTER_COMPONENT_FUNCTION:
		if (watch.component.scope != COUNTER_SCOPE_COUNT)
			return -EINVAL;

		comp_node.comp.type = COUNTER_COMP_FUNCTION;
		comp_node.comp.count_u32_read = counter->ops->function_read;
		break;
	case COUNTER_COMPONENT_SYNAPSE_ACTION:
		if (watch.component.scope != COUNTER_SCOPE_COUNT)
			return -EINVAL;
		if (id >= counter->counts[parent].num_synapses)
			return -EINVAL;
		id = array_index_nospec(id, counter->counts[parent].num_synapses);

		comp_node.comp.type = COUNTER_COMP_SYNAPSE_ACTION;
		comp_node.comp.action_read = counter->ops->action_read;
		comp_node.comp.priv = counter->counts[parent].synapses + id;
		break;
	case COUNTER_COMPONENT_EXTENSION:
		err = counter_get_ext(ext, num_ext, id, &ext_idx, &ext_id);
		if (err < 0)
			return err;

		comp_node.comp = ext[ext_idx];
		break;
	default:
		return -EINVAL;
	}
	if (!counter_comp_read_is_set(comp_node.comp))
		return -EOPNOTSUPP;

no_component:
	mutex_lock(&counter->n_events_list_lock);

	if (counter->ops->watch_validate) {
		err = counter->ops->watch_validate(counter, &watch);
		if (err < 0)
			goto err_exit;
	}

	comp_node.component = watch.component;

	err = counter_set_event_node(counter, &watch, &comp_node);

err_exit:
	mutex_unlock(&counter->n_events_list_lock);

	return err;
}

static long counter_chrdev_ioctl(struct file *filp, unsigned int cmd,
				 unsigned long arg)
{
	struct counter_device *const counter = filp->private_data;
	int ret = -ENODEV;

	mutex_lock(&counter->ops_exist_lock);

	if (!counter->ops)
		goto out_unlock;

	switch (cmd) {
	case COUNTER_ADD_WATCH_IOCTL:
		ret = counter_add_watch(counter, arg);
		break;
	case COUNTER_ENABLE_EVENTS_IOCTL:
		ret = counter_enable_events(counter);
		break;
	case COUNTER_DISABLE_EVENTS_IOCTL:
		ret = counter_disable_events(counter);
		break;
	default:
		ret = -ENOIOCTLCMD;
		break;
	}

out_unlock:
	mutex_unlock(&counter->ops_exist_lock);

	return ret;
}

static int counter_chrdev_open(struct inode *inode, struct file *filp)
{
	struct counter_device *const counter = container_of(inode->i_cdev,
							    typeof(*counter),
							    chrdev);

	get_device(&counter->dev);
	filp->private_data = counter;

	return nonseekable_open(inode, filp);
}

static int counter_chrdev_release(struct inode *inode, struct file *filp)
{
	struct counter_device *const counter = filp->private_data;
	int ret = 0;

	mutex_lock(&counter->ops_exist_lock);

	if (!counter->ops) {
		/* Free any lingering held memory */
		counter_events_list_free(&counter->events_list);
		counter_events_list_free(&counter->next_events_list);
		ret = -ENODEV;
		goto out_unlock;
	}

	ret = counter_disable_events(counter);
	if (ret < 0) {
		mutex_unlock(&counter->ops_exist_lock);
		return ret;
	}

out_unlock:
	mutex_unlock(&counter->ops_exist_lock);

	put_device(&counter->dev);

	return ret;
}

static const struct file_operations counter_fops = {
	.owner = THIS_MODULE,
	.read = counter_chrdev_read,
	.poll = counter_chrdev_poll,
	.unlocked_ioctl = counter_chrdev_ioctl,
	.open = counter_chrdev_open,
	.release = counter_chrdev_release,
};

int counter_chrdev_add(struct counter_device *const counter)
{
	/* Initialize Counter events lists */
	INIT_LIST_HEAD(&counter->events_list);
	INIT_LIST_HEAD(&counter->next_events_list);
	spin_lock_init(&counter->events_list_lock);
	mutex_init(&counter->n_events_list_lock);
	init_waitqueue_head(&counter->events_wait);
	spin_lock_init(&counter->events_in_lock);
	mutex_init(&counter->events_out_lock);

	/* Initialize character device */
	cdev_init(&counter->chrdev, &counter_fops);

	/* Allocate Counter events queue */
	return kfifo_alloc(&counter->events, 64, GFP_KERNEL);
}

void counter_chrdev_remove(struct counter_device *const counter)
{
	kfifo_free(&counter->events);
}

static int counter_get_array_data(struct counter_device *const counter,
				  const enum counter_scope scope,
				  void *const parent,
				  const struct counter_comp *const comp,
				  const size_t idx, u64 *const value)
{
	const struct counter_array *const element = comp->priv;
	u32 value_u32 = 0;
	int ret;

	switch (element->type) {
	case COUNTER_COMP_SIGNAL_POLARITY:
		if (scope != COUNTER_SCOPE_SIGNAL)
			return -EINVAL;
		ret = comp->signal_array_u32_read(counter, parent, idx,
						  &value_u32);
		*value = value_u32;
		return ret;
	case COUNTER_COMP_U64:
		switch (scope) {
		case COUNTER_SCOPE_DEVICE:
			return comp->device_array_u64_read(counter, idx, value);
		case COUNTER_SCOPE_SIGNAL:
			return comp->signal_array_u64_read(counter, parent, idx,
							   value);
		case COUNTER_SCOPE_COUNT:
			return comp->count_array_u64_read(counter, parent, idx,
							  value);
		default:
			return -EINVAL;
		}
	default:
		return -EINVAL;
	}
}

static int counter_get_data(struct counter_device *const counter,
			    const struct counter_comp_node *const comp_node,
			    u64 *const value)
{
	const struct counter_comp *const comp = &comp_node->comp;
	const enum counter_scope scope = comp_node->component.scope;
	const size_t id = comp_node->component.id;
	struct counter_signal *const signal = comp_node->parent;
	struct counter_count *const count = comp_node->parent;
	u8 value_u8 = 0;
	u32 value_u32 = 0;
	const struct counter_comp *ext;
	size_t num_ext;
	size_t ext_idx, ext_id;
	int ret;

	if (comp_node->component.type == COUNTER_COMPONENT_NONE)
		return 0;

	switch (comp->type) {
	case COUNTER_COMP_U8:
	case COUNTER_COMP_BOOL:
		switch (scope) {
		case COUNTER_SCOPE_DEVICE:
			ret = comp->device_u8_read(counter, &value_u8);
			break;
		case COUNTER_SCOPE_SIGNAL:
			ret = comp->signal_u8_read(counter, signal, &value_u8);
			break;
		case COUNTER_SCOPE_COUNT:
			ret = comp->count_u8_read(counter, count, &value_u8);
			break;
		default:
			return -EINVAL;
		}
		*value = value_u8;
		return ret;
	case COUNTER_COMP_SIGNAL_LEVEL:
	case COUNTER_COMP_FUNCTION:
	case COUNTER_COMP_ENUM:
	case COUNTER_COMP_COUNT_DIRECTION:
	case COUNTER_COMP_COUNT_MODE:
	case COUNTER_COMP_SIGNAL_POLARITY:
		switch (scope) {
		case COUNTER_SCOPE_DEVICE:
			ret = comp->device_u32_read(counter, &value_u32);
			break;
		case COUNTER_SCOPE_SIGNAL:
			ret = comp->signal_u32_read(counter, signal,
						    &value_u32);
			break;
		case COUNTER_SCOPE_COUNT:
			ret = comp->count_u32_read(counter, count, &value_u32);
			break;
		default:
			return -EINVAL;
		}
		*value = value_u32;
		return ret;
	case COUNTER_COMP_U64:
		switch (scope) {
		case COUNTER_SCOPE_DEVICE:
			return comp->device_u64_read(counter, value);
		case COUNTER_SCOPE_SIGNAL:
			return comp->signal_u64_read(counter, signal, value);
		case COUNTER_SCOPE_COUNT:
			return comp->count_u64_read(counter, count, value);
		default:
			return -EINVAL;
		}
	case COUNTER_COMP_SYNAPSE_ACTION:
		ret = comp->action_read(counter, count, comp->priv, &value_u32);
		*value = value_u32;
		return ret;
	case COUNTER_COMP_ARRAY:
		switch (scope) {
		case COUNTER_SCOPE_DEVICE:
			ext = counter->ext;
			num_ext = counter->num_ext;
			break;
		case COUNTER_SCOPE_SIGNAL:
			ext = signal->ext;
			num_ext = signal->num_ext;
			break;
		case COUNTER_SCOPE_COUNT:
			ext = count->ext;
			num_ext = count->num_ext;
			break;
		default:
			return -EINVAL;
		}
		ret = counter_get_ext(ext, num_ext, id, &ext_idx, &ext_id);
		if (ret < 0)
			return ret;

		return counter_get_array_data(counter, scope, comp_node->parent,
					      comp, id - ext_id, value);
	default:
		return -EINVAL;
	}
}

/**
 * counter_push_event - queue event for userspace reading
 * @counter:	pointer to Counter structure
 * @event:	triggered event
 * @channel:	event channel
 *
 * Note: If no one is watching for the respective event, it is silently
 * discarded.
 */
void counter_push_event(struct counter_device *const counter, const u8 event,
			const u8 channel)
{
	struct counter_event ev;
	unsigned int copied = 0;
	unsigned long flags;
	struct counter_event_node *event_node;
	struct counter_comp_node *comp_node;

	ev.timestamp = ktime_get_ns();
	ev.watch.event = event;
	ev.watch.channel = channel;

	/* Could be in an interrupt context, so use a spin lock */
	spin_lock_irqsave(&counter->events_list_lock, flags);

	/* Search for event in the list */
	list_for_each_entry(event_node, &counter->events_list, l)
		if (event_node->event == event &&
		    event_node->channel == channel)
			break;

	/* If event is not in the list */
	if (&event_node->l == &counter->events_list)
		goto exit_early;

	/* Read and queue relevant comp for userspace */
	list_for_each_entry(comp_node, &event_node->comp_list, l) {
		ev.watch.component = comp_node->component;
		ev.status = -counter_get_data(counter, comp_node, &ev.value);

		copied += kfifo_in_spinlocked_noirqsave(&counter->events, &ev,
							1, &counter->events_in_lock);
	}

exit_early:
	spin_unlock_irqrestore(&counter->events_list_lock, flags);

	if (copied)
		wake_up_poll(&counter->events_wait, EPOLLIN);
}
EXPORT_SYMBOL_NS_GPL(counter_push_event, "COUNTER");
