|
33 | 33 |
|
34 | 34 | static dev_t rpmsg_major; |
35 | 35 |
|
36 | | -static DEFINE_IDA(rpmsg_ctrl_ida); |
37 | 36 | static DEFINE_IDA(rpmsg_ept_ida); |
38 | 37 | static DEFINE_IDA(rpmsg_minor_ida); |
39 | 38 |
|
40 | 39 | #define dev_to_eptdev(dev) container_of(dev, struct rpmsg_eptdev, dev) |
41 | 40 | #define cdev_to_eptdev(i_cdev) container_of(i_cdev, struct rpmsg_eptdev, cdev) |
42 | 41 |
|
43 | | -#define dev_to_ctrldev(dev) container_of(dev, struct rpmsg_ctrldev, dev) |
44 | | -#define cdev_to_ctrldev(i_cdev) container_of(i_cdev, struct rpmsg_ctrldev, cdev) |
45 | | - |
46 | | -/** |
47 | | - * struct rpmsg_ctrldev - control device for instantiating endpoint devices |
48 | | - * @rpdev: underlaying rpmsg device |
49 | | - * @cdev: cdev for the ctrl device |
50 | | - * @dev: device for the ctrl device |
51 | | - */ |
52 | | -struct rpmsg_ctrldev { |
53 | | - struct rpmsg_device *rpdev; |
54 | | - struct cdev cdev; |
55 | | - struct device dev; |
56 | | -}; |
57 | | - |
58 | 42 | /** |
59 | 43 | * struct rpmsg_eptdev - endpoint device context |
60 | 44 | * @dev: endpoint device |
@@ -407,162 +391,22 @@ int rpmsg_chrdev_eptdev_create(struct rpmsg_device *rpdev, struct device *parent |
407 | 391 | } |
408 | 392 | EXPORT_SYMBOL(rpmsg_chrdev_eptdev_create); |
409 | 393 |
|
410 | | -static 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 | | - |
417 | | - return 0; |
418 | | -} |
419 | | - |
420 | | -static int rpmsg_ctrldev_release(struct inode *inode, struct file *filp) |
421 | | -{ |
422 | | - struct rpmsg_ctrldev *ctrldev = cdev_to_ctrldev(inode->i_cdev); |
423 | | - |
424 | | - put_device(&ctrldev->dev); |
425 | | - |
426 | | - return 0; |
427 | | -} |
428 | | - |
429 | | -static long rpmsg_ctrldev_ioctl(struct file *fp, unsigned int cmd, |
430 | | - unsigned long arg) |
431 | | -{ |
432 | | - struct rpmsg_ctrldev *ctrldev = fp->private_data; |
433 | | - void __user *argp = (void __user *)arg; |
434 | | - struct rpmsg_endpoint_info eptinfo; |
435 | | - struct rpmsg_channel_info chinfo; |
436 | | - |
437 | | - if (cmd != RPMSG_CREATE_EPT_IOCTL) |
438 | | - return -EINVAL; |
439 | | - |
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 | | - |
448 | | - return rpmsg_chrdev_eptdev_create(ctrldev->rpdev, &ctrldev->dev, chinfo); |
449 | | -}; |
450 | | - |
451 | | -static 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, |
457 | | -}; |
458 | | - |
459 | | -static void rpmsg_ctrldev_release_device(struct device *dev) |
460 | | -{ |
461 | | - struct rpmsg_ctrldev *ctrldev = dev_to_ctrldev(dev); |
462 | | - |
463 | | - ida_simple_remove(&rpmsg_ctrl_ida, dev->id); |
464 | | - ida_simple_remove(&rpmsg_minor_ida, MINOR(dev->devt)); |
465 | | - kfree(ctrldev); |
466 | | -} |
467 | | - |
468 | | -static int rpmsg_chrdev_probe(struct rpmsg_device *rpdev) |
469 | | -{ |
470 | | - struct rpmsg_ctrldev *ctrldev; |
471 | | - struct device *dev; |
472 | | - int ret; |
473 | | - |
474 | | - ctrldev = kzalloc(sizeof(*ctrldev), GFP_KERNEL); |
475 | | - if (!ctrldev) |
476 | | - return -ENOMEM; |
477 | | - |
478 | | - ctrldev->rpdev = rpdev; |
479 | | - |
480 | | - dev = &ctrldev->dev; |
481 | | - device_initialize(dev); |
482 | | - dev->parent = &rpdev->dev; |
483 | | - dev->class = rpmsg_class; |
484 | | - |
485 | | - cdev_init(&ctrldev->cdev, &rpmsg_ctrldev_fops); |
486 | | - ctrldev->cdev.owner = THIS_MODULE; |
487 | | - |
488 | | - ret = ida_simple_get(&rpmsg_minor_ida, 0, RPMSG_DEV_MAX, GFP_KERNEL); |
489 | | - if (ret < 0) |
490 | | - goto free_ctrldev; |
491 | | - dev->devt = MKDEV(MAJOR(rpmsg_major), ret); |
492 | | - |
493 | | - ret = ida_simple_get(&rpmsg_ctrl_ida, 0, 0, GFP_KERNEL); |
494 | | - if (ret < 0) |
495 | | - goto free_minor_ida; |
496 | | - dev->id = ret; |
497 | | - dev_set_name(&ctrldev->dev, "rpmsg_ctrl%d", ret); |
498 | | - |
499 | | - ret = cdev_device_add(&ctrldev->cdev, &ctrldev->dev); |
500 | | - if (ret) |
501 | | - goto free_ctrl_ida; |
502 | | - |
503 | | - /* We can now rely on the release function for cleanup */ |
504 | | - dev->release = rpmsg_ctrldev_release_device; |
505 | | - |
506 | | - dev_set_drvdata(&rpdev->dev, ctrldev); |
507 | | - |
508 | | - return ret; |
509 | | - |
510 | | -free_ctrl_ida: |
511 | | - ida_simple_remove(&rpmsg_ctrl_ida, dev->id); |
512 | | -free_minor_ida: |
513 | | - ida_simple_remove(&rpmsg_minor_ida, MINOR(dev->devt)); |
514 | | -free_ctrldev: |
515 | | - put_device(dev); |
516 | | - kfree(ctrldev); |
517 | | - |
518 | | - return ret; |
519 | | -} |
520 | | - |
521 | | -static 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 */ |
527 | | - ret = device_for_each_child(&ctrldev->dev, NULL, rpmsg_chrdev_eptdev_destroy); |
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 | | - |
535 | | -static struct rpmsg_driver rpmsg_chrdev_driver = { |
536 | | - .probe = rpmsg_chrdev_probe, |
537 | | - .remove = rpmsg_chrdev_remove, |
538 | | - .drv = { |
539 | | - .name = "rpmsg_chrdev", |
540 | | - }, |
541 | | -}; |
542 | | - |
543 | 394 | static int rpmsg_chrdev_init(void) |
544 | 395 | { |
545 | 396 | int ret; |
546 | 397 |
|
547 | | - ret = alloc_chrdev_region(&rpmsg_major, 0, RPMSG_DEV_MAX, "rpmsg"); |
| 398 | + ret = alloc_chrdev_region(&rpmsg_major, 0, RPMSG_DEV_MAX, "rpmsg_char"); |
548 | 399 | if (ret < 0) { |
549 | 400 | pr_err("failed to allocate char dev region\n"); |
550 | 401 | return ret; |
551 | 402 | } |
552 | 403 |
|
553 | | - ret = register_rpmsg_driver(&rpmsg_chrdev_driver); |
554 | | - if (ret < 0) { |
555 | | - pr_err("failed to register rpmsg driver\n"); |
556 | | - unregister_chrdev_region(rpmsg_major, RPMSG_DEV_MAX); |
557 | | - } |
558 | | - |
559 | | - return ret; |
| 404 | + return 0; |
560 | 405 | } |
561 | 406 | postcore_initcall(rpmsg_chrdev_init); |
562 | 407 |
|
563 | 408 | static void rpmsg_chrdev_exit(void) |
564 | 409 | { |
565 | | - unregister_rpmsg_driver(&rpmsg_chrdev_driver); |
566 | 410 | unregister_chrdev_region(rpmsg_major, RPMSG_DEV_MAX); |
567 | 411 | } |
568 | 412 | module_exit(rpmsg_chrdev_exit); |
|
0 commit comments