/* Copyright (c) 2011-2017, 2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#include <linux/slab.h>
#include <linux/list.h>
#include <linux/workqueue.h>
#include <linux/debugfs.h>
#include <kgsl_device.h>

#include "kgsl_debugfs.h"
#include "kgsl_trace.h"

/*
 * Define an kmem cache for the event structures since we allocate and free them
 * so frequently
 */
static struct kmem_cache *events_cache;
static struct dentry *events_dentry;

static inline void signal_event(struct kgsl_device *device,
		struct kgsl_event *event, int result)
{
	list_del(&event->node);
	event->result = result;
	queue_work(device->events_wq, &event->work);
}

/**
 * _kgsl_event_worker() - Work handler for processing GPU event callbacks
 * @work: Pointer to the work_struct for the event
 *
 * Each event callback has its own work struct and is run on a event specific
 * workqeuue.  This is the worker that queues up the event callback function.
 */
static void _kgsl_event_worker(struct work_struct *work)
{
	struct kgsl_event *event = container_of(work, struct kgsl_event, work);
	int id = KGSL_CONTEXT_ID(event->context);

	trace_kgsl_fire_event(id, event->timestamp, event->result,
		jiffies - event->created, event->func);

	event->func(event->device, event->group, event->priv, event->result);

	kgsl_context_put(event->context);
	kmem_cache_free(events_cache, event);
}

/* return true if the group needs to be processed */
static bool _do_process_group(unsigned int processed, unsigned int cur)
{
	if (processed == cur)
		return false;

	/*
	 * This ensures that the timestamp didn't slip back accidently, maybe
	 * due to a memory barrier issue. This is highly unlikely but we've
	 * been burned here in the past.
	 */
	if ((cur < processed) && ((processed - cur) < KGSL_TIMESTAMP_WINDOW))
		return false;

	return true;
}

static void _process_event_group(struct kgsl_device *device,
		struct kgsl_event_group *group, bool flush)
{
	struct kgsl_event *event, *tmp;
	unsigned int timestamp;
	struct kgsl_context *context;

	if (group == NULL)
		return;

	context = group->context;

	/*
	 * Sanity check to be sure that we we aren't racing with the context
	 * getting destroyed
	 */
	if (context != NULL && !_kgsl_context_get(context)) {
		WARN_ON(1);
		return;
	}

	spin_lock(&group->lock);

	group->readtimestamp(device, group->priv, KGSL_TIMESTAMP_RETIRED,
		&timestamp);

	if (!flush && _do_process_group(group->processed, timestamp) == false)
		goto out;

	list_for_each_entry_safe(event, tmp, &group->events, node) {
		if (timestamp_cmp(event->timestamp, timestamp) <= 0)
			signal_event(device, event, KGSL_EVENT_RETIRED);
		else if (flush)
			signal_event(device, event, KGSL_EVENT_CANCELLED);

	}

	group->processed = timestamp;

out:
	spin_unlock(&group->lock);
	kgsl_context_put(context);
}

/**
 * kgsl_process_event_group() - Handle all the retired events in a group
 * @device: Pointer to a KGSL device
 * @group: Pointer to a GPU events group to process
 */

void kgsl_process_event_group(struct kgsl_device *device,
		struct kgsl_event_group *group)
{
	_process_event_group(device, group, false);
}
EXPORT_SYMBOL(kgsl_process_event_group);

/**
 * kgsl_flush_event_group() - flush all the events in a group by retiring the
 * ones can be retired and cancelling the ones that are pending
 * @device: Pointer to a KGSL device
 * @group: Pointer to a GPU events group to process
 */
void kgsl_flush_event_group(struct kgsl_device *device,
		struct kgsl_event_group *group)
{
	_process_event_group(device, group, true);
}
EXPORT_SYMBOL(kgsl_flush_event_group);

/**
 * kgsl_cancel_events_timestamp() - Cancel pending events for a given timestamp
 * @device: Pointer to a KGSL device
 * @group: Ponter to the GPU event group that owns the event
 * @timestamp: Registered expiry timestamp for the event
 */
void kgsl_cancel_events_timestamp(struct kgsl_device *device,
		struct kgsl_event_group *group, unsigned int timestamp)
{
	struct kgsl_event *event, *tmp;

	spin_lock(&group->lock);

	list_for_each_entry_safe(event, tmp, &group->events, node) {
		if (timestamp_cmp(timestamp, event->timestamp) == 0)
			signal_event(device, event, KGSL_EVENT_CANCELLED);
	}

