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

Commit 5fca3180 authored by Chris Lew's avatar Chris Lew
Browse files

soc: qcom: glink: Add support for Glink Probe



The RPMSG over GLINK transport expects to be a subdev
in a remote proc node. This driver helps probe the glink
transports when remote proc is disabled.

Change-Id: If6f2b2de49c583a2f0aa57127380a027f815edc3
Signed-off-by: default avatarChris Lew <clew@codeaurora.org>
parent 627b033c
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
Qualcomm Technologies, Inc. GLINK Probe

This binding describes the GLINK Probe driver, a device
that initializes the GLINK edge pairs within the system.

- compatible :
	Usage: required
	Value type: <stringlist>
	Definition: must be "qcom,glink"

= SUBNODES
The GLINK probe node must contain subnodes that describes the
edge-pairs. See qcom,glink.txt for details on how to describe them.

In addition to the properties in qcom,glink.txt, The GLINK Probe driver
requires the remote-pid and transport type to be specified in the subnodes.

- transport :
	Usage: required
	Value type: <stringlist>
	Definition: must be "smem", "mbox", or "spi"

- qcom,remote-pid :
	Usage: required
	Value type: <prop-encoded-array>
	Definition: specifies the identifier of the remote proc of this edge.

= EXAMPLE
qcom,glink {
	compatible = "qcom,glink";
	modem {
		transport = "smem";
		qcom,remote-pid = <1>;
		mboxes = <&apcs_glb 8>;
		mbox-names = "mpss_smem";
		interrupts = <GIC_SPI 449 IRQ_TYPE_EDGE_RISING>;
	};
};
+8 −0
Original line number Diff line number Diff line
@@ -323,3 +323,11 @@ config QTI_RPMH_API

config QTI_SYSTEM_PM
	bool

config QCOM_GLINK
	tristate "GLINK Probe Helper"
	depends on RPMSG_QCOM_GLINK_SMEM
	help
	  The GLINK RPMSG Plugin is currently designed to plugin with the
	  remote proc framework as a subdev. This module is responsible for
	  creating the glink transports when remote proc is disabled.
+1 −0
Original line number Diff line number Diff line
@@ -39,3 +39,4 @@ ifdef CONFIG_MSM_SUBSYSTEM_RESTART
       obj-y += ramdump.o
endif
obj-$(CONFIG_QCOM_EUD) += eud.o
obj-$(CONFIG_QCOM_GLINK) += glink_probe.o
+83 −0
Original line number Diff line number Diff line
/* Copyright (c) 2017, 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/of.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/rpmsg/qcom_glink.h>

#define NUM_SUBSYSTEMS 10

static struct qcom_glink *edge_infos[NUM_SUBSYSTEMS];

static int glink_probe(struct platform_device *pdev)
{
	struct device_node *cn, *pn = pdev->dev.of_node;
	struct qcom_glink *glink = ERR_PTR(-EINVAL);
	const char *xprt;
	u32 pid;
	int ret;

	for_each_available_child_of_node(pn, cn) {
		ret = of_property_read_u32(cn, "qcom,remote-pid", &pid);
		if (ret || pid >= NUM_SUBSYSTEMS) {
			dev_err(&pdev->dev, "invalid pid:%d ret:%d\n",
				pid, ret);
			return -EINVAL;
		}
		xprt = of_get_property(cn, "transport", NULL);
		if (!xprt) {
			dev_err(&pdev->dev, "missing xprt pid:%d\n", pid);
			return -EINVAL;
		}
		if (!strcmp(xprt, "smem"))
			glink = qcom_glink_smem_register(&pdev->dev, cn);
		if (IS_ERR(glink)) {
			dev_err(&pdev->dev, "%s failed\n", cn->name);
			return PTR_ERR(glink);
		}
		edge_infos[pid] = glink;
	}
	return 0;
}

static const struct of_device_id glink_match_table[] = {
	{ .compatible = "qcom,glink" },
	{},
};

static struct platform_driver glink_probe_driver = {
	.probe = glink_probe,
	.driver = {
		.name = "msm_glink",
		.owner = THIS_MODULE,
		.of_match_table = glink_match_table,
	},
};

static int __init glink_probe_init(void)
{
	int rc;

	rc = platform_driver_register(&glink_probe_driver);
	if (rc) {
		pr_err("%s: glink_probe register failed %d\n",
			__func__, rc);
		return rc;
	}

	return 0;
}
arch_initcall(glink_probe_init);

MODULE_DESCRIPTION("Qualcomm GLINK probe helper driver");
MODULE_LICENSE("GPL v2");