Received: by 2002:a05:6a10:16a7:0:0:0:0 with SMTP id gp39csp655471pxb; Wed, 18 Nov 2020 13:40:13 -0800 (PST) X-Google-Smtp-Source: ABdhPJw6D9bw7ab6bQJk0j4OW0FZRNUJyU1HAhZQPWtffpBDzXvF0e+RTePL+NIxfuXDwlR6g1qN X-Received: by 2002:a17:906:f05:: with SMTP id z5mr26688781eji.8.1605735612808; Wed, 18 Nov 2020 13:40:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1605735612; cv=none; d=google.com; s=arc-20160816; b=d1QeEmXvytjyVRXXjg6jaHzNTrk9b6yaAcjMzJ0Ex2Vh1HRBqN8f1b5D32hVN27XY6 yqgmc8kXMoejyYsaKMpEVamTSTMNgFyGRiQ7rsOpSQ7b9jnwCu4ZiYtHCE0+lTUU465F 52I0XtisSV0+KHPVVnz3jkytOe/5+98+e6fZNCGzE8VoPZRtuCD+ctUX86pRJ9hT8/Ew oZe828e9M+95YCcZ6a5bfUQi5TgJLF15tXWxkINr3aDYn4bUePX0dCSuQn5VDSKpIFiV Exa8UNEhI9MLeK2f+2ktg1rWQVvgYk1haVvz02JkIA0l6PZDSj6qm3YoEFOEb4Pq7VVJ KNkg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=IfJSGBCVk4goNi0VOu0iLazGHTRiVCH1JUbI/YhJhcs=; b=ZPhRrMoDwd5JDzUvWRcyvfaFPA0y3oanoPuoNqAf3Qd+aGs9k6gQCkhtRBvpY7lUY1 X+yOULVNsrffpNmjdQaFKnBuEa/WQn4m6K+UZFd66ArLxBRzlaaDqaaLY4m6miVP9WAr BW6TncXMA/nX6LUs9A5rNWOWe7CFN5f33B+b2kZtIsNthrvtx55RCNvlav52R8y5cerN 43B7Sdm8n4kyF+bwWJwX1XSixD/y0She9bkHMuNNKTl4a2T2SRlwmTev0iFncKSgQjzO NNb1O2HJF3cbiJ3kbgMLl3gNlYV8/+FY3qLyL1mjRCZH2muSKREtLiNFgdWRuubAn887 IXNg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=BkCdRcDN; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id x3si15279471ede.333.2020.11.18.13.39.49; Wed, 18 Nov 2020 13:40:12 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=BkCdRcDN; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727204AbgKRVhR (ORCPT + 99 others); Wed, 18 Nov 2020 16:37:17 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48966 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727167AbgKRVhL (ORCPT ); Wed, 18 Nov 2020 16:37:11 -0500 Received: from mail-pg1-x541.google.com (mail-pg1-x541.google.com [IPv6:2607:f8b0:4864:20::541]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 490FDC0613D6 for ; Wed, 18 Nov 2020 13:37:11 -0800 (PST) Received: by mail-pg1-x541.google.com with SMTP id 62so2184044pgg.12 for ; Wed, 18 Nov 2020 13:37:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=IfJSGBCVk4goNi0VOu0iLazGHTRiVCH1JUbI/YhJhcs=; b=BkCdRcDNrADcIg/Hw8kzIOjee5gFFy6PUDIzxBffDTQmvajqR+FT6tzAhweQjX1Kpq dfBX57j4h6rfaoENgdK4emgrqwDp+N+2rmiDLKV6e9Pw9cGi0M/aAfv3oagp7kJXPhJj y5iQ93vLRtCIRtK5BmUZGBdMLg81CDJ7fnIQDBeUD6lAJZbPv5wzHG8nMYL1r4J3Mwnt yvd4/LMmTePJZQ4q1ZYz0mR2ZVlZmH6bj/UVMe+RfhTe7bRxDCSYijsMdHAcrxCK52W1 jRCorvEjyqtn9BFMbw+XIOn7nde+fAArP9QBY6IJOdVs4/eMnmQ2+qmqfMUCK/OIfEtG 93Sg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=IfJSGBCVk4goNi0VOu0iLazGHTRiVCH1JUbI/YhJhcs=; b=m4Md65RTcCD5x+eUDhFOFHwbr1xNC0SX9u1hCvva2v68FEOSddPz5wYJAd1lVQJGAq DrlFDQdpwul49Rfd9oXCypvykXRwRAuo9gbpFpepE4g8cFAnp5/p5gqziZrhSBNVdHBo nzc/WIVEXI9grMl8MCiuLPSbe4TBoQpL2kbUSKIkoBz6cjF3uLg/z254qi+yYbs6z94D 5UjOzbfieAvpWFMfosDFk/2qjFGOqOO3RlUgoF3drl/E4SSx1aTkkkAiJcH3rCaO99r7 CDchNW8J1vMhl50apySu6CUiB/h6HGusLuGdp75kCkWYI2nN9x6dIlpvQ/9qZD19O4z7 Y//A== X-Gm-Message-State: AOAM532uQNbPmhGo4DlZjQcFZbnPDHif+2Fp1hc1R7P0yDRlNBU339WR S67gYULPrfmSUrBAf17N+apgcA== X-Received: by 2002:a63:fc56:: with SMTP id r22mr10320574pgk.247.1605735430790; Wed, 18 Nov 2020 13:37:10 -0800 (PST) Received: from xps15.cg.shawcable.net (S0106889e681aac74.cg.shawcable.net. [68.147.0.187]) by smtp.gmail.com with ESMTPSA id e6sm26575694pfn.190.2020.11.18.13.37.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Nov 2020 13:37:10 -0800 (PST) From: Mathieu Poirier To: ohad@wizery.com, bjorn.andersson@linaro.org Cc: guennadi.liakhovetski@linux.intel.com, arnaud.pouliquen@st.com, linux-remoteproc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v6 8/8] rpmsg: Turn name service into a stand alone driver Date: Wed, 18 Nov 2020 14:37:00 -0700 Message-Id: <20201118213700.74106-9-mathieu.poirier@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201118213700.74106-1-mathieu.poirier@linaro.org> References: <20201118213700.74106-1-mathieu.poirier@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Arnaud Pouliquen Make the RPMSG name service announcement a stand alone driver so that it can be reused by other subsystems. It is also the first step in making the functionatlity transport independent, i.e that is not tied to virtIO. Co-developed-by: Mathieu Poirier Signed-off-by: Mathieu Poirier Co-developed-by: Guennadi Liakhovetski Signed-off-by: Guennadi Liakhovetski Signed-off-by: Arnaud Pouliquen --- drivers/rpmsg/Kconfig | 9 +++ drivers/rpmsg/Makefile | 1 + drivers/rpmsg/rpmsg_ns.c | 126 +++++++++++++++++++++++++++++++ drivers/rpmsg/virtio_rpmsg_bus.c | 86 +++++---------------- include/linux/rpmsg/ns.h | 3 + 5 files changed, 158 insertions(+), 67 deletions(-) create mode 100644 drivers/rpmsg/rpmsg_ns.c diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig index f96716893c2a..0b4407abdf13 100644 --- a/drivers/rpmsg/Kconfig +++ b/drivers/rpmsg/Kconfig @@ -15,6 +15,14 @@ config RPMSG_CHAR in /dev. They make it possible for user-space programs to send and receive rpmsg packets. +config RPMSG_NS + tristate "RPMSG name service announcement" + depends on RPMSG + help + Say Y here to enable the support of the name service announcement + channel that probes the associated RPMsg device on remote endpoint + service announcement. + config RPMSG_MTK_SCP tristate "MediaTek SCP" depends on MTK_SCP @@ -62,6 +70,7 @@ config RPMSG_VIRTIO tristate "Virtio RPMSG bus driver" depends on HAS_DMA select RPMSG + select RPMSG_NS select VIRTIO endmenu diff --git a/drivers/rpmsg/Makefile b/drivers/rpmsg/Makefile index ffe932ef6050..8d452656f0ee 100644 --- a/drivers/rpmsg/Makefile +++ b/drivers/rpmsg/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_RPMSG) += rpmsg_core.o obj-$(CONFIG_RPMSG_CHAR) += rpmsg_char.o +obj-$(CONFIG_RPMSG_NS) += rpmsg_ns.o obj-$(CONFIG_RPMSG_MTK_SCP) += mtk_rpmsg.o qcom_glink-objs := qcom_glink_native.o qcom_glink_ssr.o obj-$(CONFIG_RPMSG_QCOM_GLINK) += qcom_glink.o diff --git a/drivers/rpmsg/rpmsg_ns.c b/drivers/rpmsg/rpmsg_ns.c new file mode 100644 index 000000000000..66a22497d316 --- /dev/null +++ b/drivers/rpmsg/rpmsg_ns.c @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) STMicroelectronics 2020 - All Rights Reserved + */ +#include +#include +#include +#include +#include +#include + +#include "rpmsg_internal.h" + +/** + * rpmsg_ns_register_device() - register name service device based on rpdev + * @rpdev: prepared rpdev to be used for creating endpoints + * + * This function wraps rpmsg_register_device() preparing the rpdev for use as + * basis for the rpmsg name service device. + */ +int rpmsg_ns_register_device(struct rpmsg_device *rpdev) +{ + strcpy(rpdev->id.name, "rpmsg_ns"); + rpdev->driver_override = "rpmsg_ns"; + rpdev->src = RPMSG_NS_ADDR; + rpdev->dst = RPMSG_NS_ADDR; + + return rpmsg_register_device(rpdev); +} +EXPORT_SYMBOL(rpmsg_ns_register_device); + +/* invoked when a name service announcement arrives */ +static int rpmsg_ns_cb(struct rpmsg_device *rpdev, void *data, int len, + void *priv, u32 src) +{ + struct rpmsg_ns_msg *msg = data; + struct rpmsg_device *newch; + struct rpmsg_channel_info chinfo; + struct device *dev = rpdev->dev.parent; + int ret; + +#if defined(CONFIG_DYNAMIC_DEBUG) + dynamic_hex_dump("NS announcement: ", DUMP_PREFIX_NONE, 16, 1, + data, len, true); +#endif + + if (len != sizeof(*msg)) { + dev_err(dev, "malformed ns msg (%d)\n", len); + return -EINVAL; + } + + /* don't trust the remote processor for null terminating the name */ + msg->name[RPMSG_NAME_SIZE - 1] = '\0'; + + strncpy(chinfo.name, msg->name, sizeof(chinfo.name)); + chinfo.src = RPMSG_ADDR_ANY; + chinfo.dst = rpmsg32_to_cpu(rpdev, msg->addr); + + dev_info(dev, "%sing channel %s addr 0x%x\n", + rpmsg32_to_cpu(rpdev, msg->flags) & RPMSG_NS_DESTROY ? + "destroy" : "creat", msg->name, chinfo.dst); + + if (rpmsg32_to_cpu(rpdev, msg->flags) & RPMSG_NS_DESTROY) { + ret = rpmsg_release_channel(rpdev, &chinfo); + if (ret) + dev_err(dev, "rpmsg_destroy_channel failed: %d\n", ret); + } else { + newch = rpmsg_create_channel(rpdev, &chinfo); + if (!newch) + dev_err(dev, "rpmsg_create_channel failed\n"); + } + + return 0; +} + +static int rpmsg_ns_probe(struct rpmsg_device *rpdev) +{ + struct rpmsg_endpoint *ns_ept; + struct rpmsg_channel_info ns_chinfo = { + .src = RPMSG_NS_ADDR, + .dst = RPMSG_NS_ADDR, + .name = "name_service", + }; + + /* + * Create the NS announcement service endpoint associated to the RPMsg + * device. The endpoint will be automatically destroyed when the RPMsg + * device will be deleted. + */ + ns_ept = rpmsg_create_ept(rpdev, rpmsg_ns_cb, NULL, ns_chinfo); + if (!ns_ept) { + dev_err(&rpdev->dev, "failed to create the ns ept\n"); + return -ENOMEM; + } + rpdev->ept = ns_ept; + + return 0; +} + +static struct rpmsg_driver rpmsg_ns_driver = { + .drv.name = KBUILD_MODNAME, + .probe = rpmsg_ns_probe, +}; + +static int rpmsg_ns_init(void) +{ + int ret; + + ret = register_rpmsg_driver(&rpmsg_ns_driver); + if (ret < 0) + pr_err("%s: Failed to register rpmsg driver\n", __func__); + + return ret; +} +postcore_initcall(rpmsg_ns_init); + +static void rpmsg_ns_exit(void) +{ + unregister_rpmsg_driver(&rpmsg_ns_driver); +} +module_exit(rpmsg_ns_exit); + +MODULE_DESCRIPTION("Name service announcement rpmsg driver"); +MODULE_AUTHOR("Arnaud Pouliquen "); +MODULE_ALIAS("rpmsg:" KBUILD_MODNAME); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index 6ec299f7f790..338f16c6563d 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c @@ -49,7 +49,6 @@ * @endpoints_lock: lock of the endpoints set * @sendq: wait queue of sending contexts waiting for a tx buffers * @sleepers: number of senders that are waiting for a tx buffer - * @ns_ept: the bus's name service endpoint * * This structure stores the rpmsg state of a given virtio remote processor * device (there might be several virtio proc devices for each physical @@ -68,7 +67,6 @@ struct virtproc_info { struct mutex endpoints_lock; wait_queue_head_t sendq; atomic_t sleepers; - struct rpmsg_endpoint *ns_ept; }; /* The feature bitmap for virtio rpmsg */ @@ -815,69 +813,14 @@ static void rpmsg_xmit_done(struct virtqueue *svq) wake_up_interruptible(&vrp->sendq); } -/* invoked when a name service announcement arrives */ -static int rpmsg_ns_cb(struct rpmsg_device *rpdev, void *data, int len, - void *priv, u32 src) -{ - struct rpmsg_ns_msg *msg = data; - struct rpmsg_device *newch; - struct rpmsg_channel_info chinfo; - struct virtproc_info *vrp = priv; - struct device *dev = &vrp->vdev->dev; - bool little_endian = virtio_is_little_endian(vrp->vdev); - int ret; - -#if defined(CONFIG_DYNAMIC_DEBUG) - dynamic_hex_dump("NS announcement: ", DUMP_PREFIX_NONE, 16, 1, - data, len, true); -#endif - - if (len != sizeof(*msg)) { - dev_err(dev, "malformed ns msg (%d)\n", len); - return -EINVAL; - } - - /* - * the name service ept does _not_ belong to a real rpmsg channel, - * and is handled by the rpmsg bus itself. - * for sanity reasons, make sure a valid rpdev has _not_ sneaked - * in somehow. - */ - if (rpdev) { - dev_err(dev, "anomaly: ns ept has an rpdev handle\n"); - return -EINVAL; - } - - /* don't trust the remote processor for null terminating the name */ - msg->name[RPMSG_NAME_SIZE - 1] = '\0'; - - strncpy(chinfo.name, msg->name, sizeof(chinfo.name)); - chinfo.src = RPMSG_ADDR_ANY; - chinfo.dst = __rpmsg32_to_cpu(little_endian, msg->addr); - - dev_info(dev, "%sing channel %s addr 0x%x\n", - __rpmsg32_to_cpu(little_endian, msg->flags) & RPMSG_NS_DESTROY ? - "destroy" : "creat", msg->name, chinfo.dst); - - if (__rpmsg32_to_cpu(little_endian, msg->flags) & RPMSG_NS_DESTROY) { - ret = rpmsg_unregister_device(&vrp->vdev->dev, &chinfo); - if (ret) - dev_err(dev, "rpmsg_destroy_channel failed: %d\n", ret); - } else { - newch = __rpmsg_create_channel(vrp, &chinfo); - if (!newch) - dev_err(dev, "rpmsg_create_channel failed\n"); - } - - return 0; -} - static int rpmsg_probe(struct virtio_device *vdev) { vq_callback_t *vq_cbs[] = { rpmsg_recv_done, rpmsg_xmit_done }; static const char * const names[] = { "input", "output" }; struct virtqueue *vqs[2]; struct virtproc_info *vrp; + struct virtio_rpmsg_channel *vch; + struct rpmsg_device *rpdev_ns; void *bufs_va; int err = 0, i; size_t total_buf_space; @@ -953,14 +896,26 @@ static int rpmsg_probe(struct virtio_device *vdev) /* if supported by the remote processor, enable the name service */ if (virtio_has_feature(vdev, VIRTIO_RPMSG_F_NS)) { - /* a dedicated endpoint handles the name service msgs */ - vrp->ns_ept = __rpmsg_create_ept(vrp, NULL, rpmsg_ns_cb, - vrp, RPMSG_NS_ADDR); - if (!vrp->ns_ept) { - dev_err(&vdev->dev, "failed to create the ns ept\n"); + vch = kzalloc(sizeof(*vch), GFP_KERNEL); + if (!vch) { err = -ENOMEM; goto free_coherent; } + + /* Link the channel to our vrp */ + vch->vrp = vrp; + + /* Assign public information to the rpmsg_device */ + rpdev_ns = &vch->rpdev; + rpdev_ns->ops = &virtio_rpmsg_ops; + rpdev_ns->little_endian = virtio_is_little_endian(vrp->vdev); + + rpdev_ns->dev.parent = &vrp->vdev->dev; + rpdev_ns->dev.release = virtio_rpmsg_release_device; + + err = rpmsg_ns_register_device(rpdev_ns); + if (err) + goto free_coherent; } /* @@ -1013,9 +968,6 @@ static void rpmsg_remove(struct virtio_device *vdev) if (ret) dev_warn(&vdev->dev, "can't remove rpmsg device: %d\n", ret); - if (vrp->ns_ept) - __rpmsg_destroy_ept(vrp, vrp->ns_ept); - idr_destroy(&vrp->endpoints); vdev->config->del_vqs(vrp->vdev); diff --git a/include/linux/rpmsg/ns.h b/include/linux/rpmsg/ns.h index 73ecc91dc26f..a7804edd6d58 100644 --- a/include/linux/rpmsg/ns.h +++ b/include/linux/rpmsg/ns.h @@ -4,6 +4,7 @@ #define _LINUX_RPMSG_NS_H #include +#include #include #include @@ -39,4 +40,6 @@ enum rpmsg_ns_flags { /* Address 53 is reserved for advertising remote services */ #define RPMSG_NS_ADDR (53) +int rpmsg_ns_register_device(struct rpmsg_device *rpdev); + #endif -- 2.25.1