// SPDX-License-Identifier: GPL-2.0
/*
 * Platform driver for CDX bus.
 *
 * Copyright (C) 2022-2023, Advanced Micro Devices, Inc.
 */

#include <linux/rpmsg.h>
#include <linux/remoteproc.h>
#include <linux/of_platform.h>
#include <linux/cdx/cdx_bus.h>
#include <linux/module.h>

#include "../cdx.h"
#include "cdx_controller.h"
#include "mcdi_functions.h"
#include "mcdi.h"

static struct rpmsg_device_id cdx_rpmsg_id_table[] = {
	{ .name = "mcdi_ipc" },
	{ },
};
MODULE_DEVICE_TABLE(rpmsg, cdx_rpmsg_id_table);

int cdx_rpmsg_send(struct cdx_mcdi *cdx_mcdi,
		   const struct cdx_dword *hdr, size_t hdr_len,
		   const struct cdx_dword *sdu, size_t sdu_len)
{
	unsigned char *send_buf;
	int ret;

	send_buf = kzalloc(hdr_len + sdu_len, GFP_KERNEL);
	if (!send_buf)
		return -ENOMEM;

	memcpy(send_buf, hdr, hdr_len);
	memcpy(send_buf + hdr_len, sdu, sdu_len);

	ret = rpmsg_send(cdx_mcdi->ept, send_buf, hdr_len + sdu_len);
	kfree(send_buf);

	return ret;
}

static int cdx_attach_to_rproc(struct platform_device *pdev)
{
	struct device_node *r5_core_node;
	struct cdx_controller *cdx_c;
	struct cdx_mcdi *cdx_mcdi;
	struct device *dev;
	struct rproc *rp;
	int ret;

	dev = &pdev->dev;
	cdx_c = platform_get_drvdata(pdev);
	cdx_mcdi = cdx_c->priv;

	r5_core_node = of_parse_phandle(dev->of_node, "xlnx,rproc", 0);
	if (!r5_core_node) {
		dev_err(&pdev->dev, "xlnx,rproc: invalid phandle\n");
		return -EINVAL;
	}

	rp = rproc_get_by_phandle(r5_core_node->phandle);
	if (!rp) {
		ret = -EPROBE_DEFER;
		goto pdev_err;
	}

	/* Attach to remote processor */
	ret = rproc_boot(rp);
	if (ret) {
		dev_err(&pdev->dev, "Failed to attach to remote processor\n");
		rproc_put(rp);
		goto pdev_err;
	}

	cdx_mcdi->r5_rproc = rp;
pdev_err:
	of_node_put(r5_core_node);
	return ret;
}

static void cdx_detach_to_r5(struct platform_device *pdev)
{
	struct cdx_controller *cdx_c;
	struct cdx_mcdi *cdx_mcdi;

	cdx_c = platform_get_drvdata(pdev);
	cdx_mcdi = cdx_c->priv;

	rproc_detach(cdx_mcdi->r5_rproc);
	rproc_put(cdx_mcdi->r5_rproc);
}

static int cdx_rpmsg_cb(struct rpmsg_device *rpdev, void *data,
			int len, void *priv, u32 src)
{
	struct cdx_controller *cdx_c = dev_get_drvdata(&rpdev->dev);
	struct cdx_mcdi *cdx_mcdi = cdx_c->priv;

	if (len > MCDI_BUF_LEN)
		return -EINVAL;

	cdx_mcdi_process_cmd(cdx_mcdi, (struct cdx_dword *)data, len);

	return 0;
}

static void cdx_rpmsg_post_probe_work(struct work_struct *work)
{
	struct cdx_controller *cdx_c;
	struct cdx_mcdi *cdx_mcdi;

	cdx_mcdi = container_of(work, struct cdx_mcdi, work);
	cdx_c = dev_get_drvdata(&cdx_mcdi->rpdev->dev);
	cdx_rpmsg_post_probe(cdx_c);
}

static int cdx_rpmsg_probe(struct rpmsg_device *rpdev)
{
	struct rpmsg_channel_info chinfo = {0};
	struct cdx_controller *cdx_c;
	struct cdx_mcdi *cdx_mcdi;

	cdx_c = (struct cdx_controller *)cdx_rpmsg_id_table[0].driver_data;
	cdx_mcdi = cdx_c->priv;

	chinfo.src = RPMSG_ADDR_ANY;
	chinfo.dst = rpdev->dst;
	strscpy(chinfo.name, cdx_rpmsg_id_table[0].name,
		strlen(cdx_rpmsg_id_table[0].name));

	cdx_mcdi->ept = rpmsg_create_ept(rpdev, cdx_rpmsg_cb, NULL, chinfo);
	if (!cdx_mcdi->ept) {
		dev_err_probe(&rpdev->dev, -ENXIO,
			      "Failed to create ept for channel %s\n",
			      chinfo.name);
		return -EINVAL;
	}

	cdx_mcdi->rpdev = rpdev;
	dev_set_drvdata(&rpdev->dev, cdx_c);

	schedule_work(&cdx_mcdi->work);
	return 0;
}

static void cdx_rpmsg_remove(struct rpmsg_device *rpdev)
{
	struct cdx_controller *cdx_c = dev_get_drvdata(&rpdev->dev);
	struct cdx_mcdi *cdx_mcdi = cdx_c->priv;

	flush_work(&cdx_mcdi->work);
	cdx_rpmsg_pre_remove(cdx_c);

	rpmsg_destroy_ept(cdx_mcdi->ept);
	dev_set_drvdata(&rpdev->dev, NULL);
}

static struct rpmsg_driver cdx_rpmsg_driver = {
	.drv.name = KBUILD_MODNAME,
	.id_table = cdx_rpmsg_id_table,
	.probe = cdx_rpmsg_probe,
	.remove = cdx_rpmsg_remove,
	.callback = cdx_rpmsg_cb,
};

int cdx_setup_rpmsg(struct platform_device *pdev)
{
	struct cdx_controller *cdx_c;
	struct cdx_mcdi *cdx_mcdi;
	int ret;

	/* Attach to remote processor */
	ret = cdx_attach_to_rproc(pdev);
	if (ret)
		return ret;

	cdx_c = platform_get_drvdata(pdev);
	cdx_mcdi = cdx_c->priv;

	/* Register RPMsg driver */
	cdx_rpmsg_id_table[0].driver_data = (kernel_ulong_t)cdx_c;

	INIT_WORK(&cdx_mcdi->work, cdx_rpmsg_post_probe_work);
	ret = register_rpmsg_driver(&cdx_rpmsg_driver);
	if (ret) {
		dev_err(&pdev->dev,
			"Failed to register cdx RPMsg driver: %d\n", ret);
		cdx_detach_to_r5(pdev);
	}

	return ret;
}

void cdx_destroy_rpmsg(struct platform_device *pdev)
{
	unregister_rpmsg_driver(&cdx_rpmsg_driver);

	cdx_detach_to_r5(pdev);
}
