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 device_del(&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()
130 if (eptdev->ept) in rpmsg_eptdev_open()
131 return -EBUSY; in rpmsg_eptdev_open()
135 ept = rpmsg_create_ept(rpdev, rpmsg_ept_cb, eptdev, eptdev->chinfo); in rpmsg_eptdev_open()
137 dev_err(dev, "failed to open %s\n", eptdev->chinfo.name); in rpmsg_eptdev_open()
139 return -EINVAL; in rpmsg_eptdev_open()
142 eptdev->ept = ept; in rpmsg_eptdev_open()
143 filp->private_data = eptdev; in rpmsg_eptdev_open()
150 struct rpmsg_eptdev *eptdev = cdev_to_eptdev(inode->i_cdev); in rpmsg_eptdev_release()
151 struct device *dev = &eptdev->dev; in rpmsg_eptdev_release()
154 mutex_lock(&eptdev->ept_lock); in rpmsg_eptdev_release()
155 if (eptdev->ept) { in rpmsg_eptdev_release()
156 rpmsg_destroy_ept(eptdev->ept); in rpmsg_eptdev_release()
157 eptdev->ept = NULL; in rpmsg_eptdev_release()
159 mutex_unlock(&eptdev->ept_lock); in rpmsg_eptdev_release()
162 skb_queue_purge(&eptdev->queue); in rpmsg_eptdev_release()
171 struct file *filp = iocb->ki_filp; in rpmsg_eptdev_read_iter()
172 struct rpmsg_eptdev *eptdev = filp->private_data; in rpmsg_eptdev_read_iter()
177 if (!eptdev->ept) in rpmsg_eptdev_read_iter()
178 return -EPIPE; in rpmsg_eptdev_read_iter()
180 spin_lock_irqsave(&eptdev->queue_lock, flags); in rpmsg_eptdev_read_iter()
183 if (skb_queue_empty(&eptdev->queue)) { in rpmsg_eptdev_read_iter()
184 spin_unlock_irqrestore(&eptdev->queue_lock, flags); in rpmsg_eptdev_read_iter()
186 if (filp->f_flags & O_NONBLOCK) in rpmsg_eptdev_read_iter()
187 return -EAGAIN; in rpmsg_eptdev_read_iter()
190 if (wait_event_interruptible(eptdev->readq, in rpmsg_eptdev_read_iter()
191 !skb_queue_empty(&eptdev->queue) || in rpmsg_eptdev_read_iter()
192 !eptdev->ept)) in rpmsg_eptdev_read_iter()
193 return -ERESTARTSYS; in rpmsg_eptdev_read_iter()
196 if (!eptdev->ept) in rpmsg_eptdev_read_iter()
197 return -EPIPE; in rpmsg_eptdev_read_iter()
199 spin_lock_irqsave(&eptdev->queue_lock, flags); in rpmsg_eptdev_read_iter()
202 skb = skb_dequeue(&eptdev->queue); in rpmsg_eptdev_read_iter()
203 spin_unlock_irqrestore(&eptdev->queue_lock, flags); in rpmsg_eptdev_read_iter()
205 return -EFAULT; in rpmsg_eptdev_read_iter()
207 use = min_t(size_t, iov_iter_count(to), skb->len); in rpmsg_eptdev_read_iter()
208 if (copy_to_iter(skb->data, use, to) != use) in rpmsg_eptdev_read_iter()
209 use = -EFAULT; in rpmsg_eptdev_read_iter()
219 struct file *filp = iocb->ki_filp; in rpmsg_eptdev_write_iter()
220 struct rpmsg_eptdev *eptdev = filp->private_data; in rpmsg_eptdev_write_iter()
227 return -ENOMEM; in rpmsg_eptdev_write_iter()
230 ret = -EFAULT; in rpmsg_eptdev_write_iter()
234 if (mutex_lock_interruptible(&eptdev->ept_lock)) { in rpmsg_eptdev_write_iter()
235 ret = -ERESTARTSYS; in rpmsg_eptdev_write_iter()
239 if (!eptdev->ept) { in rpmsg_eptdev_write_iter()
240 ret = -EPIPE; in rpmsg_eptdev_write_iter()
244 if (filp->f_flags & O_NONBLOCK) in rpmsg_eptdev_write_iter()
245 ret = rpmsg_trysendto(eptdev->ept, kbuf, len, eptdev->chinfo.dst); in rpmsg_eptdev_write_iter()
247 ret = rpmsg_sendto(eptdev->ept, kbuf, len, eptdev->chinfo.dst); in rpmsg_eptdev_write_iter()
250 mutex_unlock(&eptdev->ept_lock); in rpmsg_eptdev_write_iter()
259 struct rpmsg_eptdev *eptdev = filp->private_data; in rpmsg_eptdev_poll()
262 if (!eptdev->ept) in rpmsg_eptdev_poll()
265 poll_wait(filp, &eptdev->readq, wait); in rpmsg_eptdev_poll()
267 if (!skb_queue_empty(&eptdev->queue)) in rpmsg_eptdev_poll()
270 mask |= rpmsg_poll(eptdev->ept, filp, wait); in rpmsg_eptdev_poll()
278 struct rpmsg_eptdev *eptdev = fp->private_data; in rpmsg_eptdev_ioctl()
281 return -EINVAL; in rpmsg_eptdev_ioctl()
283 return rpmsg_eptdev_destroy(&eptdev->dev, NULL); in rpmsg_eptdev_ioctl()
302 return sprintf(buf, "%s\n", eptdev->chinfo.name); in name_show()
304 static DEVICE_ATTR_RO(name);
311 return sprintf(buf, "%d\n", eptdev->chinfo.src); in src_show()
320 return sprintf(buf, "%d\n", eptdev->chinfo.dst); in dst_show()
336 ida_simple_remove(&rpmsg_ept_ida, dev->id); in rpmsg_eptdev_release_device()
337 ida_simple_remove(&rpmsg_minor_ida, MINOR(eptdev->dev.devt)); in rpmsg_eptdev_release_device()
338 cdev_del(&eptdev->cdev); in rpmsg_eptdev_release_device()
345 struct rpmsg_device *rpdev = ctrldev->rpdev; in rpmsg_eptdev_create()
352 return -ENOMEM; in rpmsg_eptdev_create()
354 dev = &eptdev->dev; in rpmsg_eptdev_create()
355 eptdev->rpdev = rpdev; in rpmsg_eptdev_create()
356 eptdev->chinfo = chinfo; in rpmsg_eptdev_create()
358 mutex_init(&eptdev->ept_lock); in rpmsg_eptdev_create()
359 spin_lock_init(&eptdev->queue_lock); in rpmsg_eptdev_create()
360 skb_queue_head_init(&eptdev->queue); in rpmsg_eptdev_create()
361 init_waitqueue_head(&eptdev->readq); in rpmsg_eptdev_create()
364 dev->class = rpmsg_class; in rpmsg_eptdev_create()
365 dev->parent = &ctrldev->dev; in rpmsg_eptdev_create()
366 dev->groups = rpmsg_eptdev_groups; in rpmsg_eptdev_create()
369 cdev_init(&eptdev->cdev, &rpmsg_eptdev_fops); in rpmsg_eptdev_create()
370 eptdev->cdev.owner = THIS_MODULE; in rpmsg_eptdev_create()
375 dev->devt = MKDEV(MAJOR(rpmsg_major), ret); in rpmsg_eptdev_create()
380 dev->id = ret; in rpmsg_eptdev_create()
381 dev_set_name(dev, "rpmsg%d", ret); in rpmsg_eptdev_create()
383 ret = cdev_add(&eptdev->cdev, dev->devt, 1); in rpmsg_eptdev_create()
388 dev->release = rpmsg_eptdev_release_device; in rpmsg_eptdev_create()
399 ida_simple_remove(&rpmsg_ept_ida, dev->id); in rpmsg_eptdev_create()
401 ida_simple_remove(&rpmsg_minor_ida, MINOR(dev->devt)); in rpmsg_eptdev_create()
411 struct rpmsg_ctrldev *ctrldev = cdev_to_ctrldev(inode->i_cdev); in rpmsg_ctrldev_open()
413 get_device(&ctrldev->dev); in rpmsg_ctrldev_open()
414 filp->private_data = ctrldev; in rpmsg_ctrldev_open()
421 struct rpmsg_ctrldev *ctrldev = cdev_to_ctrldev(inode->i_cdev); in rpmsg_ctrldev_release()
423 put_device(&ctrldev->dev); in rpmsg_ctrldev_release()
431 struct rpmsg_ctrldev *ctrldev = fp->private_data; in rpmsg_ctrldev_ioctl()
437 return -EINVAL; in rpmsg_ctrldev_ioctl()
440 return -EFAULT; in rpmsg_ctrldev_ioctl()
442 memcpy(chinfo.name, eptinfo.name, RPMSG_NAME_SIZE); in rpmsg_ctrldev_ioctl()
443 chinfo.name[RPMSG_NAME_SIZE-1] = '\0'; in rpmsg_ctrldev_ioctl()
462 ida_simple_remove(&rpmsg_ctrl_ida, dev->id); in rpmsg_ctrldev_release_device()
463 ida_simple_remove(&rpmsg_minor_ida, MINOR(dev->devt)); in rpmsg_ctrldev_release_device()
464 cdev_del(&ctrldev->cdev); in rpmsg_ctrldev_release_device()
476 return -ENOMEM; in rpmsg_chrdev_probe()
478 ctrldev->rpdev = rpdev; in rpmsg_chrdev_probe()
480 dev = &ctrldev->dev; in rpmsg_chrdev_probe()
482 dev->parent = &rpdev->dev; in rpmsg_chrdev_probe()
483 dev->class = rpmsg_class; in rpmsg_chrdev_probe()
485 cdev_init(&ctrldev->cdev, &rpmsg_ctrldev_fops); in rpmsg_chrdev_probe()
486 ctrldev->cdev.owner = THIS_MODULE; in rpmsg_chrdev_probe()
491 dev->devt = MKDEV(MAJOR(rpmsg_major), ret); in rpmsg_chrdev_probe()
496 dev->id = ret; in rpmsg_chrdev_probe()
497 dev_set_name(&ctrldev->dev, "rpmsg_ctrl%d", ret); in rpmsg_chrdev_probe()
499 ret = cdev_add(&ctrldev->cdev, dev->devt, 1); in rpmsg_chrdev_probe()
504 dev->release = rpmsg_ctrldev_release_device; in rpmsg_chrdev_probe()
508 dev_err(&rpdev->dev, "device_add failed: %d\n", ret); in rpmsg_chrdev_probe()
512 dev_set_drvdata(&rpdev->dev, ctrldev); in rpmsg_chrdev_probe()
517 ida_simple_remove(&rpmsg_ctrl_ida, dev->id); in rpmsg_chrdev_probe()
519 ida_simple_remove(&rpmsg_minor_ida, MINOR(dev->devt)); in rpmsg_chrdev_probe()
529 struct rpmsg_ctrldev *ctrldev = dev_get_drvdata(&rpdev->dev); in rpmsg_chrdev_remove()
533 ret = device_for_each_child(&ctrldev->dev, NULL, rpmsg_eptdev_destroy); in rpmsg_chrdev_remove()
535 dev_warn(&rpdev->dev, "failed to nuke endpoints: %d\n", ret); in rpmsg_chrdev_remove()
537 device_del(&ctrldev->dev); in rpmsg_chrdev_remove()
538 put_device(&ctrldev->dev); in rpmsg_chrdev_remove()
545 .name = "rpmsg_chrdev",
553 ret = alloc_chrdev_region(&rpmsg_major, 0, RPMSG_DEV_MAX, "rpmsg"); in rpmsg_chrdev_init()
555 pr_err("rpmsg: failed to allocate char dev region\n"); in rpmsg_chrdev_init()
559 rpmsg_class = class_create(THIS_MODULE, "rpmsg"); in rpmsg_chrdev_init()
561 pr_err("failed to create rpmsg class\n"); in rpmsg_chrdev_init()
568 pr_err("rpmsgchr: failed to register rpmsg driver\n"); in rpmsg_chrdev_init()
585 MODULE_ALIAS("rpmsg:rpmsg_chrdev");