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

Configure Feed

Select the types of activity you want to include in your feed.

at v5.15-rc4 126 lines 3.3 kB view raw
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 */ 21int 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} 30EXPORT_SYMBOL(rpmsg_ns_register_device); 31 32/* invoked when a name service announcement arrives */ 33static 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 76static 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 100static struct rpmsg_driver rpmsg_ns_driver = { 101 .drv.name = KBUILD_MODNAME, 102 .probe = rpmsg_ns_probe, 103}; 104 105static 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} 115postcore_initcall(rpmsg_ns_init); 116 117static void rpmsg_ns_exit(void) 118{ 119 unregister_rpmsg_driver(&rpmsg_ns_driver); 120} 121module_exit(rpmsg_ns_exit); 122 123MODULE_DESCRIPTION("Name service announcement rpmsg driver"); 124MODULE_AUTHOR("Arnaud Pouliquen <arnaud.pouliquen@st.com>"); 125MODULE_ALIAS("rpmsg:" KBUILD_MODNAME); 126MODULE_LICENSE("GPL v2");