1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2022, STMicroelectronics
4 * Copyright (c) 2016, Linaro Ltd.
5 * Copyright (c) 2012, Michal Simek <monstr@monstr.eu>
6 * Copyright (c) 2012, PetaLogix
7 * Copyright (c) 2011, Texas Instruments, Inc.
8 * Copyright (c) 2011, Google, Inc.
10 * Based on rpmsg performance statistics driver by Michal Simek, which in turn
11 * was based on TI & Google OMX rpmsg driver.
14 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
16 #include <linux/cdev.h>
17 #include <linux/device.h>
19 #include <linux/idr.h>
20 #include <linux/kernel.h>
21 #include <linux/module.h>
22 #include <linux/rpmsg.h>
23 #include <linux/skbuff.h>
24 #include <linux/slab.h>
25 #include <linux/uaccess.h>
26 #include <uapi/linux/rpmsg.h>
28 #include "rpmsg_char.h"
29 #include "rpmsg_internal.h"
31 #define RPMSG_DEV_MAX (MINORMASK + 1)
33 static dev_t rpmsg_major
;
35 static DEFINE_IDA(rpmsg_ctrl_ida
);
36 static DEFINE_IDA(rpmsg_minor_ida
);
38 #define dev_to_ctrldev(dev) container_of(dev, struct rpmsg_ctrldev, dev)
39 #define cdev_to_ctrldev(i_cdev) container_of(i_cdev, struct rpmsg_ctrldev, cdev)
42 * struct rpmsg_ctrldev - control device for instantiating endpoint devices
43 * @rpdev: underlaying rpmsg device
44 * @cdev: cdev for the ctrl device
45 * @dev: device for the ctrl device
46 * @ctrl_lock: serialize the ioctrls.
48 struct rpmsg_ctrldev
{
49 struct rpmsg_device
*rpdev
;
52 struct mutex ctrl_lock
;
55 static int rpmsg_ctrldev_open(struct inode
*inode
, struct file
*filp
)
57 struct rpmsg_ctrldev
*ctrldev
= cdev_to_ctrldev(inode
->i_cdev
);
59 get_device(&ctrldev
->dev
);
60 filp
->private_data
= ctrldev
;
65 static int rpmsg_ctrldev_release(struct inode
*inode
, struct file
*filp
)
67 struct rpmsg_ctrldev
*ctrldev
= cdev_to_ctrldev(inode
->i_cdev
);
69 put_device(&ctrldev
->dev
);
74 static long rpmsg_ctrldev_ioctl(struct file
*fp
, unsigned int cmd
,
77 struct rpmsg_ctrldev
*ctrldev
= fp
->private_data
;
78 void __user
*argp
= (void __user
*)arg
;
79 struct rpmsg_endpoint_info eptinfo
;
80 struct rpmsg_channel_info chinfo
;
81 struct rpmsg_device
*rpdev
;
84 if (copy_from_user(&eptinfo
, argp
, sizeof(eptinfo
)))
87 memcpy(chinfo
.name
, eptinfo
.name
, RPMSG_NAME_SIZE
);
88 chinfo
.name
[RPMSG_NAME_SIZE
- 1] = '\0';
89 chinfo
.src
= eptinfo
.src
;
90 chinfo
.dst
= eptinfo
.dst
;
92 mutex_lock(&ctrldev
->ctrl_lock
);
94 case RPMSG_CREATE_EPT_IOCTL
:
95 ret
= rpmsg_chrdev_eptdev_create(ctrldev
->rpdev
, &ctrldev
->dev
, chinfo
);
98 case RPMSG_CREATE_DEV_IOCTL
:
99 rpdev
= rpmsg_create_channel(ctrldev
->rpdev
, &chinfo
);
101 dev_err(&ctrldev
->dev
, "failed to create %s channel\n", chinfo
.name
);
106 case RPMSG_RELEASE_DEV_IOCTL
:
107 ret
= rpmsg_release_channel(ctrldev
->rpdev
, &chinfo
);
109 dev_err(&ctrldev
->dev
, "failed to release %s channel (%d)\n",
116 mutex_unlock(&ctrldev
->ctrl_lock
);
121 static const struct file_operations rpmsg_ctrldev_fops
= {
122 .owner
= THIS_MODULE
,
123 .open
= rpmsg_ctrldev_open
,
124 .release
= rpmsg_ctrldev_release
,
125 .unlocked_ioctl
= rpmsg_ctrldev_ioctl
,
126 .compat_ioctl
= compat_ptr_ioctl
,
129 static void rpmsg_ctrldev_release_device(struct device
*dev
)
131 struct rpmsg_ctrldev
*ctrldev
= dev_to_ctrldev(dev
);
133 ida_free(&rpmsg_ctrl_ida
, dev
->id
);
134 ida_free(&rpmsg_minor_ida
, MINOR(dev
->devt
));
138 static int rpmsg_ctrldev_probe(struct rpmsg_device
*rpdev
)
140 struct rpmsg_ctrldev
*ctrldev
;
144 ctrldev
= kzalloc(sizeof(*ctrldev
), GFP_KERNEL
);
148 ctrldev
->rpdev
= rpdev
;
151 device_initialize(dev
);
152 dev
->parent
= &rpdev
->dev
;
153 dev
->class = &rpmsg_class
;
155 mutex_init(&ctrldev
->ctrl_lock
);
156 cdev_init(&ctrldev
->cdev
, &rpmsg_ctrldev_fops
);
157 ctrldev
->cdev
.owner
= THIS_MODULE
;
159 ret
= ida_alloc_max(&rpmsg_minor_ida
, RPMSG_DEV_MAX
- 1, GFP_KERNEL
);
162 dev
->devt
= MKDEV(MAJOR(rpmsg_major
), ret
);
164 ret
= ida_alloc(&rpmsg_ctrl_ida
, GFP_KERNEL
);
168 dev_set_name(&ctrldev
->dev
, "rpmsg_ctrl%d", ret
);
170 ret
= cdev_device_add(&ctrldev
->cdev
, &ctrldev
->dev
);
174 /* We can now rely on the release function for cleanup */
175 dev
->release
= rpmsg_ctrldev_release_device
;
177 dev_set_drvdata(&rpdev
->dev
, ctrldev
);
182 ida_free(&rpmsg_ctrl_ida
, dev
->id
);
184 ida_free(&rpmsg_minor_ida
, MINOR(dev
->devt
));
192 static void rpmsg_ctrldev_remove(struct rpmsg_device
*rpdev
)
194 struct rpmsg_ctrldev
*ctrldev
= dev_get_drvdata(&rpdev
->dev
);
197 mutex_lock(&ctrldev
->ctrl_lock
);
198 /* Destroy all endpoints */
199 ret
= device_for_each_child(&ctrldev
->dev
, NULL
, rpmsg_chrdev_eptdev_destroy
);
201 dev_warn(&rpdev
->dev
, "failed to nuke endpoints: %d\n", ret
);
202 mutex_unlock(&ctrldev
->ctrl_lock
);
204 cdev_device_del(&ctrldev
->cdev
, &ctrldev
->dev
);
205 put_device(&ctrldev
->dev
);
208 static struct rpmsg_driver rpmsg_ctrldev_driver
= {
209 .probe
= rpmsg_ctrldev_probe
,
210 .remove
= rpmsg_ctrldev_remove
,
212 .name
= "rpmsg_ctrl",
216 static int rpmsg_ctrldev_init(void)
220 ret
= alloc_chrdev_region(&rpmsg_major
, 0, RPMSG_DEV_MAX
, "rpmsg_ctrl");
222 pr_err("failed to allocate char dev region\n");
226 ret
= register_rpmsg_driver(&rpmsg_ctrldev_driver
);
228 pr_err("failed to register rpmsg driver\n");
229 unregister_chrdev_region(rpmsg_major
, RPMSG_DEV_MAX
);
234 postcore_initcall(rpmsg_ctrldev_init
);
236 static void rpmsg_ctrldev_exit(void)
238 unregister_rpmsg_driver(&rpmsg_ctrldev_driver
);
239 unregister_chrdev_region(rpmsg_major
, RPMSG_DEV_MAX
);
241 module_exit(rpmsg_ctrldev_exit
);
243 MODULE_DESCRIPTION("rpmsg control interface");
244 MODULE_ALIAS("rpmsg:" KBUILD_MODNAME
);
245 MODULE_LICENSE("GPL v2");