Lines Matching +full:rpmsg +full:- +full:in

1 // SPDX-License-Identifier: GPL-2.0
10 * Based on rpmsg performance statistics driver by Michal Simek, which in turn
11 * was based on TI & Google OMX rpmsg driver.
23 #include <linux/rpmsg.h>
27 #include <uapi/linux/rpmsg.h>
43 * struct rpmsg_eptdev - endpoint device context
46 * @rpdev: underlaying rpmsg device
49 * @ept: rpmsg endpoint reference, when open
53 * @default_ept: set to channel default endpoint if the default endpoint should be re-used
81 mutex_lock(&eptdev->ept_lock); in rpmsg_chrdev_eptdev_destroy()
82 eptdev->rpdev = NULL; in rpmsg_chrdev_eptdev_destroy()
83 if (eptdev->ept) { in rpmsg_chrdev_eptdev_destroy()
84 /* The default endpoint is released by the rpmsg core */ in rpmsg_chrdev_eptdev_destroy()
85 if (!eptdev->default_ept) in rpmsg_chrdev_eptdev_destroy()
86 rpmsg_destroy_ept(eptdev->ept); in rpmsg_chrdev_eptdev_destroy()
87 eptdev->ept = NULL; in rpmsg_chrdev_eptdev_destroy()
89 mutex_unlock(&eptdev->ept_lock); in rpmsg_chrdev_eptdev_destroy()
92 wake_up_interruptible(&eptdev->readq); in rpmsg_chrdev_eptdev_destroy()
94 cdev_device_del(&eptdev->cdev, &eptdev->dev); in rpmsg_chrdev_eptdev_destroy()
95 put_device(&eptdev->dev); in rpmsg_chrdev_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()
127 eptdev->remote_flow_restricted = enable; in rpmsg_ept_flow_cb()
128 eptdev->remote_flow_updated = true; in rpmsg_ept_flow_cb()
130 wake_up_interruptible(&eptdev->readq); in rpmsg_ept_flow_cb()
137 struct rpmsg_eptdev *eptdev = cdev_to_eptdev(inode->i_cdev); in rpmsg_eptdev_open()
139 struct rpmsg_device *rpdev = eptdev->rpdev; in rpmsg_eptdev_open()
140 struct device *dev = &eptdev->dev; in rpmsg_eptdev_open()
142 mutex_lock(&eptdev->ept_lock); in rpmsg_eptdev_open()
143 if (eptdev->ept) { in rpmsg_eptdev_open()
144 mutex_unlock(&eptdev->ept_lock); in rpmsg_eptdev_open()
145 return -EBUSY; in rpmsg_eptdev_open()
148 if (!eptdev->rpdev) { in rpmsg_eptdev_open()
149 mutex_unlock(&eptdev->ept_lock); in rpmsg_eptdev_open()
150 return -ENETRESET; in rpmsg_eptdev_open()
156 * If the default_ept is set, the rpmsg device default endpoint is used. in rpmsg_eptdev_open()
159 if (eptdev->default_ept) in rpmsg_eptdev_open()
160 ept = eptdev->default_ept; in rpmsg_eptdev_open()
162 ept = rpmsg_create_ept(rpdev, rpmsg_ept_cb, eptdev, eptdev->chinfo); in rpmsg_eptdev_open()
165 dev_err(dev, "failed to open %s\n", eptdev->chinfo.name); in rpmsg_eptdev_open()
167 mutex_unlock(&eptdev->ept_lock); in rpmsg_eptdev_open()
168 return -EINVAL; in rpmsg_eptdev_open()
171 ept->flow_cb = rpmsg_ept_flow_cb; in rpmsg_eptdev_open()
172 eptdev->ept = ept; in rpmsg_eptdev_open()
173 filp->private_data = eptdev; in rpmsg_eptdev_open()
174 mutex_unlock(&eptdev->ept_lock); in rpmsg_eptdev_open()
181 struct rpmsg_eptdev *eptdev = cdev_to_eptdev(inode->i_cdev); in rpmsg_eptdev_release()
182 struct device *dev = &eptdev->dev; in rpmsg_eptdev_release()
185 mutex_lock(&eptdev->ept_lock); in rpmsg_eptdev_release()
186 if (eptdev->ept) { in rpmsg_eptdev_release()
187 if (!eptdev->default_ept) in rpmsg_eptdev_release()
188 rpmsg_destroy_ept(eptdev->ept); in rpmsg_eptdev_release()
189 eptdev->ept = NULL; in rpmsg_eptdev_release()
191 mutex_unlock(&eptdev->ept_lock); in rpmsg_eptdev_release()
192 eptdev->remote_flow_updated = false; in rpmsg_eptdev_release()
195 skb_queue_purge(&eptdev->queue); in rpmsg_eptdev_release()
204 struct file *filp = iocb->ki_filp; in rpmsg_eptdev_read_iter()
205 struct rpmsg_eptdev *eptdev = filp->private_data; in rpmsg_eptdev_read_iter()
210 if (!eptdev->ept) in rpmsg_eptdev_read_iter()
211 return -EPIPE; in rpmsg_eptdev_read_iter()
213 spin_lock_irqsave(&eptdev->queue_lock, flags); in rpmsg_eptdev_read_iter()
215 /* Wait for data in the queue */ in rpmsg_eptdev_read_iter()
216 if (skb_queue_empty(&eptdev->queue)) { in rpmsg_eptdev_read_iter()
217 spin_unlock_irqrestore(&eptdev->queue_lock, flags); in rpmsg_eptdev_read_iter()
219 if (filp->f_flags & O_NONBLOCK) in rpmsg_eptdev_read_iter()
220 return -EAGAIN; in rpmsg_eptdev_read_iter()
223 if (wait_event_interruptible(eptdev->readq, in rpmsg_eptdev_read_iter()
224 !skb_queue_empty(&eptdev->queue) || in rpmsg_eptdev_read_iter()
225 !eptdev->ept)) in rpmsg_eptdev_read_iter()
226 return -ERESTARTSYS; in rpmsg_eptdev_read_iter()
229 if (!eptdev->ept) in rpmsg_eptdev_read_iter()
230 return -EPIPE; in rpmsg_eptdev_read_iter()
232 spin_lock_irqsave(&eptdev->queue_lock, flags); in rpmsg_eptdev_read_iter()
235 skb = skb_dequeue(&eptdev->queue); in rpmsg_eptdev_read_iter()
236 spin_unlock_irqrestore(&eptdev->queue_lock, flags); in rpmsg_eptdev_read_iter()
238 return -EFAULT; in rpmsg_eptdev_read_iter()
240 use = min_t(size_t, iov_iter_count(to), skb->len); in rpmsg_eptdev_read_iter()
241 if (copy_to_iter(skb->data, use, to) != use) in rpmsg_eptdev_read_iter()
242 use = -EFAULT; in rpmsg_eptdev_read_iter()
252 struct file *filp = iocb->ki_filp; in rpmsg_eptdev_write_iter()
253 struct rpmsg_eptdev *eptdev = filp->private_data; in rpmsg_eptdev_write_iter()
260 return -ENOMEM; in rpmsg_eptdev_write_iter()
263 ret = -EFAULT; in rpmsg_eptdev_write_iter()
267 if (mutex_lock_interruptible(&eptdev->ept_lock)) { in rpmsg_eptdev_write_iter()
268 ret = -ERESTARTSYS; in rpmsg_eptdev_write_iter()
272 if (!eptdev->ept) { in rpmsg_eptdev_write_iter()
273 ret = -EPIPE; in rpmsg_eptdev_write_iter()
277 if (filp->f_flags & O_NONBLOCK) { in rpmsg_eptdev_write_iter()
278 ret = rpmsg_trysendto(eptdev->ept, kbuf, len, eptdev->chinfo.dst); in rpmsg_eptdev_write_iter()
279 if (ret == -ENOMEM) in rpmsg_eptdev_write_iter()
280 ret = -EAGAIN; in rpmsg_eptdev_write_iter()
282 ret = rpmsg_sendto(eptdev->ept, kbuf, len, eptdev->chinfo.dst); in rpmsg_eptdev_write_iter()
286 mutex_unlock(&eptdev->ept_lock); in rpmsg_eptdev_write_iter()
295 struct rpmsg_eptdev *eptdev = filp->private_data; in rpmsg_eptdev_poll()
298 if (!eptdev->ept) in rpmsg_eptdev_poll()
301 poll_wait(filp, &eptdev->readq, wait); in rpmsg_eptdev_poll()
303 if (!skb_queue_empty(&eptdev->queue)) in rpmsg_eptdev_poll()
306 if (eptdev->remote_flow_updated) in rpmsg_eptdev_poll()
309 mutex_lock(&eptdev->ept_lock); in rpmsg_eptdev_poll()
310 mask |= rpmsg_poll(eptdev->ept, filp, wait); in rpmsg_eptdev_poll()
311 mutex_unlock(&eptdev->ept_lock); in rpmsg_eptdev_poll()
319 struct rpmsg_eptdev *eptdev = fp->private_data; in rpmsg_eptdev_ioctl()
326 eptdev->remote_flow_updated = false; in rpmsg_eptdev_ioctl()
327 ret = put_user(eptdev->remote_flow_restricted, (int __user *)arg); in rpmsg_eptdev_ioctl()
331 ret = -EINVAL; in rpmsg_eptdev_ioctl()
335 ret = rpmsg_set_flow_control(eptdev->ept, set, eptdev->chinfo.dst); in rpmsg_eptdev_ioctl()
339 if (eptdev->default_ept) { in rpmsg_eptdev_ioctl()
340 ret = -EINVAL; in rpmsg_eptdev_ioctl()
343 ret = rpmsg_chrdev_eptdev_destroy(&eptdev->dev, NULL); in rpmsg_eptdev_ioctl()
346 ret = -EINVAL; in rpmsg_eptdev_ioctl()
368 return sprintf(buf, "%s\n", eptdev->chinfo.name); in name_show()
377 return sprintf(buf, "%d\n", eptdev->chinfo.src); in src_show()
386 return sprintf(buf, "%d\n", eptdev->chinfo.dst); in dst_show()
402 ida_free(&rpmsg_ept_ida, dev->id); in rpmsg_eptdev_release_device()
403 ida_free(&rpmsg_minor_ida, MINOR(eptdev->dev.devt)); in rpmsg_eptdev_release_device()
415 return ERR_PTR(-ENOMEM); in rpmsg_chrdev_eptdev_alloc()
417 dev = &eptdev->dev; in rpmsg_chrdev_eptdev_alloc()
418 eptdev->rpdev = rpdev; in rpmsg_chrdev_eptdev_alloc()
420 mutex_init(&eptdev->ept_lock); in rpmsg_chrdev_eptdev_alloc()
421 spin_lock_init(&eptdev->queue_lock); in rpmsg_chrdev_eptdev_alloc()
422 skb_queue_head_init(&eptdev->queue); in rpmsg_chrdev_eptdev_alloc()
423 init_waitqueue_head(&eptdev->readq); in rpmsg_chrdev_eptdev_alloc()
426 dev->class = &rpmsg_class; in rpmsg_chrdev_eptdev_alloc()
427 dev->parent = parent; in rpmsg_chrdev_eptdev_alloc()
428 dev->groups = rpmsg_eptdev_groups; in rpmsg_chrdev_eptdev_alloc()
431 cdev_init(&eptdev->cdev, &rpmsg_eptdev_fops); in rpmsg_chrdev_eptdev_alloc()
432 eptdev->cdev.owner = THIS_MODULE; in rpmsg_chrdev_eptdev_alloc()
439 struct device *dev = &eptdev->dev; in rpmsg_chrdev_eptdev_add()
442 eptdev->chinfo = chinfo; in rpmsg_chrdev_eptdev_add()
444 ret = ida_alloc_max(&rpmsg_minor_ida, RPMSG_DEV_MAX - 1, GFP_KERNEL); in rpmsg_chrdev_eptdev_add()
447 dev->devt = MKDEV(MAJOR(rpmsg_major), ret); in rpmsg_chrdev_eptdev_add()
452 dev->id = ret; in rpmsg_chrdev_eptdev_add()
453 dev_set_name(dev, "rpmsg%d", ret); in rpmsg_chrdev_eptdev_add()
455 ret = cdev_device_add(&eptdev->cdev, &eptdev->dev); in rpmsg_chrdev_eptdev_add()
460 dev->release = rpmsg_eptdev_release_device; in rpmsg_chrdev_eptdev_add()
465 ida_free(&rpmsg_ept_ida, dev->id); in rpmsg_chrdev_eptdev_add()
467 ida_free(&rpmsg_minor_ida, MINOR(dev->devt)); in rpmsg_chrdev_eptdev_add()
492 struct device *dev = &rpdev->dev; in rpmsg_chrdev_probe()
494 memcpy(chinfo.name, rpdev->id.name, RPMSG_NAME_SIZE); in rpmsg_chrdev_probe()
495 chinfo.src = rpdev->src; in rpmsg_chrdev_probe()
496 chinfo.dst = rpdev->dst; in rpmsg_chrdev_probe()
502 /* Set the default_ept to the rpmsg device endpoint */ in rpmsg_chrdev_probe()
503 eptdev->default_ept = rpdev->ept; in rpmsg_chrdev_probe()
507 * Storedit in default_ept *priv field. in rpmsg_chrdev_probe()
509 eptdev->default_ept->priv = eptdev; in rpmsg_chrdev_probe()
518 ret = device_for_each_child(&rpdev->dev, NULL, rpmsg_chrdev_eptdev_destroy); in rpmsg_chrdev_remove()
520 dev_warn(&rpdev->dev, "failed to destroy endpoints: %d\n", ret); in rpmsg_chrdev_remove()
524 { .name = "rpmsg-raw" },
548 pr_err("rpmsg: failed to register rpmsg raw driver\n"); in rpmsg_chrdev_init()
568 MODULE_ALIAS("rpmsg:rpmsg_chrdev");
569 MODULE_DESCRIPTION("RPMSG device interface");