rpmsg_char.c (cbf58250b33e26d7e8e84919ee71eb1129f91f12) rpmsg_char.c (69265bc12b6567c6aa9550a198b791e876fbfd2c)
1// SPDX-License-Identifier: GPL-2.0
2/*
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2022, STMicroelectronics
3 * Copyright (c) 2016, Linaro Ltd.
4 * Copyright (c) 2012, Michal Simek <monstr@monstr.eu>
5 * Copyright (c) 2012, PetaLogix
6 * Copyright (c) 2011, Texas Instruments, Inc.
7 * Copyright (c) 2011, Google, Inc.
8 *
9 * Based on rpmsg performance statistics driver by Michal Simek, which in turn
10 * was based on TI & Google OMX rpmsg driver.

--- 9 unchanged lines hidden (view full) ---

20#include <linux/module.h>
21#include <linux/poll.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>
27
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.
9 *
10 * Based on rpmsg performance statistics driver by Michal Simek, which in turn
11 * was based on TI & Google OMX rpmsg driver.

--- 9 unchanged lines hidden (view full) ---

21#include <linux/module.h>
22#include <linux/poll.h>
23#include <linux/rpmsg.h>
24#include <linux/skbuff.h>
25#include <linux/slab.h>
26#include <linux/uaccess.h>
27#include <uapi/linux/rpmsg.h>
28
29#include "rpmsg_char.h"
30
28#define RPMSG_DEV_MAX (MINORMASK + 1)
29
30static dev_t rpmsg_major;
31static struct class *rpmsg_class;
32
33static DEFINE_IDA(rpmsg_ctrl_ida);
34static DEFINE_IDA(rpmsg_ept_ida);
35static DEFINE_IDA(rpmsg_minor_ida);

--- 38 unchanged lines hidden (view full) ---

74 struct mutex ept_lock;
75 struct rpmsg_endpoint *ept;
76
77 spinlock_t queue_lock;
78 struct sk_buff_head queue;
79 wait_queue_head_t readq;
80};
81
31#define RPMSG_DEV_MAX (MINORMASK + 1)
32
33static dev_t rpmsg_major;
34static struct class *rpmsg_class;
35
36static DEFINE_IDA(rpmsg_ctrl_ida);
37static DEFINE_IDA(rpmsg_ept_ida);
38static DEFINE_IDA(rpmsg_minor_ida);

--- 38 unchanged lines hidden (view full) ---

77 struct mutex ept_lock;
78 struct rpmsg_endpoint *ept;
79
80 spinlock_t queue_lock;
81 struct sk_buff_head queue;
82 wait_queue_head_t readq;
83};
84
82static int rpmsg_eptdev_destroy(struct device *dev, void *data)
85int rpmsg_chrdev_eptdev_destroy(struct device *dev, void *data)
83{
84 struct rpmsg_eptdev *eptdev = dev_to_eptdev(dev);
85
86 mutex_lock(&eptdev->ept_lock);
87 if (eptdev->ept) {
88 rpmsg_destroy_ept(eptdev->ept);
89 eptdev->ept = NULL;
90 }
91 mutex_unlock(&eptdev->ept_lock);
92
93 /* wake up any blocked readers */
94 wake_up_interruptible(&eptdev->readq);
95
96 cdev_device_del(&eptdev->cdev, &eptdev->dev);
97 put_device(&eptdev->dev);
98
99 return 0;
100}
86{
87 struct rpmsg_eptdev *eptdev = dev_to_eptdev(dev);
88
89 mutex_lock(&eptdev->ept_lock);
90 if (eptdev->ept) {
91 rpmsg_destroy_ept(eptdev->ept);
92 eptdev->ept = NULL;
93 }
94 mutex_unlock(&eptdev->ept_lock);
95
96 /* wake up any blocked readers */
97 wake_up_interruptible(&eptdev->readq);
98
99 cdev_device_del(&eptdev->cdev, &eptdev->dev);
100 put_device(&eptdev->dev);
101
102 return 0;
103}
104EXPORT_SYMBOL(rpmsg_chrdev_eptdev_destroy);
101
102static int rpmsg_ept_cb(struct rpmsg_device *rpdev, void *buf, int len,
103 void *priv, u32 addr)
104{
105 struct rpmsg_eptdev *eptdev = priv;
106 struct sk_buff *skb;
107
108 skb = alloc_skb(len, GFP_ATOMIC);

--- 170 unchanged lines hidden (view full) ---

279static long rpmsg_eptdev_ioctl(struct file *fp, unsigned int cmd,
280 unsigned long arg)
281{
282 struct rpmsg_eptdev *eptdev = fp->private_data;
283
284 if (cmd != RPMSG_DESTROY_EPT_IOCTL)
285 return -EINVAL;
286
105
106static int rpmsg_ept_cb(struct rpmsg_device *rpdev, void *buf, int len,
107 void *priv, u32 addr)
108{
109 struct rpmsg_eptdev *eptdev = priv;
110 struct sk_buff *skb;
111
112 skb = alloc_skb(len, GFP_ATOMIC);

--- 170 unchanged lines hidden (view full) ---

283static long rpmsg_eptdev_ioctl(struct file *fp, unsigned int cmd,
284 unsigned long arg)
285{
286 struct rpmsg_eptdev *eptdev = fp->private_data;
287
288 if (cmd != RPMSG_DESTROY_EPT_IOCTL)
289 return -EINVAL;
290
287 return rpmsg_eptdev_destroy(&eptdev->dev, NULL);
291 return rpmsg_chrdev_eptdev_destroy(&eptdev->dev, NULL);
288}
289
290static const struct file_operations rpmsg_eptdev_fops = {
291 .owner = THIS_MODULE,
292 .open = rpmsg_eptdev_open,
293 .release = rpmsg_eptdev_release,
294 .read_iter = rpmsg_eptdev_read_iter,
295 .write_iter = rpmsg_eptdev_write_iter,

--- 41 unchanged lines hidden (view full) ---

337{
338 struct rpmsg_eptdev *eptdev = dev_to_eptdev(dev);
339
340 ida_simple_remove(&rpmsg_ept_ida, dev->id);
341 ida_simple_remove(&rpmsg_minor_ida, MINOR(eptdev->dev.devt));
342 kfree(eptdev);
343}
344
292}
293
294static const struct file_operations rpmsg_eptdev_fops = {
295 .owner = THIS_MODULE,
296 .open = rpmsg_eptdev_open,
297 .release = rpmsg_eptdev_release,
298 .read_iter = rpmsg_eptdev_read_iter,
299 .write_iter = rpmsg_eptdev_write_iter,

--- 41 unchanged lines hidden (view full) ---

341{
342 struct rpmsg_eptdev *eptdev = dev_to_eptdev(dev);
343
344 ida_simple_remove(&rpmsg_ept_ida, dev->id);
345 ida_simple_remove(&rpmsg_minor_ida, MINOR(eptdev->dev.devt));
346 kfree(eptdev);
347}
348
345static int rpmsg_eptdev_create(struct rpmsg_ctrldev *ctrldev,
349int rpmsg_chrdev_eptdev_create(struct rpmsg_device *rpdev, struct device *parent,
346 struct rpmsg_channel_info chinfo)
347{
350 struct rpmsg_channel_info chinfo)
351{
348 struct rpmsg_device *rpdev = ctrldev->rpdev;
349 struct rpmsg_eptdev *eptdev;
350 struct device *dev;
351 int ret;
352
353 eptdev = kzalloc(sizeof(*eptdev), GFP_KERNEL);
354 if (!eptdev)
355 return -ENOMEM;
356
357 dev = &eptdev->dev;
358 eptdev->rpdev = rpdev;
359 eptdev->chinfo = chinfo;
360
361 mutex_init(&eptdev->ept_lock);
362 spin_lock_init(&eptdev->queue_lock);
363 skb_queue_head_init(&eptdev->queue);
364 init_waitqueue_head(&eptdev->readq);
365
366 device_initialize(dev);
367 dev->class = rpmsg_class;
352 struct rpmsg_eptdev *eptdev;
353 struct device *dev;
354 int ret;
355
356 eptdev = kzalloc(sizeof(*eptdev), GFP_KERNEL);
357 if (!eptdev)
358 return -ENOMEM;
359
360 dev = &eptdev->dev;
361 eptdev->rpdev = rpdev;
362 eptdev->chinfo = chinfo;
363
364 mutex_init(&eptdev->ept_lock);
365 spin_lock_init(&eptdev->queue_lock);
366 skb_queue_head_init(&eptdev->queue);
367 init_waitqueue_head(&eptdev->readq);
368
369 device_initialize(dev);
370 dev->class = rpmsg_class;
368 dev->parent = &ctrldev->dev;
371 dev->parent = parent;
369 dev->groups = rpmsg_eptdev_groups;
370 dev_set_drvdata(dev, eptdev);
371
372 cdev_init(&eptdev->cdev, &rpmsg_eptdev_fops);
373 eptdev->cdev.owner = THIS_MODULE;
374
375 ret = ida_simple_get(&rpmsg_minor_ida, 0, RPMSG_DEV_MAX, GFP_KERNEL);
376 if (ret < 0)

--- 20 unchanged lines hidden (view full) ---

397free_minor_ida:
398 ida_simple_remove(&rpmsg_minor_ida, MINOR(dev->devt));
399free_eptdev:
400 put_device(dev);
401 kfree(eptdev);
402
403 return ret;
404}
372 dev->groups = rpmsg_eptdev_groups;
373 dev_set_drvdata(dev, eptdev);
374
375 cdev_init(&eptdev->cdev, &rpmsg_eptdev_fops);
376 eptdev->cdev.owner = THIS_MODULE;
377
378 ret = ida_simple_get(&rpmsg_minor_ida, 0, RPMSG_DEV_MAX, GFP_KERNEL);
379 if (ret < 0)

--- 20 unchanged lines hidden (view full) ---

400free_minor_ida:
401 ida_simple_remove(&rpmsg_minor_ida, MINOR(dev->devt));
402free_eptdev:
403 put_device(dev);
404 kfree(eptdev);
405
406 return ret;
407}
408EXPORT_SYMBOL(rpmsg_chrdev_eptdev_create);
405
406static int rpmsg_ctrldev_open(struct inode *inode, struct file *filp)
407{
408 struct rpmsg_ctrldev *ctrldev = cdev_to_ctrldev(inode->i_cdev);
409
410 get_device(&ctrldev->dev);
411 filp->private_data = ctrldev;
412

--- 23 unchanged lines hidden (view full) ---

436 if (copy_from_user(&eptinfo, argp, sizeof(eptinfo)))
437 return -EFAULT;
438
439 memcpy(chinfo.name, eptinfo.name, RPMSG_NAME_SIZE);
440 chinfo.name[RPMSG_NAME_SIZE-1] = '\0';
441 chinfo.src = eptinfo.src;
442 chinfo.dst = eptinfo.dst;
443
409
410static int rpmsg_ctrldev_open(struct inode *inode, struct file *filp)
411{
412 struct rpmsg_ctrldev *ctrldev = cdev_to_ctrldev(inode->i_cdev);
413
414 get_device(&ctrldev->dev);
415 filp->private_data = ctrldev;
416

--- 23 unchanged lines hidden (view full) ---

440 if (copy_from_user(&eptinfo, argp, sizeof(eptinfo)))
441 return -EFAULT;
442
443 memcpy(chinfo.name, eptinfo.name, RPMSG_NAME_SIZE);
444 chinfo.name[RPMSG_NAME_SIZE-1] = '\0';
445 chinfo.src = eptinfo.src;
446 chinfo.dst = eptinfo.dst;
447
444 return rpmsg_eptdev_create(ctrldev, chinfo);
448 return rpmsg_chrdev_eptdev_create(ctrldev->rpdev, &ctrldev->dev, chinfo);
445};
446
447static const struct file_operations rpmsg_ctrldev_fops = {
448 .owner = THIS_MODULE,
449 .open = rpmsg_ctrldev_open,
450 .release = rpmsg_ctrldev_release,
451 .unlocked_ioctl = rpmsg_ctrldev_ioctl,
452 .compat_ioctl = compat_ptr_ioctl,

--- 62 unchanged lines hidden (view full) ---

515}
516
517static void rpmsg_chrdev_remove(struct rpmsg_device *rpdev)
518{
519 struct rpmsg_ctrldev *ctrldev = dev_get_drvdata(&rpdev->dev);
520 int ret;
521
522 /* Destroy all endpoints */
449};
450
451static const struct file_operations rpmsg_ctrldev_fops = {
452 .owner = THIS_MODULE,
453 .open = rpmsg_ctrldev_open,
454 .release = rpmsg_ctrldev_release,
455 .unlocked_ioctl = rpmsg_ctrldev_ioctl,
456 .compat_ioctl = compat_ptr_ioctl,

--- 62 unchanged lines hidden (view full) ---

519}
520
521static void rpmsg_chrdev_remove(struct rpmsg_device *rpdev)
522{
523 struct rpmsg_ctrldev *ctrldev = dev_get_drvdata(&rpdev->dev);
524 int ret;
525
526 /* Destroy all endpoints */
523 ret = device_for_each_child(&ctrldev->dev, NULL, rpmsg_eptdev_destroy);
527 ret = device_for_each_child(&ctrldev->dev, NULL, rpmsg_chrdev_eptdev_destroy);
524 if (ret)
525 dev_warn(&rpdev->dev, "failed to nuke endpoints: %d\n", ret);
526
527 cdev_device_del(&ctrldev->cdev, &ctrldev->dev);
528 put_device(&ctrldev->dev);
529}
530
531static struct rpmsg_driver rpmsg_chrdev_driver = {

--- 45 unchanged lines hidden ---
528 if (ret)
529 dev_warn(&rpdev->dev, "failed to nuke endpoints: %d\n", ret);
530
531 cdev_device_del(&ctrldev->cdev, &ctrldev->dev);
532 put_device(&ctrldev->dev);
533}
534
535static struct rpmsg_driver rpmsg_chrdev_driver = {

--- 45 unchanged lines hidden ---