Lines Matching +full:rpmsg +full:- +full:name
1 // SPDX-License-Identifier: GPL-2.0
9 * Based on rpmsg performance statistics driver by Michal Simek, which in turn
10 * was based on TI & Google OMX rpmsg driver.
19 #include <linux/rpmsg.h>
23 #include <uapi/linux/rpmsg.h>
43 * struct rpmsg_ctrldev - control device for instantiating endpoint devices
44 * @rpdev: underlaying rpmsg device
55 * struct rpmsg_eptdev - endpoint device context
58 * @rpdev: underlaying rpmsg device
61 * @ept: rpmsg endpoint reference, when open
85 mutex_lock(&eptdev->ept_lock); in rpmsg_eptdev_destroy()
86 if (eptdev->ept) { in rpmsg_eptdev_destroy()
87 rpmsg_destroy_ept(eptdev->ept); in rpmsg_eptdev_destroy()
88 eptdev->ept = NULL; in rpmsg_eptdev_destroy()
90 mutex_unlock(&eptdev->ept_lock); in rpmsg_eptdev_destroy()
93 wake_up_interruptible(&eptdev->readq); in rpmsg_eptdev_destroy()
95 cdev_device_del(&eptdev->cdev, &eptdev->dev); in rpmsg_eptdev_destroy()
96 put_device(&eptdev->dev); in rpmsg_eptdev_destroy()
109 return -ENOMEM; in rpmsg_ept_cb()
113 spin_lock(&eptdev->queue_lock); in rpmsg_ept_cb()
114 skb_queue_tail(&eptdev->queue, skb); in rpmsg_ept_cb()
115 spin_unlock(&eptdev->queue_lock); in rpmsg_ept_cb()
118 wake_up_interruptible(&eptdev->readq); in rpmsg_ept_cb()
125 struct rpmsg_eptdev *eptdev = cdev_to_eptdev(inode->i_cdev); in rpmsg_eptdev_open()
127 struct rpmsg_device *rpdev = eptdev->rpdev; in rpmsg_eptdev_open()
128 struct device *dev = &eptdev->dev; in rpmsg_eptdev_open()
132 ept = rpmsg_create_ept(rpdev, rpmsg_ept_cb, eptdev, eptdev->chinfo); in rpmsg_eptdev_open()
134 dev_err(dev, "failed to open %s\n", eptdev->chinfo.name); in rpmsg_eptdev_open()
136 return -EINVAL; in rpmsg_eptdev_open()
139 eptdev->ept = ept; in rpmsg_eptdev_open()
140 filp->private_data = eptdev; in rpmsg_eptdev_open()
147 struct rpmsg_eptdev *eptdev = cdev_to_eptdev(inode->i_cdev); in rpmsg_eptdev_release()
148 struct device *dev = &eptdev->dev; in rpmsg_eptdev_release()
151 mutex_lock(&eptdev->ept_lock); in rpmsg_eptdev_release()
152 if (eptdev->ept) { in rpmsg_eptdev_release()
153 rpmsg_destroy_ept(eptdev->ept); in rpmsg_eptdev_release()
154 eptdev->ept = NULL; in rpmsg_eptdev_release()
156 mutex_unlock(&eptdev->ept_lock); in rpmsg_eptdev_release()
159 skb_queue_purge(&eptdev->queue); in rpmsg_eptdev_release()
168 struct file *filp = iocb->ki_filp; in rpmsg_eptdev_read_iter()
169 struct rpmsg_eptdev *eptdev = filp->private_data; in rpmsg_eptdev_read_iter()
174 if (!eptdev->ept) in rpmsg_eptdev_read_iter()
175 return -EPIPE; in rpmsg_eptdev_read_iter()
177 spin_lock_irqsave(&eptdev->queue_lock, flags); in rpmsg_eptdev_read_iter()
180 if (skb_queue_empty(&eptdev->queue)) { in rpmsg_eptdev_read_iter()
181 spin_unlock_irqrestore(&eptdev->queue_lock, flags); in rpmsg_eptdev_read_iter()
183 if (filp->f_flags & O_NONBLOCK) in rpmsg_eptdev_read_iter()
184 return -EAGAIN; in rpmsg_eptdev_read_iter()
187 if (wait_event_interruptible(eptdev->readq, in rpmsg_eptdev_read_iter()
188 !skb_queue_empty(&eptdev->queue) || in rpmsg_eptdev_read_iter()
189 !eptdev->ept)) in rpmsg_eptdev_read_iter()
190 return -ERESTARTSYS; in rpmsg_eptdev_read_iter()
193 if (!eptdev->ept) in rpmsg_eptdev_read_iter()
194 return -EPIPE; in rpmsg_eptdev_read_iter()
196 spin_lock_irqsave(&eptdev->queue_lock, flags); in rpmsg_eptdev_read_iter()
199 skb = skb_dequeue(&eptdev->queue); in rpmsg_eptdev_read_iter()
200 spin_unlock_irqrestore(&eptdev->queue_lock, flags); in rpmsg_eptdev_read_iter()
202 return -EFAULT; in rpmsg_eptdev_read_iter()
204 use = min_t(size_t, iov_iter_count(to), skb->len); in rpmsg_eptdev_read_iter()
205 if (copy_to_iter(skb->data, use, to) != use) in rpmsg_eptdev_read_iter()
206 use = -EFAULT; in rpmsg_eptdev_read_iter()
216 struct file *filp = iocb->ki_filp; in rpmsg_eptdev_write_iter()
217 struct rpmsg_eptdev *eptdev = filp->private_data; in rpmsg_eptdev_write_iter()
224 return -ENOMEM; in rpmsg_eptdev_write_iter()
227 ret = -EFAULT; in rpmsg_eptdev_write_iter()
231 if (mutex_lock_interruptible(&eptdev->ept_lock)) { in rpmsg_eptdev_write_iter()
232 ret = -ERESTARTSYS; in rpmsg_eptdev_write_iter()
236 if (!eptdev->ept) { in rpmsg_eptdev_write_iter()
237 ret = -EPIPE; in rpmsg_eptdev_write_iter()
241 if (filp->f_flags & O_NONBLOCK) in rpmsg_eptdev_write_iter()
242 ret = rpmsg_trysend(eptdev->ept, kbuf, len); in rpmsg_eptdev_write_iter()
244 ret = rpmsg_send(eptdev->ept, kbuf, len); in rpmsg_eptdev_write_iter()
247 mutex_unlock(&eptdev->ept_lock); in rpmsg_eptdev_write_iter()
256 struct rpmsg_eptdev *eptdev = filp->private_data; in rpmsg_eptdev_poll()
259 if (!eptdev->ept) in rpmsg_eptdev_poll()
262 poll_wait(filp, &eptdev->readq, wait); in rpmsg_eptdev_poll()
264 if (!skb_queue_empty(&eptdev->queue)) in rpmsg_eptdev_poll()
267 mask |= rpmsg_poll(eptdev->ept, filp, wait); in rpmsg_eptdev_poll()
275 struct rpmsg_eptdev *eptdev = fp->private_data; in rpmsg_eptdev_ioctl()
278 return -EINVAL; in rpmsg_eptdev_ioctl()
280 return rpmsg_eptdev_destroy(&eptdev->dev, NULL); in rpmsg_eptdev_ioctl()
299 return sprintf(buf, "%s\n", eptdev->chinfo.name); in name_show()
301 static DEVICE_ATTR_RO(name);
308 return sprintf(buf, "%d\n", eptdev->chinfo.src); in src_show()
317 return sprintf(buf, "%d\n", eptdev->chinfo.dst); in dst_show()
333 ida_simple_remove(&rpmsg_ept_ida, dev->id); in rpmsg_eptdev_release_device()
334 ida_simple_remove(&rpmsg_minor_ida, MINOR(eptdev->dev.devt)); in rpmsg_eptdev_release_device()
341 struct rpmsg_device *rpdev = ctrldev->rpdev; in rpmsg_eptdev_create()
348 return -ENOMEM; in rpmsg_eptdev_create()
350 dev = &eptdev->dev; in rpmsg_eptdev_create()
351 eptdev->rpdev = rpdev; in rpmsg_eptdev_create()
352 eptdev->chinfo = chinfo; in rpmsg_eptdev_create()
354 mutex_init(&eptdev->ept_lock); in rpmsg_eptdev_create()
355 spin_lock_init(&eptdev->queue_lock); in rpmsg_eptdev_create()
356 skb_queue_head_init(&eptdev->queue); in rpmsg_eptdev_create()
357 init_waitqueue_head(&eptdev->readq); in rpmsg_eptdev_create()
360 dev->class = rpmsg_class; in rpmsg_eptdev_create()
361 dev->parent = &ctrldev->dev; in rpmsg_eptdev_create()
362 dev->groups = rpmsg_eptdev_groups; in rpmsg_eptdev_create()
365 cdev_init(&eptdev->cdev, &rpmsg_eptdev_fops); in rpmsg_eptdev_create()
366 eptdev->cdev.owner = THIS_MODULE; in rpmsg_eptdev_create()
371 dev->devt = MKDEV(MAJOR(rpmsg_major), ret); in rpmsg_eptdev_create()
376 dev->id = ret; in rpmsg_eptdev_create()
377 dev_set_name(dev, "rpmsg%d", ret); in rpmsg_eptdev_create()
379 ret = cdev_device_add(&eptdev->cdev, &eptdev->dev); in rpmsg_eptdev_create()
384 dev->release = rpmsg_eptdev_release_device; in rpmsg_eptdev_create()
389 ida_simple_remove(&rpmsg_ept_ida, dev->id); in rpmsg_eptdev_create()
391 ida_simple_remove(&rpmsg_minor_ida, MINOR(dev->devt)); in rpmsg_eptdev_create()
401 struct rpmsg_ctrldev *ctrldev = cdev_to_ctrldev(inode->i_cdev); in rpmsg_ctrldev_open()
403 get_device(&ctrldev->dev); in rpmsg_ctrldev_open()
404 filp->private_data = ctrldev; in rpmsg_ctrldev_open()
411 struct rpmsg_ctrldev *ctrldev = cdev_to_ctrldev(inode->i_cdev); in rpmsg_ctrldev_release()
413 put_device(&ctrldev->dev); in rpmsg_ctrldev_release()
421 struct rpmsg_ctrldev *ctrldev = fp->private_data; in rpmsg_ctrldev_ioctl()
427 return -EINVAL; in rpmsg_ctrldev_ioctl()
430 return -EFAULT; in rpmsg_ctrldev_ioctl()
432 memcpy(chinfo.name, eptinfo.name, RPMSG_NAME_SIZE); in rpmsg_ctrldev_ioctl()
433 chinfo.name[RPMSG_NAME_SIZE-1] = '\0'; in rpmsg_ctrldev_ioctl()
452 ida_simple_remove(&rpmsg_ctrl_ida, dev->id); in rpmsg_ctrldev_release_device()
453 ida_simple_remove(&rpmsg_minor_ida, MINOR(dev->devt)); in rpmsg_ctrldev_release_device()
465 return -ENOMEM; in rpmsg_chrdev_probe()
467 ctrldev->rpdev = rpdev; in rpmsg_chrdev_probe()
469 dev = &ctrldev->dev; in rpmsg_chrdev_probe()
471 dev->parent = &rpdev->dev; in rpmsg_chrdev_probe()
472 dev->class = rpmsg_class; in rpmsg_chrdev_probe()
474 cdev_init(&ctrldev->cdev, &rpmsg_ctrldev_fops); in rpmsg_chrdev_probe()
475 ctrldev->cdev.owner = THIS_MODULE; in rpmsg_chrdev_probe()
480 dev->devt = MKDEV(MAJOR(rpmsg_major), ret); in rpmsg_chrdev_probe()
485 dev->id = ret; in rpmsg_chrdev_probe()
486 dev_set_name(&ctrldev->dev, "rpmsg_ctrl%d", ret); in rpmsg_chrdev_probe()
488 ret = cdev_device_add(&ctrldev->cdev, &ctrldev->dev); in rpmsg_chrdev_probe()
493 dev->release = rpmsg_ctrldev_release_device; in rpmsg_chrdev_probe()
495 dev_set_drvdata(&rpdev->dev, ctrldev); in rpmsg_chrdev_probe()
500 ida_simple_remove(&rpmsg_ctrl_ida, dev->id); in rpmsg_chrdev_probe()
502 ida_simple_remove(&rpmsg_minor_ida, MINOR(dev->devt)); in rpmsg_chrdev_probe()
512 struct rpmsg_ctrldev *ctrldev = dev_get_drvdata(&rpdev->dev); in rpmsg_chrdev_remove()
516 ret = device_for_each_child(&ctrldev->dev, NULL, rpmsg_eptdev_destroy); in rpmsg_chrdev_remove()
518 dev_warn(&rpdev->dev, "failed to nuke endpoints: %d\n", ret); in rpmsg_chrdev_remove()
520 cdev_device_del(&ctrldev->cdev, &ctrldev->dev); in rpmsg_chrdev_remove()
521 put_device(&ctrldev->dev); in rpmsg_chrdev_remove()
528 .name = "rpmsg_chrdev",
536 ret = alloc_chrdev_region(&rpmsg_major, 0, RPMSG_DEV_MAX, "rpmsg"); in rpmsg_char_init()
538 pr_err("rpmsg: failed to allocate char dev region\n"); in rpmsg_char_init()
542 rpmsg_class = class_create(THIS_MODULE, "rpmsg"); in rpmsg_char_init()
544 pr_err("failed to create rpmsg class\n"); in rpmsg_char_init()
551 pr_err("rpmsgchr: failed to register rpmsg driver\n"); in rpmsg_char_init()
568 MODULE_ALIAS("rpmsg:rpmsg_chrdev");