// 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(sizeof(*event_node), GFP_KERNEL);
		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(sizeof(*comp_node), GFP_KERNEL);
	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->type == COUNTER_COMP_ARRAY) {
			element = ext->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,
	.llseek = no_llseek,
	.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);
