aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/media-device.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/media-device.c')
-rw-r--r--drivers/media/media-device.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index bcd3985d415a..a36509a1df09 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -25,6 +25,7 @@
25 25
26#include <media/media-device.h> 26#include <media/media-device.h>
27#include <media/media-devnode.h> 27#include <media/media-devnode.h>
28#include <media/media-entity.h>
28 29
29static const struct media_file_operations media_device_fops = { 30static const struct media_file_operations media_device_fops = {
30 .owner = THIS_MODULE, 31 .owner = THIS_MODULE,
@@ -69,6 +70,10 @@ int __must_check media_device_register(struct media_device *mdev)
69 if (WARN_ON(mdev->dev == NULL || mdev->model[0] == 0)) 70 if (WARN_ON(mdev->dev == NULL || mdev->model[0] == 0))
70 return -EINVAL; 71 return -EINVAL;
71 72
73 mdev->entity_id = 1;
74 INIT_LIST_HEAD(&mdev->entities);
75 spin_lock_init(&mdev->lock);
76
72 /* Register the device node. */ 77 /* Register the device node. */
73 mdev->devnode.fops = &media_device_fops; 78 mdev->devnode.fops = &media_device_fops;
74 mdev->devnode.parent = mdev->dev; 79 mdev->devnode.parent = mdev->dev;
@@ -94,7 +99,58 @@ EXPORT_SYMBOL_GPL(media_device_register);
94 */ 99 */
95void media_device_unregister(struct media_device *mdev) 100void media_device_unregister(struct media_device *mdev)
96{ 101{
102 struct media_entity *entity;
103 struct media_entity *next;
104
105 list_for_each_entry_safe(entity, next, &mdev->entities, list)
106 media_device_unregister_entity(entity);
107
97 device_remove_file(&mdev->devnode.dev, &dev_attr_model); 108 device_remove_file(&mdev->devnode.dev, &dev_attr_model);
98 media_devnode_unregister(&mdev->devnode); 109 media_devnode_unregister(&mdev->devnode);
99} 110}
100EXPORT_SYMBOL_GPL(media_device_unregister); 111EXPORT_SYMBOL_GPL(media_device_unregister);
112
113/**
114 * media_device_register_entity - Register an entity with a media device
115 * @mdev: The media device
116 * @entity: The entity
117 */
118int __must_check media_device_register_entity(struct media_device *mdev,
119 struct media_entity *entity)
120{
121 /* Warn if we apparently re-register an entity */
122 WARN_ON(entity->parent != NULL);
123 entity->parent = mdev;
124
125 spin_lock(&mdev->lock);
126 if (entity->id == 0)
127 entity->id = mdev->entity_id++;
128 else
129 mdev->entity_id = max(entity->id + 1, mdev->entity_id);
130 list_add_tail(&entity->list, &mdev->entities);
131 spin_unlock(&mdev->lock);
132
133 return 0;
134}
135EXPORT_SYMBOL_GPL(media_device_register_entity);
136
137/**
138 * media_device_unregister_entity - Unregister an entity
139 * @entity: The entity
140 *
141 * If the entity has never been registered this function will return
142 * immediately.
143 */
144void media_device_unregister_entity(struct media_entity *entity)
145{
146 struct media_device *mdev = entity->parent;
147
148 if (mdev == NULL)
149 return;
150
151 spin_lock(&mdev->lock);
152 list_del(&entity->list);
153 spin_unlock(&mdev->lock);
154 entity->parent = NULL;
155}
156EXPORT_SYMBOL_GPL(media_device_unregister_entity);