Commit 70179969 authored by Pi-Hsun Shih's avatar Pi-Hsun Shih Committed by Bjorn Andersson
Browse files

rpmsg: add rpmsg support for mt8183 SCP.



Add a simple rpmsg support for mt8183 SCP, that use IPI / IPC directly.

Signed-off-by: default avatarPi-Hsun Shih <pihsun@chromium.org>
Link: https://lore.kernel.org/r/20191112110330.179649-4-pihsun@chromium.org


Signed-off-by: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
parent 63c13d61
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ config IMX_REMOTEPROC
config MTK_SCP
	tristate "Mediatek SCP support"
	depends on ARCH_MEDIATEK
	select RPMSG_MTK_SCP
	help
	  Say y here to support Mediatek's System Companion Processor (SCP) via
	  the remote processor framework.
+2 −0
Original line number Diff line number Diff line
@@ -70,6 +70,8 @@ struct mtk_scp {
	void __iomem *cpu_addr;
	phys_addr_t phys_addr;
	size_t dram_size;

	struct rproc_subdev *rpmsg_subdev;
};

/**
+57 −4
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#include <linux/platform_device.h>
#include <linux/remoteproc.h>
#include <linux/remoteproc/mtk_scp.h>
#include <linux/rpmsg/mtk_rpmsg.h>

#include "mtk_common.h"
#include "remoteproc_internal.h"
@@ -464,6 +465,54 @@ static void scp_unmap_memory_region(struct mtk_scp *scp)
	of_reserved_mem_device_release(scp->dev);
}

static int scp_register_ipi(struct platform_device *pdev, u32 id,
			    ipi_handler_t handler, void *priv)
{
	struct mtk_scp *scp = platform_get_drvdata(pdev);

	return scp_ipi_register(scp, id, handler, priv);
}

static void scp_unregister_ipi(struct platform_device *pdev, u32 id)
{
	struct mtk_scp *scp = platform_get_drvdata(pdev);

	scp_ipi_unregister(scp, id);
}

static int scp_send_ipi(struct platform_device *pdev, u32 id, void *buf,
			unsigned int len, unsigned int wait)
{
	struct mtk_scp *scp = platform_get_drvdata(pdev);

	return scp_ipi_send(scp, id, buf, len, wait);
}

static struct mtk_rpmsg_info mtk_scp_rpmsg_info = {
	.send_ipi = scp_send_ipi,
	.register_ipi = scp_register_ipi,
	.unregister_ipi = scp_unregister_ipi,
	.ns_ipi_id = SCP_IPI_NS_SERVICE,
};

static void scp_add_rpmsg_subdev(struct mtk_scp *scp)
{
	scp->rpmsg_subdev =
		mtk_rpmsg_create_rproc_subdev(to_platform_device(scp->dev),
					      &mtk_scp_rpmsg_info);
	if (scp->rpmsg_subdev)
		rproc_add_subdev(scp->rproc, scp->rpmsg_subdev);
}

static void scp_remove_rpmsg_subdev(struct mtk_scp *scp)
{
	if (scp->rpmsg_subdev) {
		rproc_remove_subdev(scp->rproc, scp->rpmsg_subdev);
		mtk_rpmsg_destroy_rproc_subdev(scp->rpmsg_subdev);
		scp->rpmsg_subdev = NULL;
	}
}

static int scp_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
@@ -544,22 +593,25 @@ static int scp_probe(struct platform_device *pdev)
	init_waitqueue_head(&scp->run.wq);
	init_waitqueue_head(&scp->ack_wq);

	scp_add_rpmsg_subdev(scp);

	ret = devm_request_threaded_irq(dev, platform_get_irq(pdev, 0), NULL,
					scp_irq_handler, IRQF_ONESHOT,
					pdev->name, scp);

	if (ret) {
		dev_err(dev, "failed to request irq\n");
		goto unregister_ipi;
		goto remove_subdev;
	}

	ret = rproc_add(rproc);
	if (ret)
		goto unregister_ipi;
		goto remove_subdev;

	return ret;
	return 0;

unregister_ipi:
remove_subdev:
	scp_remove_rpmsg_subdev(scp);
	scp_ipi_unregister(scp, SCP_IPI_INIT);
release_dev_mem:
	scp_unmap_memory_region(scp);
@@ -579,6 +631,7 @@ static int scp_remove(struct platform_device *pdev)
	int i;

	rproc_del(scp->rproc);
	scp_remove_rpmsg_subdev(scp);
	scp_ipi_unregister(scp, SCP_IPI_INIT);
	scp_unmap_memory_region(scp);
	for (i = 0; i < SCP_IPI_MAX; i++)
+1 −0
Original line number Diff line number Diff line
@@ -162,6 +162,7 @@ int scp_ipi_send(struct mtk_scp *scp, u32 id, void *buf, unsigned int len,
	int ret;

	if (WARN_ON(id <= SCP_IPI_INIT) || WARN_ON(id >= SCP_IPI_MAX) ||
	    WARN_ON(id == SCP_IPI_NS_SERVICE) ||
	    WARN_ON(len > sizeof(send_obj->share_buf)) || WARN_ON(!buf))
		return -EINVAL;

+9 −0
Original line number Diff line number Diff line
@@ -15,6 +15,15 @@ config RPMSG_CHAR
	  in /dev. They make it possible for user-space programs to send and
	  receive rpmsg packets.

config RPMSG_MTK_SCP
	tristate "MediaTek SCP"
	depends on MTK_SCP
	select RPMSG
	help
	  Say y here to enable support providing communication channels to
	  remote processors in MediaTek platforms.
	  This use IPI and IPC to communicate with remote processors.

config RPMSG_QCOM_GLINK_NATIVE
	tristate
	select RPMSG
Loading