/*
 * Simple heartbeat STM source driver
 * Copyright (c) 2016, Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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.
 *
 * Heartbeat STM source will send repetitive messages over STM devices to a
 * trace host.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/hrtimer.h>
#include <linux/slab.h>
#include <linux/stm.h>

#define STM_HEARTBEAT_MAX	32

static int nr_devs = 4;
static int interval_ms = 10;

module_param(nr_devs, int, 0600);
module_param(interval_ms, int, 0600);

static struct stm_heartbeat {
	struct stm_source_data	data;
	struct hrtimer		hrtimer;
	unsigned int		active;
} stm_heartbeat[STM_HEARTBEAT_MAX];

static unsigned int nr_instances;

static const char str[] = "heartbeat stm source driver is here to serve you";

static enum hrtimer_restart stm_heartbeat_hrtimer_handler(struct hrtimer *hr)
{
	struct stm_heartbeat *heartbeat = container_of(hr, struct stm_heartbeat,
						       hrtimer);

	stm_source_write(&heartbeat->data, 0, str, sizeof str);
	if (heartbeat->active)
		hrtimer_forward_now(hr, ms_to_ktime(interval_ms));

	return heartbeat->active ? HRTIMER_RESTART : HRTIMER_NORESTART;
}

static int stm_heartbeat_link(struct stm_source_data *data)
{
	struct stm_heartbeat *heartbeat =
		container_of(data, struct stm_heartbeat, data);

	heartbeat->active = 1;
	hrtimer_start(&heartbeat->hrtimer, ms_to_ktime(interval_ms),
		      HRTIMER_MODE_ABS);

	return 0;
}

static void stm_heartbeat_unlink(struct stm_source_data *data)
{
	struct stm_heartbeat *heartbeat =
		container_of(data, struct stm_heartbeat, data);

	heartbeat->active = 0;
	hrtimer_cancel(&heartbeat->hrtimer);
}

static int stm_heartbeat_init(void)
{
	int i, ret = -ENOMEM, __nr_instances = ACCESS_ONCE(nr_devs);

	if (__nr_instances < 0 || __nr_instances > STM_HEARTBEAT_MAX)
		return -EINVAL;

	for (i = 0; i < __nr_instances; i++) {
		stm_heartbeat[i].data.name =
			kasprintf(GFP_KERNEL, "heartbeat.%d", i);
		if (!stm_heartbeat[i].data.name)
			goto fail_unregister;

		stm_heartbeat[i].data.nr_chans	= 1;
		stm_heartbeat[i].data.link		= stm_heartbeat_link;
		stm_heartbeat[i].data.unlink	= stm_heartbeat_unlink;
		hrtimer_init(&stm_heartbeat[i].hrtimer, CLOCK_MONOTONIC,
			     HRTIMER_MODE_ABS);
		stm_heartbeat[i].hrtimer.function =
			stm_heartbeat_hrtimer_handler;

		ret = stm_source_register_device(NULL, &stm_heartbeat[i].data);
		if (ret)
			goto fail_free;
	}

	nr_instances = __nr_instances;

	return 0;

fail_unregister:
	for (i--; i >= 0; i--) {
		stm_source_unregister_device(&stm_heartbeat[i].data);
fail_free:
		kfree(stm_heartbeat[i].data.name);
	}

	return ret;
}

static void stm_heartbeat_exit(void)
{
	int i;

	for (i = 0; i < nr_instances; i++) {
		stm_source_unregister_device(&stm_heartbeat[i].data);
		kfree(stm_heartbeat[i].data.name);
	}
}

module_init(stm_heartbeat_init);
module_exit(stm_heartbeat_exit);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("stm_heartbeat driver");
MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@linux.intel.com>");
