media-device.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*
  2. * Media device
  3. *
  4. * Copyright (C) 2010 Nokia Corporation
  5. *
  6. * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
  7. * Sakari Ailus <sakari.ailus@iki.fi>
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2 as
  11. * published by the Free Software Foundation.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21. */
  22. #include <linux/types.h>
  23. #include <linux/ioctl.h>
  24. #include <media/media-device.h>
  25. #include <media/media-devnode.h>
  26. #include <media/media-entity.h>
  27. static const struct media_file_operations media_device_fops = {
  28. .owner = THIS_MODULE,
  29. };
  30. /* -----------------------------------------------------------------------------
  31. * sysfs
  32. */
  33. static ssize_t show_model(struct device *cd,
  34. struct device_attribute *attr, char *buf)
  35. {
  36. struct media_device *mdev = to_media_device(to_media_devnode(cd));
  37. return sprintf(buf, "%.*s\n", (int)sizeof(mdev->model), mdev->model);
  38. }
  39. static DEVICE_ATTR(model, S_IRUGO, show_model, NULL);
  40. /* -----------------------------------------------------------------------------
  41. * Registration/unregistration
  42. */
  43. static void media_device_release(struct media_devnode *mdev)
  44. {
  45. }
  46. /**
  47. * media_device_register - register a media device
  48. * @mdev: The media device
  49. *
  50. * The caller is responsible for initializing the media device before
  51. * registration. The following fields must be set:
  52. *
  53. * - dev must point to the parent device
  54. * - model must be filled with the device model name
  55. */
  56. int __must_check media_device_register(struct media_device *mdev)
  57. {
  58. int ret;
  59. if (WARN_ON(mdev->dev == NULL || mdev->model[0] == 0))
  60. return -EINVAL;
  61. mdev->entity_id = 1;
  62. INIT_LIST_HEAD(&mdev->entities);
  63. spin_lock_init(&mdev->lock);
  64. mutex_init(&mdev->graph_mutex);
  65. /* Register the device node. */
  66. mdev->devnode.fops = &media_device_fops;
  67. mdev->devnode.parent = mdev->dev;
  68. mdev->devnode.release = media_device_release;
  69. ret = media_devnode_register(&mdev->devnode);
  70. if (ret < 0)
  71. return ret;
  72. ret = device_create_file(&mdev->devnode.dev, &dev_attr_model);
  73. if (ret < 0) {
  74. media_devnode_unregister(&mdev->devnode);
  75. return ret;
  76. }
  77. return 0;
  78. }
  79. EXPORT_SYMBOL_GPL(media_device_register);
  80. /**
  81. * media_device_unregister - unregister a media device
  82. * @mdev: The media device
  83. *
  84. */
  85. void media_device_unregister(struct media_device *mdev)
  86. {
  87. struct media_entity *entity;
  88. struct media_entity *next;
  89. list_for_each_entry_safe(entity, next, &mdev->entities, list)
  90. media_device_unregister_entity(entity);
  91. device_remove_file(&mdev->devnode.dev, &dev_attr_model);
  92. media_devnode_unregister(&mdev->devnode);
  93. }
  94. EXPORT_SYMBOL_GPL(media_device_unregister);
  95. /**
  96. * media_device_register_entity - Register an entity with a media device
  97. * @mdev: The media device
  98. * @entity: The entity
  99. */
  100. int __must_check media_device_register_entity(struct media_device *mdev,
  101. struct media_entity *entity)
  102. {
  103. /* Warn if we apparently re-register an entity */
  104. WARN_ON(entity->parent != NULL);
  105. entity->parent = mdev;
  106. spin_lock(&mdev->lock);
  107. if (entity->id == 0)
  108. entity->id = mdev->entity_id++;
  109. else
  110. mdev->entity_id = max(entity->id + 1, mdev->entity_id);
  111. list_add_tail(&entity->list, &mdev->entities);
  112. spin_unlock(&mdev->lock);
  113. return 0;
  114. }
  115. EXPORT_SYMBOL_GPL(media_device_register_entity);
  116. /**
  117. * media_device_unregister_entity - Unregister an entity
  118. * @entity: The entity
  119. *
  120. * If the entity has never been registered this function will return
  121. * immediately.
  122. */
  123. void media_device_unregister_entity(struct media_entity *entity)
  124. {
  125. struct media_device *mdev = entity->parent;
  126. if (mdev == NULL)
  127. return;
  128. spin_lock(&mdev->lock);
  129. list_del(&entity->list);
  130. spin_unlock(&mdev->lock);
  131. entity->parent = NULL;
  132. }
  133. EXPORT_SYMBOL_GPL(media_device_unregister_entity);