	spin_unlock(&group->lock);
}
EXPORT_SYMBOL(kgsl_cancel_events_timestamp);

/**
 * kgsl_cancel_events() - Cancel all pending events in the group
 * @device: Pointer to a KGSL device
 * @group: Pointer to a kgsl_events_group
 */
void kgsl_cancel_events(struct kgsl_device *device,
		struct kgsl_event_group *group)
{
	struct kgsl_event *event, *tmp;

	spin_lock(&group->lock);

	list_for_each_entry_safe(event, tmp, &group->events, node)
		signal_event(device, event, KGSL_EVENT_CANCELLED);

	spin_unlock(&group->lock);
}
EXPORT_SYMBOL(kgsl_cancel_events);

/**
 * kgsl_cancel_event() - Cancel a specific event from a group
 * @device: Pointer to a KGSL device
 * @group: Pointer to the group that contains the events
 * @timestamp: Registered expiry timestamp for the event
 * @func: Registered callback for the function
 * @priv: Registered priv data for the function
 */
void kgsl_cancel_event(struct kgsl_device *device,
		struct kgsl_event_group *group, unsigned int timestamp,
		kgsl_event_func func, void *priv)
{
	struct kgsl_event *event, *tmp;

	spin_lock(&group->lock);

	list_for_each_entry_safe(event, tmp, &group->events, node) {
		if (timestamp == event->timestamp && func == event->func &&
			event->priv == priv)
			signal_event(device, event, KGSL_EVENT_CANCELLED);
	}

	spin_unlock(&group->lock);
}
EXPORT_SYMBOL(kgsl_cancel_event);

/**
 * kgsl_event_pending() - Searches for an event in an event group
 * @device: Pointer to a KGSL device
 * @group: Pointer to the group that contains the events
 * @timestamp: Registered expiry timestamp for the event
 * @func: Registered callback for the function
 * @priv: Registered priv data for the function
 */
bool kgsl_event_pending(struct kgsl_device *device,
		struct kgsl_event_group *group,
		unsigned int timestamp, kgsl_event_func func, void *priv)
{
	struct kgsl_event *event;
	bool result = false;

	spin_lock(&group->lock);
	list_for_each_entry(event, &group->events, node) {
		if (timestamp == event->timestamp && func == event->func &&
			event->priv == priv) {
			result = true;
			break;
		}
	}
	spin_unlock(&group->lock);
	return result;
}
/**
 * kgsl_add_event() - Add a new GPU event to a group
 * @device: Pointer to a KGSL device
 * @group: Pointer to the group to add the event to
 * @timestamp: Timestamp that the event will expire on
 * @func: Callback function for the event
 * @priv: Private data to send to the callback function
 */
int kgsl_add_event(struct kgsl_device *device, struct kgsl_event_group *group,
		unsigned int timestamp, kgsl_event_func func, void *priv)
{
	unsigned int queued;
	struct kgsl_context *context = group->context;
	struct kgsl_event *event;
	unsigned int retired;

	if (!func)
		return -EINVAL;

	/*
	 * If the caller is creating their own timestamps, let them schedule
	 * events in the future. Otherwise only allow timestamps that have been
	 * queued.
	 */
	if (!context || !(context->flags & KGSL_CONTEXT_USER_GENERATED_TS)) {
		group->readtimestamp(device, group->priv, KGSL_TIMESTAMP_QUEUED,
			&queued);

		if (timestamp_cmp(timestamp, queued) > 0)
			return -EINVAL;
	}

	event = kmem_cache_alloc(events_cache, GFP_KERNEL);
	if (event == NULL)
		return -ENOMEM;

	/* Get a reference to the context while the event is active */
	if (context != NULL && !_kgsl_context_get(context)) {
		kmem_cache_free(events_cache, event);
		return -ENOENT;
	}

	event->device = device;
	event->context = context;
	event->timestamp = timestamp;
	event->priv = priv;
	event->func = func;
	event->created = jiffies;
	event->group = group;

	INIT_WORK(&event->work, _kgsl_event_worker);

	trace_kgsl_register_event(KGSL_CONTEXT_ID(context), timestamp, func);

	spin_lock(&group->lock);

	/*
	 * Check to see if the requested timestamp has already retired.  If so,
	 * schedule the callback right away
	 */
	group->readtimestamp(device, group->priv, KGSL_TIMESTAMP_RETIRED,
		&retired);

	if (timestamp_cmp(retired, timestamp) >= 0) {
		event->result = KGSL_EVENT_RETIRED;
		queue_work(device->events_wq, &event->work);
		spin_unlock(&group->lock);
		return 0;
	}

	/* Add the event to the group list */
	list_add_tail(&event->node, &group->events);

	spin_unlock(&group->lock);

	return 0;
}
EXPORT_SYMBOL(kgsl_add_event);

