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

Commit 852e7611 authored by Protik Biswas's avatar Protik Biswas
Browse files

soc: qcom: bgrsb-rpmsg: add rpmsg driver



Add support for bgrsb-rpmsg driver that is
used by bgrsb driver to communicate with
a remote processor over Glink communication.

Change-Id: I1a0b904c4d6ea5df1a2e670181b44efb394b806e
Signed-off-by: default avatarProtik Biswas <protbisw@codeaurora.org>
parent c2657225
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
Qualcomm technologies, Inc. bgrsb-rpmsg

BGRSB-RPMSG : bgrsb-rpmsg is used as an interface between
BG-RSB and Blackghost for Glink communication. bg-rsb is
used to communicate with Blackghost over Glink to
configure the RSB events.

Required properties:
- compatible : should be "qcom,bgrsb-rpmsg"
- glink-channels : RSB_CTRL
- glinkpkt-edge : bg
- intents : <0x200 20>

Example:
	qcom,bg-rsb {
		compatible = "qcom,bgrsb-rpmsg";
		qcom,glink-channels = "RSB_CTRL";
		qcom,glinkpkt-edge = "bg";
		intents = <0x200 20>;
	};
+9 −0
Original line number Diff line number Diff line
@@ -1040,6 +1040,15 @@ config MSM_BGRSB
	  the regulator specific to RSB. Sends the side band events generated
	  by BG to input framework.

config MSM_BGRSB_RPMSG
	bool "Provide support for Blackghost events to RSB"
	depends on MSM_BGRSB
	help
	  BGRSB-RPMSG informs BGRSB driver if GLINK channel has been
	  opened by remote processor. It doesn't maintain state machine
	  and is probed when BG opens channel and removed when the
	  channel is closed by remote processor.

config MSM_PIL_SSR_BG
	tristate "MSM Subsystem Blackghost(BG) Support"
	depends on MSM_PIL && MSM_SUBSYSTEM_RESTART
+1 −0
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ obj-$(CONFIG_SDX_EXT_IPC) += sdx_ext_ipc.o
obj-$(CONFIG_MSM_PIL_SSR_BG) += subsys-pil-bg.o
obj-$(CONFIG_QTI_NOTIFY_SIDEBAND) += sideband_notify.o
obj-$(CONFIG_MSM_BGRSB) += bg_rsb.o
obj-$(CONFIG_MSM_BGRSB_RPMSG) += bgrsb_rpmsg.o

ifdef CONFIG_MSM_SUBSYSTEM_RESTART
       obj-y += subsystem_notif.o
+111 −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/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
#include "bgrsb_rpmsg.h"

static struct bgrsb_rpmsg_dev *pdev;

int bgrsb_rpmsg_tx_msg(void  *msg, size_t len)
{
	int ret;

	if (pdev == NULL || !pdev->chnl_state)
		pr_err("pmsg_device is null, channel is closed\n");

	pdev->message = msg;
	pdev->message_length = len;
	if (pdev->message) {
		ret = rpmsg_send(pdev->channel,
			pdev->message, pdev->message_length);
		if (ret)
			pr_err("rpmsg_send failed: %d\n", ret);

	}
	return ret;
}
EXPORT_SYMBOL(bgrsb_rpmsg_tx_msg);

static int bgrsb_rpmsg_probe(struct rpmsg_device  *rpdev)
{
	int ret;
	void *msg;

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

	pdev->channel = rpdev->ept;
	pdev->dev = &rpdev->dev;
	if (pdev->channel == NULL)
		return -ENOMEM;

	pdev->chnl_state = true;
	dev_set_drvdata(&rpdev->dev, pdev);

	/* send a callback to bg-rsb driver*/
	bgrsb_notify_glink_channel_state(true);
	if (pdev->message == NULL)
		ret = bgrsb_rpmsg_tx_msg(msg, 0);
	return 0;
}

static void bgrsb_rpmsg_remove(struct rpmsg_device *rpdev)
{
	pdev->chnl_state = false;
	pdev->message == NULL;
	dev_dbg(&rpdev->dev, "rpmsg client driver is removed\n");
	bgrsb_notify_glink_channel_state(false);
	dev_set_drvdata(&rpdev->dev, NULL);
}

static int bgrsb_rpmsg_cb(struct rpmsg_device *rpdev,
				void *data, int len, void *priv, u32 src)
{
	struct bgrsb_rpmsg_dev *dev =
			dev_get_drvdata(&rpdev->dev);

	if (!dev)
		return -ENODEV;

	return 0;
}

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

static const struct of_device_id rpmsg_driver_bgrsb_of_match[] = {
	{ .compatible = "qcom,bgrsb-rpmsg" },
	{},
};

static struct rpmsg_driver rpmsg_bgrsb_client = {
	.id_table = rpmsg_driver_bgrsb_id_table,
	.probe = bgrsb_rpmsg_probe,
	.callback = bgrsb_rpmsg_cb,
	.remove = bgrsb_rpmsg_remove,
	.drv = {
		.name = "qcom,bg_rsb_rpmsg",
		.of_match_table = rpmsg_driver_bgrsb_of_match,
	},
};
module_rpmsg_driver(rpmsg_bgrsb_client);

MODULE_DESCRIPTION("Interface Driver for BG-RSB and RPMSG");
MODULE_LICENSE("GPL v2");
+36 −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.
 *
 */
#ifndef BGRSBRPMSG_H
#define BGRSBRPMSG_H

#include <linux/rpmsg.h>
#include "bgrsb.h"

struct bgrsb_rpmsg_dev {
	struct rpmsg_endpoint *channel;
	struct device *dev;
	bool chnl_state;
	void *message;
	size_t message_length;
};

#if IS_ENABLED(CONFIG_MSM_BGRSB_RPMSG)
int bgrsb_rpmsg_tx_msg(void  *msg, size_t len);
#else
static inline int bgrsb_rpmsg_tx_msg(void  *msg, size_t len)
{
	return -EIO;
}
#endif

#endif