xref: /OK3568_Linux_fs/kernel/drivers/rpmsg/rockchip_rpmsg_test.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Rockchip Remote Processors Messaging Test.
4  *
5  * Copyright (c) 2022 Rockchip Electronics Co. Ltd.
6  * Author: Hongming Zou <hongming.zou@rock-chips.com>
7  */
8 
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/rpmsg.h>
12 #include <linux/rpmsg/rockchip_rpmsg.h>
13 #include <linux/virtio.h>
14 
15 #define LINUX_TEST_MSG_1 "Announce master ept id!"
16 #define LINUX_TEST_MSG_2 "Rockchip rpmsg linux test pingpong!"
17 #define MSG_LIMIT       100
18 
19 struct instance_data {
20 	int rx_count;
21 };
22 
rockchip_rpmsg_test_cb(struct rpmsg_device * rp,void * payload,int payload_len,void * priv,u32 src)23 static int rockchip_rpmsg_test_cb(struct rpmsg_device *rp, void *payload,
24 				  int payload_len, void *priv, u32 src)
25 {
26 	int ret;
27 	uint32_t remote_ept_id;
28 	struct instance_data *idata = dev_get_drvdata(&rp->dev);
29 
30 	remote_ept_id = src;
31 	dev_info(&rp->dev, "rx msg %s rx_count %d(remote_ept_id: 0x%x)\n",
32 			(char *)payload, ++idata->rx_count, remote_ept_id);
33 
34 	/* test should not live forever */
35 	if (idata->rx_count >= MSG_LIMIT) {
36 		dev_info(&rp->dev, "Rockchip rpmsg test exit!\n");
37 		return 0;
38 	}
39 
40 	/* send a new message now */
41 	ret = rpmsg_sendto(rp->ept, LINUX_TEST_MSG_2, strlen(LINUX_TEST_MSG_2), remote_ept_id);
42 	if (ret)
43 		dev_err(&rp->dev, "rpmsg_send failed: %d\n", ret);
44 		return ret;
45 }
46 
rockchip_rpmsg_test_probe(struct rpmsg_device * rp)47 static int rockchip_rpmsg_test_probe(struct rpmsg_device *rp)
48 {
49 	int ret;
50 	uint32_t master_ept_id, remote_ept_id;
51 	struct instance_data *idata;
52 
53 	master_ept_id = rp->src;
54 	remote_ept_id = rp->dst;
55 	dev_info(&rp->dev, "new channel: 0x%x -> 0x%x!\n", master_ept_id, remote_ept_id);
56 
57 	idata = devm_kzalloc(&rp->dev, sizeof(*idata), GFP_KERNEL);
58 	if (!idata)
59 		return -ENOMEM;
60 
61 	dev_set_drvdata(&rp->dev, idata);
62 
63 	/*
64 	 * send a message to our remote processor, and tell remote
65 	 * processor about this channel
66 	 */
67 	ret = rpmsg_send(rp->ept, LINUX_TEST_MSG_1, strlen(LINUX_TEST_MSG_1));
68 	if (ret) {
69 		dev_err(&rp->dev, "rpmsg_send failed: %d\n", ret);
70 		return ret;
71 	}
72 
73 	ret = rpmsg_sendto(rp->ept, LINUX_TEST_MSG_2, strlen(LINUX_TEST_MSG_2), remote_ept_id);
74 	if (ret) {
75 		dev_err(&rp->dev, "rpmsg_send failed: %d\n", ret);
76 		return ret;
77 	}
78 
79 	return 0;
80 }
81 
rockchip_rpmsg_test_remove(struct rpmsg_device * rp)82 static void rockchip_rpmsg_test_remove(struct rpmsg_device *rp)
83 {
84 	dev_info(&rp->dev, "rockchip rpmsg test is removed\n");
85 }
86 
87 static struct rpmsg_device_id rockchip_rpmsg_test_id_table[] = {
88 	{ .name = "rpmsg-ap3-ch0" },
89 	{ /* sentinel */ },
90 };
91 
92 static struct rpmsg_driver rockchip_rpmsg_test = {
93 	.drv.name	= KBUILD_MODNAME,
94 	.drv.owner	= THIS_MODULE,
95 	.id_table	= rockchip_rpmsg_test_id_table,
96 	.probe		= rockchip_rpmsg_test_probe,
97 	.callback	= rockchip_rpmsg_test_cb,
98 	.remove		= rockchip_rpmsg_test_remove,
99 };
100 
init(void)101 static int __init init(void)
102 {
103 	return register_rpmsg_driver(&rockchip_rpmsg_test);
104 }
105 
fini(void)106 static void __exit fini(void)
107 {
108 	unregister_rpmsg_driver(&rockchip_rpmsg_test);
109 }
110 module_init(init);
111 module_exit(fini);
112 
113 MODULE_LICENSE("GPL");
114 MODULE_DESCRIPTION("Rockchip Remote Processors Messaging Test");
115 MODULE_AUTHOR("Hongming Zou <hongming.zou@rock-chips.com>");
116 
117