/*
 * ring buffer based C-state tracer
 *
 * Arjan van de Ven <arjan@linux.intel.com>
 * Copyright (C) 2008 Intel Corporation
 *
 * Much is borrowed from trace_boot.c which is
 * Copyright (C) 2008 Frederic Weisbecker <fweisbec@gmail.com>
 *
 */

#include <linux/init.h>
#include <linux/debugfs.h>
#include <trace/power.h>
#include <linux/kallsyms.h>
#include <linux/module.h>

#include "trace.h"
#include "trace_output.h"

static struct trace_array *power_trace;
static int __read_mostly trace_power_enabled;

static void probe_power_start(struct power_trace *it, unsigned int type,
				unsigned int level)
{
	if (!trace_power_enabled)
		return;

	memset(it, 0, sizeof(struct power_trace));
	it->state = level;
	it->type = type;
	it->stamp = ktime_get();
}


static void probe_power_end(struct power_trace *it)
{
	struct ftrace_event_call *call = &event_power;
	struct ring_buffer_event *event;
	struct ring_buffer *buffer;
	struct trace_power *entry;
	struct trace_array_cpu *data;
	struct trace_array *tr = power_trace;

	if (!trace_power_enabled)
		return;

	buffer = tr->buffer;

	preempt_disable();
	it->end = ktime_get();
	data = tr->data[smp_processor_id()];

	event = trace_buffer_lock_reserve(buffer, TRACE_POWER,
					  sizeof(*entry), 0, 0);
	if (!event)
		goto out;
	entry	= ring_buffer_event_data(event);
	entry->state_data = *it;
	if (!filter_check_discard(call, entry, buffer, event))
		trace_buffer_unlock_commit(buffer, event, 0, 0);
 out:
	preempt_enable();
}

static void probe_power_mark(struct power_trace *it, unsigned int type,
				unsigned int level)
{
	struct ftrace_event_call *call = &event_power;
	struct ring_buffer_event *event;
	struct ring_buffer *buffer;
	struct trace_power *entry;
	struct trace_array_cpu *data;
	struct trace_array *tr = power_trace;

	if (!trace_power_enabled)
		return;

	buffer = tr->buffer;

	memset(it, 0, sizeof(struct power_trace));
	it->state = level;
	it->type = type;
	it->stamp = ktime_get();
	preempt_disable();
	it->end = it->stamp;
	data = tr->data[smp_processor_id()];

	event = trace_buffer_lock_reserve(buffer, TRACE_POWER,
					  sizeof(*entry), 0, 0);
	if (!event)
		goto out;
	entry	= ring_buffer_event_data(event);
	entry->state_data = *it;
	if (!filter_check_discard(call, entry, buffer, event))
		trace_buffer_unlock_commit(buffer, event, 0, 0);
 out:
	preempt_enable();
}

static int tracing_power_register(void)
{
	int ret;

	ret = register_trace_power_start(probe_power_start);
	if (ret) {
		pr_info("power trace: Couldn't activate tracepoint"
			" probe to trace_power_start\n");
		return ret;
	}
	ret = register_trace_power_end(probe_power_end);
	if (ret) {
		pr_info("power trace: Couldn't activate tracepoint"
			" probe to trace_power_end\n");
		goto fail_start;
	}
	ret = register_trace_power_mark(probe_power_mark);
	if (ret) {
		pr_info("power trace: Couldn't activate tracepoint"
			" probe to trace_power_mark\n");
		goto fail_end;
	}
	return ret;
fail_end:
	unregister_trace_power_end(probe_power_end);
fail_start:
	unregister_trace_power_start(probe_power_start);
	return ret;
}

static void start_power_trace(struct trace_array *tr)
{
	trace_power_enabled = 1;
}

static void stop_power_trace(struct trace_array *tr)
{
	trace_power_enabled = 0;
}

static void power_trace_reset(struct trace_array *tr)
{
	trace_power_enabled = 0;
	unregister_trace_power_start(probe_power_start);
	unregister_trace_power_end(probe_power_end);
	unregister_trace_power_mark(probe_power_mark);
}


static int power_trace_init(struct trace_array *tr)
{
	power_trace = tr;

	trace_power_enabled = 1;
	tracing_power_register();

	tracing_reset_online_cpus(tr);
	return 0;
}

static enum print_line_t power_print_line(struct trace_iterator *iter)
{
	int ret = 0;
	struct trace_entry *entry = iter->ent;
	struct trace_power *field ;
	struct power_trace *it;
	struct trace_seq *s = &iter->seq;
	struct timespec stamp;
	struct timespec duration;

	trace_assign_type(field, entry);
	it = &field->state_data;
	stamp = ktime_to_timespec(it->stamp);
	duration = ktime_to_timespec(ktime_sub(it->end, it->stamp));

	if (entry->type == TRACE_POWER) {
		if (it->type == POWER_CSTATE)
			ret = trace_seq_printf(s, "[%5ld.%09ld] CSTATE: Going to C%i on cpu %i for %ld.%09ld\n",
					  stamp.tv_sec,
					  stamp.tv_nsec,
					  it->state, iter->cpu,
					  duration.tv_sec,
					  duration.tv_nsec);
		if (it->type == POWER_PSTATE)
			ret = trace_seq_printf(s, "[%5ld.%09ld] PSTATE: Going to P%i on cpu %i\n",
					  stamp.tv_sec,
					  stamp.tv_nsec,
					  it->state, iter->cpu);
		if (!ret)
			return TRACE_TYPE_PARTIAL_LINE;
		return TRACE_TYPE_HANDLED;
	}
	return TRACE_TYPE_UNHANDLED;
}

static void power_print_header(struct seq_file *s)
{
	seq_puts(s, "#   TIMESTAMP      STATE  EVENT\n");
	seq_puts(s, "#       |            |      |\n");
}

static struct tracer power_tracer __read_mostly =
{
	.name		= "power",
	.init		= power_trace_init,
	.start		= start_power_trace,
	.stop		= stop_power_trace,
	.reset		= power_trace_reset,
	.print_line	= power_print_line,
	.print_header	= power_print_header,
};

static int init_power_trace(void)
{
	return register_tracer(&power_tracer);
}
device_initcall(init_power_trace);
