// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017, Linaro Ltd.
 */

#include <linux/completion.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/rpmsg.h>
#include <linux/rpmsg/qcom_glink.h>
#include <linux/remoteproc/qcom_rproc.h>

/**
 * struct do_cleanup_msg - The data structure for an SSR do_cleanup message
 * @version:	The G-Link SSR protocol version
 * @command:	The G-Link SSR command - do_cleanup
 * @seq_num:	Sequence number
 * @name_len:	Length of the name of the subsystem being restarted
 * @name:	G-Link edge name of the subsystem being restarted
 */
struct do_cleanup_msg {
	__le32 version;
	__le32 command;
	__le32 seq_num;
	__le32 name_len;
	char name[32];
};

/**
 * struct cleanup_done_msg - The data structure for an SSR cleanup_done message
 * @version:	The G-Link SSR protocol version
 * @response:	The G-Link SSR response to a do_cleanup command, cleanup_done
 * @seq_num:	Sequence number
 */
struct cleanup_done_msg {
	__le32 version;
	__le32 response;
	__le32 seq_num;
};

/*
 * G-Link SSR protocol commands
 */
#define GLINK_SSR_DO_CLEANUP	0
#define GLINK_SSR_CLEANUP_DONE	1

struct glink_ssr {
	struct device *dev;
	struct rpmsg_endpoint *ept;

	struct notifier_block nb;

	u32 seq_num;
	struct completion completion;
};

/* Notifier list for all registered glink_ssr instances */
static BLOCKING_NOTIFIER_HEAD(ssr_notifiers);

/**
 * qcom_glink_ssr_notify() - notify GLINK SSR about stopped remoteproc
 * @ssr_name:	name of the remoteproc that has been stopped
 */
void qcom_glink_ssr_notify(const char *ssr_name)
{
	blocking_notifier_call_chain(&ssr_notifiers, 0, (void *)ssr_name);
}
EXPORT_SYMBOL_GPL(qcom_glink_ssr_notify);

static int qcom_glink_ssr_callback(struct rpmsg_device *rpdev,
				   void *data, int len, void *priv, u32 addr)
{
	struct cleanup_done_msg *msg = data;
	struct glink_ssr *ssr = dev_get_drvdata(&rpdev->dev);

	if (len < sizeof(*msg)) {
		dev_err(ssr->dev, "message too short\n");
		return -EINVAL;
	}

	if (le32_to_cpu(msg->version) != 0)
		return -EINVAL;

	if (le32_to_cpu(msg->response) != GLINK_SSR_CLEANUP_DONE)
		return 0;

	if (le32_to_cpu(msg->seq_num) != ssr->seq_num) {
		dev_err(ssr->dev, "invalid sequence number of response\n");
		return -EINVAL;
	}

	complete(&ssr->completion);

	return 0;
}

static int qcom_glink_ssr_notifier_call(struct notifier_block *nb,
					unsigned long event,
					void *data)
{
	struct glink_ssr *ssr = container_of(nb, struct glink_ssr, nb);
	struct do_cleanup_msg msg;
	char *ssr_name = data;
	int ret;

	ssr->seq_num++;
	reinit_completion(&ssr->completion);

	memset(&msg, 0, sizeof(msg));
	msg.command = cpu_to_le32(GLINK_SSR_DO_CLEANUP);
	msg.seq_num = cpu_to_le32(ssr->seq_num);
	msg.name_len = cpu_to_le32(strlen(ssr_name));
	strscpy(msg.name, ssr_name, sizeof(msg.name));

	ret = rpmsg_send(ssr->ept, &msg, sizeof(msg));
	if (ret < 0)
		dev_err(ssr->dev, "failed to send cleanup message\n");

	ret = wait_for_completion_timeout(&ssr->completion, HZ);
	if (!ret)
		dev_err(ssr->dev, "timeout waiting for cleanup done message\n");

	return NOTIFY_DONE;
}

static int qcom_glink_ssr_probe(struct rpmsg_device *rpdev)
{
	struct glink_ssr *ssr;

	ssr = devm_kzalloc(&rpdev->dev, sizeof(*ssr), GFP_KERNEL);
	if (!ssr)
		return -ENOMEM;

	init_completion(&ssr->completion);

	ssr->dev = &rpdev->dev;
	ssr->ept = rpdev->ept;
	ssr->nb.notifier_call = qcom_glink_ssr_notifier_call;

	dev_set_drvdata(&rpdev->dev, ssr);

	return blocking_notifier_chain_register(&ssr_notifiers, &ssr->nb);
}

static void qcom_glink_ssr_remove(struct rpmsg_device *rpdev)
{
	struct glink_ssr *ssr = dev_get_drvdata(&rpdev->dev);

	blocking_notifier_chain_unregister(&ssr_notifiers, &ssr->nb);
}

static const struct rpmsg_device_id qcom_glink_ssr_match[] = {
	{ "glink_ssr" },
	{}
};
MODULE_DEVICE_TABLE(rpmsg, qcom_glink_ssr_match);

static struct rpmsg_driver qcom_glink_ssr_driver = {
	.probe = qcom_glink_ssr_probe,
	.remove = qcom_glink_ssr_remove,
	.callback = qcom_glink_ssr_callback,
	.id_table = qcom_glink_ssr_match,
	.drv = {
		.name = "qcom_glink_ssr",
	},
};
module_rpmsg_driver(qcom_glink_ssr_driver);
