Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f79d90f5 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "mailbox: Add new mailbox for gvm"

parents ae86dc11 78f5f831
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -132,6 +132,16 @@ config QCOM_APCS_IPC
	  providing an interface for invoking the inter-process communication
	  signals from the application processor to other masters.

config QCOM_GVM_IPC
	tristate "Qualcomm Technologies, Inc. GVM IPC driver"
	depends on ARCH_QCOM
	help
	  Say y here to enable support for the GVM IPC mailbox driver,
	  This driver will providing an interface for invoking the communication
	  between GVM and primary host through virtual IRQ line. It signals from
	  the GVM to primary host and primary host will send different signal to
	  remote sub system.

config TEGRA_HSP_MBOX
	bool "Tegra HSP (Hardware Synchronization Primitives) Driver"
	depends on ARCH_TEGRA_186_SOC
+2 −0
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@ obj-$(CONFIG_BCM_FLEXRM_MBOX) += bcm-flexrm-mailbox.o

obj-$(CONFIG_QCOM_APCS_IPC)	+= qcom-apcs-ipc-mailbox.o

obj-$(CONFIG_QCOM_GVM_IPC)	+= qcom-gvm-ipc-mailbox.o

obj-$(CONFIG_TEGRA_HSP_MBOX)	+= tegra-hsp.o

obj-$(CONFIG_QTI_RPMH_MBOX)	+= qcom-rpmh-mailbox.o
+126 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2020, The Linux Foundation, All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that 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.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/mailbox_controller.h>

#define QCOM_GVM_CHNL	32

struct qcom_gvm_ipc {
	struct mbox_controller mbox;
	struct mbox_chan mbox_chans[QCOM_GVM_CHNL];

	void __iomem *reg;
	unsigned long offset;
};

static int qcom_gvm_ipc_send_data(struct mbox_chan *chan, void *data)
{
	struct qcom_gvm_ipc *gvm_ipc = container_of(chan->mbox,
						  struct qcom_gvm_ipc, mbox);

	__raw_writel(1, gvm_ipc->reg);

	return 0;
}

static const struct mbox_chan_ops qcom_gvm_ipc_ops = {
	.send_data = qcom_gvm_ipc_send_data,
};

static int qcom_gvm_ipc_probe(struct platform_device *pdev)
{
	struct qcom_gvm_ipc *gvm_ipc;
	struct resource *res;
	void __iomem *base;
	unsigned long i;
	int ret;

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

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENODEV;
	base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
	if (IS_ERR(base))
		return PTR_ERR(base);

	gvm_ipc->reg = base;
	/* Initialize channel identifiers */
	for (i = 0; i < ARRAY_SIZE(gvm_ipc->mbox_chans); i++)
		gvm_ipc->mbox_chans[i].con_priv = (void *)i;

	gvm_ipc->mbox.dev = &pdev->dev;
	gvm_ipc->mbox.ops = &qcom_gvm_ipc_ops;
	gvm_ipc->mbox.chans = gvm_ipc->mbox_chans;
	gvm_ipc->mbox.num_chans = ARRAY_SIZE(gvm_ipc->mbox_chans);

	ret = mbox_controller_register(&gvm_ipc->mbox);
	if (ret) {
		dev_err(&pdev->dev, "failed to register GVM IPC controller\n");
		return ret;
	}

	platform_set_drvdata(pdev, gvm_ipc);

	return 0;
}

static int qcom_gvm_ipc_remove(struct platform_device *pdev)
{
	struct qcom_gvm_ipc *gvm_ipc = platform_get_drvdata(pdev);

	mbox_controller_unregister(&gvm_ipc->mbox);

	return 0;
}

/* .data is the offset of the ipc register within the global block */
static const struct of_device_id qcom_gvm_ipc_of_match[] = {
	{ .compatible = "qcom,sm8150-apcs-hmss-global" },
	{}
};
MODULE_DEVICE_TABLE(of, qcom_gvm_ipc_of_match);

static struct platform_driver qcom_gvm_ipc_driver = {
	.probe = qcom_gvm_ipc_probe,
	.remove = qcom_gvm_ipc_remove,
	.driver = {
		.name = "qcom_gvm_ipc",
		.of_match_table = qcom_gvm_ipc_of_match,
		.suppress_bind_attrs = true,
	},
};

static int __init qcom_gvm_ipc_init(void)
{
	return platform_driver_register(&qcom_gvm_ipc_driver);
}
postcore_initcall(qcom_gvm_ipc_init);

static void __exit qcom_gvm_ipc_exit(void)
{
	platform_driver_unregister(&qcom_gvm_ipc_driver);
}
module_exit(qcom_gvm_ipc_exit);

MODULE_DESCRIPTION("Qualcomm Technologies, Inc. GVM IPC driver");
MODULE_LICENSE("GPL v2");