]> git.baikalelectronics.ru Git - kernel.git/commitdiff
media: media-request: add media_request_object_find
authorHans Verkuil <hans.verkuil@cisco.com>
Mon, 21 May 2018 08:54:29 +0000 (04:54 -0400)
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Fri, 31 Aug 2018 15:07:08 +0000 (11:07 -0400)
Add media_request_object_find to find a request object inside a
request based on ops and priv values.

Objects of the same type (vb2 buffer, control handler) will have
the same ops value. And objects that refer to the same 'parent'
object (e.g. the v4l2_ctrl_handler that has the current driver
state) will have the same priv value.

The caller has to call media_request_object_put() for the returned
object since this function increments the refcount.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
drivers/media/media-request.c
include/media/media-request.h

index 8d3c7360c8f3aab39a053d9c8736ae7ac02b441a..4b0ce8fde7c9ae4fe0a3d48f8579c50da1004603 100644 (file)
@@ -342,6 +342,31 @@ static void media_request_object_release(struct kref *kref)
        obj->ops->release(obj);
 }
 
+struct media_request_object *
+media_request_object_find(struct media_request *req,
+                         const struct media_request_object_ops *ops,
+                         void *priv)
+{
+       struct media_request_object *obj;
+       struct media_request_object *found = NULL;
+       unsigned long flags;
+
+       if (WARN_ON(!ops || !priv))
+               return NULL;
+
+       spin_lock_irqsave(&req->lock, flags);
+       list_for_each_entry(obj, &req->objects, list) {
+               if (obj->ops == ops && obj->priv == priv) {
+                       media_request_object_get(obj);
+                       found = obj;
+                       break;
+               }
+       }
+       spin_unlock_irqrestore(&req->lock, flags);
+       return found;
+}
+EXPORT_SYMBOL_GPL(media_request_object_find);
+
 void media_request_object_put(struct media_request_object *obj)
 {
        kref_put(&obj->kref, media_request_object_release);
index 1c3e5d804d07695d00eec2489883da0263f7d8e8..ac02019c1d77376414e1fa5e7c576526568a41b8 100644 (file)
@@ -253,6 +253,26 @@ static inline void media_request_object_get(struct media_request_object *obj)
  */
 void media_request_object_put(struct media_request_object *obj);
 
+/**
+ * media_request_object_find - Find an object in a request
+ *
+ * @req: The media request
+ * @ops: Find an object with this ops value
+ * @priv: Find an object with this priv value
+ *
+ * Both @ops and @priv must be non-NULL.
+ *
+ * Returns the object pointer or NULL if not found. The caller must
+ * call media_request_object_put() once it finished using the object.
+ *
+ * Since this function needs to walk the list of objects it takes
+ * the @req->lock spin lock to make this safe.
+ */
+struct media_request_object *
+media_request_object_find(struct media_request *req,
+                         const struct media_request_object_ops *ops,
+                         void *priv);
+
 /**
  * media_request_object_init - Initialise a media request object
  *
@@ -331,6 +351,14 @@ static inline void media_request_object_put(struct media_request_object *obj)
 {
 }
 
+static inline struct media_request_object *
+media_request_object_find(struct media_request *req,
+                         const struct media_request_object_ops *ops,
+                         void *priv)
+{
+       return NULL;
+}
+
 static inline void media_request_object_init(struct media_request_object *obj)
 {
        obj->ops = NULL;