Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rpmsg: Turn name service into a stand alone driver

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.

Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Tested-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Co-developed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Co-developed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@st.com>
Link: https://lore.kernel.org/r/20201120214245.172963-9-mathieu.poirier@linaro.org
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>

authored by

Arnaud Pouliquen and committed by
Bjorn Andersson
950a7388 55488110

+159 -67
+9
drivers/rpmsg/Kconfig
··· 15 15 in /dev. They make it possible for user-space programs to send and 16 16 receive rpmsg packets. 17 17 18 + config RPMSG_NS 19 + tristate "RPMSG name service announcement" 20 + depends on RPMSG 21 + help 22 + Say Y here to enable the support of the name service announcement 23 + channel that probes the associated RPMsg device on remote endpoint 24 + service announcement. 25 + 18 26 config RPMSG_MTK_SCP 19 27 tristate "MediaTek SCP" 20 28 depends on MTK_SCP ··· 70 62 tristate "Virtio RPMSG bus driver" 71 63 depends on HAS_DMA 72 64 select RPMSG 65 + select RPMSG_NS 73 66 select VIRTIO 74 67 75 68 endmenu
+1
drivers/rpmsg/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 obj-$(CONFIG_RPMSG) += rpmsg_core.o 3 3 obj-$(CONFIG_RPMSG_CHAR) += rpmsg_char.o 4 + obj-$(CONFIG_RPMSG_NS) += rpmsg_ns.o 4 5 obj-$(CONFIG_RPMSG_MTK_SCP) += mtk_rpmsg.o 5 6 qcom_glink-objs := qcom_glink_native.o qcom_glink_ssr.o 6 7 obj-$(CONFIG_RPMSG_QCOM_GLINK) += qcom_glink.o
+126
drivers/rpmsg/rpmsg_ns.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) STMicroelectronics 2020 - All Rights Reserved 4 + */ 5 + #include <linux/device.h> 6 + #include <linux/kernel.h> 7 + #include <linux/module.h> 8 + #include <linux/rpmsg.h> 9 + #include <linux/rpmsg/ns.h> 10 + #include <linux/slab.h> 11 + 12 + #include "rpmsg_internal.h" 13 + 14 + /** 15 + * rpmsg_ns_register_device() - register name service device based on rpdev 16 + * @rpdev: prepared rpdev to be used for creating endpoints 17 + * 18 + * This function wraps rpmsg_register_device() preparing the rpdev for use as 19 + * basis for the rpmsg name service device. 20 + */ 21 + int rpmsg_ns_register_device(struct rpmsg_device *rpdev) 22 + { 23 + strcpy(rpdev->id.name, "rpmsg_ns"); 24 + rpdev->driver_override = "rpmsg_ns"; 25 + rpdev->src = RPMSG_NS_ADDR; 26 + rpdev->dst = RPMSG_NS_ADDR; 27 + 28 + return rpmsg_register_device(rpdev); 29 + } 30 + EXPORT_SYMBOL(rpmsg_ns_register_device); 31 + 32 + /* invoked when a name service announcement arrives */ 33 + static int rpmsg_ns_cb(struct rpmsg_device *rpdev, void *data, int len, 34 + void *priv, u32 src) 35 + { 36 + struct rpmsg_ns_msg *msg = data; 37 + struct rpmsg_device *newch; 38 + struct rpmsg_channel_info chinfo; 39 + struct device *dev = rpdev->dev.parent; 40 + int ret; 41 + 42 + #if defined(CONFIG_DYNAMIC_DEBUG) 43 + dynamic_hex_dump("NS announcement: ", DUMP_PREFIX_NONE, 16, 1, 44 + data, len, true); 45 + #endif 46 + 47 + if (len != sizeof(*msg)) { 48 + dev_err(dev, "malformed ns msg (%d)\n", len); 49 + return -EINVAL; 50 + } 51 + 52 + /* don't trust the remote processor for null terminating the name */ 53 + msg->name[RPMSG_NAME_SIZE - 1] = '\0'; 54 + 55 + strncpy(chinfo.name, msg->name, sizeof(chinfo.name)); 56 + chinfo.src = RPMSG_ADDR_ANY; 57 + chinfo.dst = rpmsg32_to_cpu(rpdev, msg->addr); 58 + 59 + dev_info(dev, "%sing channel %s addr 0x%x\n", 60 + rpmsg32_to_cpu(rpdev, msg->flags) & RPMSG_NS_DESTROY ? 61 + "destroy" : "creat", msg->name, chinfo.dst); 62 + 63 + if (rpmsg32_to_cpu(rpdev, msg->flags) & RPMSG_NS_DESTROY) { 64 + ret = rpmsg_release_channel(rpdev, &chinfo); 65 + if (ret) 66 + dev_err(dev, "rpmsg_destroy_channel failed: %d\n", ret); 67 + } else { 68 + newch = rpmsg_create_channel(rpdev, &chinfo); 69 + if (!newch) 70 + dev_err(dev, "rpmsg_create_channel failed\n"); 71 + } 72 + 73 + return 0; 74 + } 75 + 76 + static int rpmsg_ns_probe(struct rpmsg_device *rpdev) 77 + { 78 + struct rpmsg_endpoint *ns_ept; 79 + struct rpmsg_channel_info ns_chinfo = { 80 + .src = RPMSG_NS_ADDR, 81 + .dst = RPMSG_NS_ADDR, 82 + .name = "name_service", 83 + }; 84 + 85 + /* 86 + * Create the NS announcement service endpoint associated to the RPMsg 87 + * device. The endpoint will be automatically destroyed when the RPMsg 88 + * device will be deleted. 89 + */ 90 + ns_ept = rpmsg_create_ept(rpdev, rpmsg_ns_cb, NULL, ns_chinfo); 91 + if (!ns_ept) { 92 + dev_err(&rpdev->dev, "failed to create the ns ept\n"); 93 + return -ENOMEM; 94 + } 95 + rpdev->ept = ns_ept; 96 + 97 + return 0; 98 + } 99 + 100 + static struct rpmsg_driver rpmsg_ns_driver = { 101 + .drv.name = KBUILD_MODNAME, 102 + .probe = rpmsg_ns_probe, 103 + }; 104 + 105 + static int rpmsg_ns_init(void) 106 + { 107 + int ret; 108 + 109 + ret = register_rpmsg_driver(&rpmsg_ns_driver); 110 + if (ret < 0) 111 + pr_err("%s: Failed to register rpmsg driver\n", __func__); 112 + 113 + return ret; 114 + } 115 + postcore_initcall(rpmsg_ns_init); 116 + 117 + static void rpmsg_ns_exit(void) 118 + { 119 + unregister_rpmsg_driver(&rpmsg_ns_driver); 120 + } 121 + module_exit(rpmsg_ns_exit); 122 + 123 + MODULE_DESCRIPTION("Name service announcement rpmsg driver"); 124 + MODULE_AUTHOR("Arnaud Pouliquen <arnaud.pouliquen@st.com>"); 125 + MODULE_ALIAS("rpmsg:" KBUILD_MODNAME); 126 + MODULE_LICENSE("GPL v2");
+20 -67
drivers/rpmsg/virtio_rpmsg_bus.c
··· 49 49 * @endpoints_lock: lock of the endpoints set 50 50 * @sendq: wait queue of sending contexts waiting for a tx buffers 51 51 * @sleepers: number of senders that are waiting for a tx buffer 52 - * @ns_ept: the bus's name service endpoint 53 52 * 54 53 * This structure stores the rpmsg state of a given virtio remote processor 55 54 * device (there might be several virtio proc devices for each physical ··· 67 68 struct mutex endpoints_lock; 68 69 wait_queue_head_t sendq; 69 70 atomic_t sleepers; 70 - struct rpmsg_endpoint *ns_ept; 71 71 }; 72 72 73 73 /* The feature bitmap for virtio rpmsg */ ··· 813 815 wake_up_interruptible(&vrp->sendq); 814 816 } 815 817 816 - /* invoked when a name service announcement arrives */ 817 - static int rpmsg_ns_cb(struct rpmsg_device *rpdev, void *data, int len, 818 - void *priv, u32 src) 819 - { 820 - struct rpmsg_ns_msg *msg = data; 821 - struct rpmsg_device *newch; 822 - struct rpmsg_channel_info chinfo; 823 - struct virtproc_info *vrp = priv; 824 - struct device *dev = &vrp->vdev->dev; 825 - bool little_endian = virtio_is_little_endian(vrp->vdev); 826 - int ret; 827 - 828 - #if defined(CONFIG_DYNAMIC_DEBUG) 829 - dynamic_hex_dump("NS announcement: ", DUMP_PREFIX_NONE, 16, 1, 830 - data, len, true); 831 - #endif 832 - 833 - if (len != sizeof(*msg)) { 834 - dev_err(dev, "malformed ns msg (%d)\n", len); 835 - return -EINVAL; 836 - } 837 - 838 - /* 839 - * the name service ept does _not_ belong to a real rpmsg channel, 840 - * and is handled by the rpmsg bus itself. 841 - * for sanity reasons, make sure a valid rpdev has _not_ sneaked 842 - * in somehow. 843 - */ 844 - if (rpdev) { 845 - dev_err(dev, "anomaly: ns ept has an rpdev handle\n"); 846 - return -EINVAL; 847 - } 848 - 849 - /* don't trust the remote processor for null terminating the name */ 850 - msg->name[RPMSG_NAME_SIZE - 1] = '\0'; 851 - 852 - strncpy(chinfo.name, msg->name, sizeof(chinfo.name)); 853 - chinfo.src = RPMSG_ADDR_ANY; 854 - chinfo.dst = __rpmsg32_to_cpu(little_endian, msg->addr); 855 - 856 - dev_info(dev, "%sing channel %s addr 0x%x\n", 857 - __rpmsg32_to_cpu(little_endian, msg->flags) & RPMSG_NS_DESTROY ? 858 - "destroy" : "creat", msg->name, chinfo.dst); 859 - 860 - if (__rpmsg32_to_cpu(little_endian, msg->flags) & RPMSG_NS_DESTROY) { 861 - ret = rpmsg_unregister_device(&vrp->vdev->dev, &chinfo); 862 - if (ret) 863 - dev_err(dev, "rpmsg_destroy_channel failed: %d\n", ret); 864 - } else { 865 - newch = __rpmsg_create_channel(vrp, &chinfo); 866 - if (!newch) 867 - dev_err(dev, "rpmsg_create_channel failed\n"); 868 - } 869 - 870 - return 0; 871 - } 872 - 873 818 static int rpmsg_probe(struct virtio_device *vdev) 874 819 { 875 820 vq_callback_t *vq_cbs[] = { rpmsg_recv_done, rpmsg_xmit_done }; 876 821 static const char * const names[] = { "input", "output" }; 877 822 struct virtqueue *vqs[2]; 878 823 struct virtproc_info *vrp; 824 + struct virtio_rpmsg_channel *vch; 825 + struct rpmsg_device *rpdev_ns; 879 826 void *bufs_va; 880 827 int err = 0, i; 881 828 size_t total_buf_space; ··· 896 953 897 954 /* if supported by the remote processor, enable the name service */ 898 955 if (virtio_has_feature(vdev, VIRTIO_RPMSG_F_NS)) { 899 - /* a dedicated endpoint handles the name service msgs */ 900 - vrp->ns_ept = __rpmsg_create_ept(vrp, NULL, rpmsg_ns_cb, 901 - vrp, RPMSG_NS_ADDR); 902 - if (!vrp->ns_ept) { 903 - dev_err(&vdev->dev, "failed to create the ns ept\n"); 956 + vch = kzalloc(sizeof(*vch), GFP_KERNEL); 957 + if (!vch) { 904 958 err = -ENOMEM; 905 959 goto free_coherent; 906 960 } 961 + 962 + /* Link the channel to our vrp */ 963 + vch->vrp = vrp; 964 + 965 + /* Assign public information to the rpmsg_device */ 966 + rpdev_ns = &vch->rpdev; 967 + rpdev_ns->ops = &virtio_rpmsg_ops; 968 + rpdev_ns->little_endian = virtio_is_little_endian(vrp->vdev); 969 + 970 + rpdev_ns->dev.parent = &vrp->vdev->dev; 971 + rpdev_ns->dev.release = virtio_rpmsg_release_device; 972 + 973 + err = rpmsg_ns_register_device(rpdev_ns); 974 + if (err) 975 + goto free_coherent; 907 976 } 908 977 909 978 /* ··· 940 985 return 0; 941 986 942 987 free_coherent: 988 + kfree(vch); 943 989 dma_free_coherent(vdev->dev.parent, total_buf_space, 944 990 bufs_va, vrp->bufs_dma); 945 991 vqs_del: ··· 968 1012 ret = device_for_each_child(&vdev->dev, NULL, rpmsg_remove_device); 969 1013 if (ret) 970 1014 dev_warn(&vdev->dev, "can't remove rpmsg device: %d\n", ret); 971 - 972 - if (vrp->ns_ept) 973 - __rpmsg_destroy_ept(vrp, vrp->ns_ept); 974 1015 975 1016 idr_destroy(&vrp->endpoints); 976 1017
+3
include/linux/rpmsg/ns.h
··· 4 4 #define _LINUX_RPMSG_NS_H 5 5 6 6 #include <linux/mod_devicetable.h> 7 + #include <linux/rpmsg.h> 7 8 #include <linux/rpmsg/byteorder.h> 8 9 #include <linux/types.h> 9 10 ··· 39 38 40 39 /* Address 53 is reserved for advertising remote services */ 41 40 #define RPMSG_NS_ADDR (53) 41 + 42 + int rpmsg_ns_register_device(struct rpmsg_device *rpdev); 42 43 43 44 #endif