static DEFINE_RWLOCK(group_lock);
static LIST_HEAD(group_list);

void kgsl_process_event_groups(struct kgsl_device *device)
{
	struct kgsl_event_group *group;

	read_lock(&group_lock);
	list_for_each_entry(group, &group_list, group)
		_process_event_group(device, group, false);
	read_unlock(&group_lock);
}
EXPORT_SYMBOL(kgsl_process_event_groups);

/**
 * kgsl_del_event_group() - Remove a GPU event group
 * @group: GPU event group to remove
 */
void kgsl_del_event_group(struct kgsl_event_group *group)
{
	/* Make sure that all the events have been deleted from the list */
	BUG_ON(!list_empty(&group->events));

	write_lock(&group_lock);
	list_del(&group->group);
	write_unlock(&group_lock);
}
EXPORT_SYMBOL(kgsl_del_event_group);

/**
 * kgsl_add_event_group() - Add a new GPU event group
 * group: Pointer to the new group to add to the list
 * context: Context that owns the group (or NULL for global)
 * name: Name of the group
 * readtimestamp: Function pointer to the readtimestamp function to call when
 * processing events
 * priv: Priv member to pass to the readtimestamp function
 */
void kgsl_add_event_group(struct kgsl_event_group *group,
		struct kgsl_context *context, const char *name,
		readtimestamp_func readtimestamp, void *priv)
{
	BUG_ON(readtimestamp == NULL);

	spin_lock_init(&group->lock);
	INIT_LIST_HEAD(&group->events);

	group->context = context;
	group->readtimestamp = readtimestamp;
	group->priv = priv;

	if (name)
		strlcpy(group->name, name, sizeof(group->name));

	write_lock(&group_lock);
	list_add_tail(&group->group, &group_list);
	write_unlock(&group_lock);
}
EXPORT_SYMBOL(kgsl_add_event_group);

static void events_debugfs_print_group(struct seq_file *s,
		struct kgsl_event_group *group)
{
	struct kgsl_event *event;
	unsigned int retired;

	spin_lock(&group->lock);

	seq_printf(s, "%s: last=%d\n", group->name, group->processed);

	list_for_each_entry(event, &group->events, node) {

		group->readtimestamp(event->device, group->priv,
			KGSL_TIMESTAMP_RETIRED, &retired);

		seq_printf(s, "\t%d:%d age=%lu func=%ps [retired=%d]\n",
			group->context ? group->context->id :
						KGSL_MEMSTORE_GLOBAL,
			event->timestamp, jiffies  - event->created,
			event->func, retired);
	}
	spin_unlock(&group->lock);
}

static int events_debugfs_print(struct seq_file *s, void *unused)
{
	struct kgsl_event_group *group;

	seq_puts(s, "event groups:\n");
	seq_puts(s, "--------------\n");

	read_lock(&group_lock);
	list_for_each_entry(group, &group_list, group) {
		events_debugfs_print_group(s, group);
		seq_puts(s, "\n");
	}
	read_unlock(&group_lock);

	return 0;
}

static int events_debugfs_open(struct inode *inode, struct file *file)
{
	return single_open(file, events_debugfs_print, NULL);
}

static const struct file_operations events_fops = {
	.open = events_debugfs_open,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = single_release,
};

/**
 * kgsl_events_exit() - Destroy the event kmem cache on module exit
 */
void kgsl_events_exit(void)
{
	kmem_cache_destroy(events_cache);

	debugfs_remove(events_dentry);
}

/**
 * kgsl_events_init() - Create the event kmem cache on module start
 */
void __init kgsl_events_init(void)
{
	struct dentry *debugfs_dir = kgsl_get_debugfs_dir();

	events_cache = KMEM_CACHE(kgsl_event, 0);

	events_dentry = debugfs_create_file("events", 0444, debugfs_dir, NULL,
		&events_fops);

	/* Failure to create a debugfs entry is non fatal */
	if (IS_ERR(events_dentry))
		events_dentry = NULL;
}
