// SPDX-License-Identifier: GPL-2.0
/*
 * Simple heartbeat STM source driver
 * Copyright (c) 2016, Intel Corporation.
 *
 * 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, 0400);
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 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;

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

	for (i = 0; i < nr_devs; 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;
	}

	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_devs; 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>");
