mac80211: correct legacy rates check in ieee80211_calc_rx_airtime
[platform/kernel/linux-rpi.git] / include / media / media-request.h
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Media device request objects
4  *
5  * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
6  * Copyright (C) 2018 Intel Corporation
7  *
8  * Author: Hans Verkuil <hans.verkuil@cisco.com>
9  * Author: Sakari Ailus <sakari.ailus@linux.intel.com>
10  */
11
12 #ifndef MEDIA_REQUEST_H
13 #define MEDIA_REQUEST_H
14
15 #include <linux/list.h>
16 #include <linux/slab.h>
17 #include <linux/spinlock.h>
18 #include <linux/refcount.h>
19
20 #include <media/media-device.h>
21
22 /**
23  * enum media_request_state - media request state
24  *
25  * @MEDIA_REQUEST_STATE_IDLE:           Idle
26  * @MEDIA_REQUEST_STATE_VALIDATING:     Validating the request, no state changes
27  *                                      allowed
28  * @MEDIA_REQUEST_STATE_QUEUED:         Queued
29  * @MEDIA_REQUEST_STATE_COMPLETE:       Completed, the request is done
30  * @MEDIA_REQUEST_STATE_CLEANING:       Cleaning, the request is being re-inited
31  * @MEDIA_REQUEST_STATE_UPDATING:       The request is being updated, i.e.
32  *                                      request objects are being added,
33  *                                      modified or removed
34  * @NR_OF_MEDIA_REQUEST_STATE:          The number of media request states, used
35  *                                      internally for sanity check purposes
36  */
37 enum media_request_state {
38         MEDIA_REQUEST_STATE_IDLE,
39         MEDIA_REQUEST_STATE_VALIDATING,
40         MEDIA_REQUEST_STATE_QUEUED,
41         MEDIA_REQUEST_STATE_COMPLETE,
42         MEDIA_REQUEST_STATE_CLEANING,
43         MEDIA_REQUEST_STATE_UPDATING,
44         NR_OF_MEDIA_REQUEST_STATE,
45 };
46
47 struct media_request_object;
48
49 /**
50  * struct media_request - Media device request
51  * @mdev: Media device this request belongs to
52  * @kref: Reference count
53  * @debug_str: Prefix for debug messages (process name:fd)
54  * @state: The state of the request
55  * @updating_count: count the number of request updates that are in progress
56  * @access_count: count the number of request accesses that are in progress
57  * @objects: List of @struct media_request_object request objects
58  * @num_incomplete_objects: The number of incomplete objects in the request
59  * @poll_wait: Wait queue for poll
60  * @lock: Serializes access to this struct
61  */
62 struct media_request {
63         struct media_device *mdev;
64         struct kref kref;
65         char debug_str[TASK_COMM_LEN + 11];
66         enum media_request_state state;
67         unsigned int updating_count;
68         unsigned int access_count;
69         struct list_head objects;
70         unsigned int num_incomplete_objects;
71         wait_queue_head_t poll_wait;
72         spinlock_t lock;
73 };
74
75 #ifdef CONFIG_MEDIA_CONTROLLER
76
77 /**
78  * media_request_lock_for_access - Lock the request to access its objects
79  *
80  * @req: The media request
81  *
82  * Use before accessing a completed request. A reference to the request must
83  * be held during the access. This usually takes place automatically through
84  * a file handle. Use @media_request_unlock_for_access when done.
85  */
86 static inline int __must_check
87 media_request_lock_for_access(struct media_request *req)
88 {
89         unsigned long flags;
90         int ret = -EBUSY;
91
92         spin_lock_irqsave(&req->lock, flags);
93         if (req->state == MEDIA_REQUEST_STATE_COMPLETE) {
94                 req->access_count++;
95                 ret = 0;
96         }
97         spin_unlock_irqrestore(&req->lock, flags);
98
99         return ret;
100 }
101
102 /**
103  * media_request_unlock_for_access - Unlock a request previously locked for
104  *                                   access
105  *
106  * @req: The media request
107  *
108  * Unlock a request that has previously been locked using
109  * @media_request_lock_for_access.
110  */
111 static inline void media_request_unlock_for_access(struct media_request *req)
112 {
113         unsigned long flags;
114
115         spin_lock_irqsave(&req->lock, flags);
116         if (!WARN_ON(!req->access_count))
117                 req->access_count--;
118         spin_unlock_irqrestore(&req->lock, flags);
119 }
120
121 /**
122  * media_request_lock_for_update - Lock the request for updating its objects
123  *
124  * @req: The media request
125  *
126  * Use before updating a request, i.e. adding, modifying or removing a request
127  * object in it. A reference to the request must be held during the update. This
128  * usually takes place automatically through a file handle. Use
129  * @media_request_unlock_for_update when done.
130  */
131 static inline int __must_check
132 media_request_lock_for_update(struct media_request *req)
133 {
134         unsigned long flags;
135         int ret = 0;
136
137         spin_lock_irqsave(&req->lock, flags);
138         if (req->state == MEDIA_REQUEST_STATE_IDLE ||
139             req->state == MEDIA_REQUEST_STATE_UPDATING) {
140                 req->state = MEDIA_REQUEST_STATE_UPDATING;
141                 req->updating_count++;
142         } else {
143                 ret = -EBUSY;
144         }
145         spin_unlock_irqrestore(&req->lock, flags);
146
147         return ret;
148 }
149
150 /**
151  * media_request_unlock_for_update - Unlock a request previously locked for
152  *                                   update
153  *
154  * @req: The media request
155  *
156  * Unlock a request that has previously been locked using
157  * @media_request_lock_for_update.
158  */
159 static inline void media_request_unlock_for_update(struct media_request *req)
160 {
161         unsigned long flags;
162
163         spin_lock_irqsave(&req->lock, flags);
164         WARN_ON(req->updating_count <= 0);
165         if (!--req->updating_count)
166                 req->state = MEDIA_REQUEST_STATE_IDLE;
167         spin_unlock_irqrestore(&req->lock, flags);
168 }
169
170 /**
171  * media_request_get - Get the media request
172  *
173  * @req: The media request
174  *
175  * Get the media request.
176  */
177 static inline void media_request_get(struct media_request *req)
178 {
179         kref_get(&req->kref);
180 }
181
182 /**
183  * media_request_put - Put the media request
184  *
185  * @req: The media request
186  *
187  * Put the media request. The media request will be released
188  * when the refcount reaches 0.
189  */
190 void media_request_put(struct media_request *req);
191
192 void media_request_pin(struct media_request *req);
193
194 void media_request_unpin(struct media_request *req);
195
196 /**
197  * media_request_get_by_fd - Get a media request by fd
198  *
199  * @mdev: Media device this request belongs to
200  * @request_fd: The file descriptor of the request
201  *
202  * Get the request represented by @request_fd that is owned
203  * by the media device.
204  *
205  * Return a -EBADR error pointer if requests are not supported
206  * by this driver. Return -EINVAL if the request was not found.
207  * Return the pointer to the request if found: the caller will
208  * have to call @media_request_put when it finished using the
209  * request.
210  */
211 struct media_request *
212 media_request_get_by_fd(struct media_device *mdev, int request_fd);
213
214 /**
215  * media_request_alloc - Allocate the media request
216  *
217  * @mdev: Media device this request belongs to
218  * @alloc_fd: Store the request's file descriptor in this int
219  *
220  * Allocated the media request and put the fd in @alloc_fd.
221  */
222 int media_request_alloc(struct media_device *mdev,
223                         int *alloc_fd);
224
225 #else
226
227 static inline void media_request_get(struct media_request *req)
228 {
229 }
230
231 static inline void media_request_put(struct media_request *req)
232 {
233 }
234
235 static inline void media_request_pin(struct media_request *req)
236 {
237 }
238
239 static inline void media_request_unpin(struct media_request *req)
240 {
241 }
242
243 static inline struct media_request *
244 media_request_get_by_fd(struct media_device *mdev, int request_fd)
245 {
246         return ERR_PTR(-EBADR);
247 }
248
249 #endif
250
251 /**
252  * struct media_request_object_ops - Media request object operations
253  * @prepare: Validate and prepare the request object, optional.
254  * @unprepare: Unprepare the request object, optional.
255  * @queue: Queue the request object, optional.
256  * @unbind: Unbind the request object, optional.
257  * @release: Release the request object, required.
258  */
259 struct media_request_object_ops {
260         int (*prepare)(struct media_request_object *object);
261         void (*unprepare)(struct media_request_object *object);
262         void (*queue)(struct media_request_object *object);
263         void (*unbind)(struct media_request_object *object);
264         void (*release)(struct media_request_object *object);
265 };
266
267 /**
268  * struct media_request_object - An opaque object that belongs to a media
269  *                               request
270  *
271  * @ops: object's operations
272  * @priv: object's priv pointer
273  * @req: the request this object belongs to (can be NULL)
274  * @list: List entry of the object for @struct media_request
275  * @kref: Reference count of the object, acquire before releasing req->lock
276  * @completed: If true, then this object was completed.
277  *
278  * An object related to the request. This struct is always embedded in
279  * another struct that contains the actual data for this request object.
280  */
281 struct media_request_object {
282         const struct media_request_object_ops *ops;
283         void *priv;
284         struct media_request *req;
285         struct list_head list;
286         struct kref kref;
287         bool completed;
288 };
289
290 #ifdef CONFIG_MEDIA_CONTROLLER
291
292 /**
293  * media_request_object_get - Get a media request object
294  *
295  * @obj: The object
296  *
297  * Get a media request object.
298  */
299 static inline void media_request_object_get(struct media_request_object *obj)
300 {
301         kref_get(&obj->kref);
302 }
303
304 /**
305  * media_request_object_put - Put a media request object
306  *
307  * @obj: The object
308  *
309  * Put a media request object. Once all references are gone, the
310  * object's memory is released.
311  */
312 void media_request_object_put(struct media_request_object *obj);
313
314 /**
315  * media_request_object_find - Find an object in a request
316  *
317  * @req: The media request
318  * @ops: Find an object with this ops value
319  * @priv: Find an object with this priv value
320  *
321  * Both @ops and @priv must be non-NULL.
322  *
323  * Returns the object pointer or NULL if not found. The caller must
324  * call media_request_object_put() once it finished using the object.
325  *
326  * Since this function needs to walk the list of objects it takes
327  * the @req->lock spin lock to make this safe.
328  */
329 struct media_request_object *
330 media_request_object_find(struct media_request *req,
331                           const struct media_request_object_ops *ops,
332                           void *priv);
333
334 /**
335  * media_request_object_init - Initialise a media request object
336  *
337  * @obj: The object
338  *
339  * Initialise a media request object. The object will be released using the
340  * release callback of the ops once it has no references (this function
341  * initialises references to one).
342  */
343 void media_request_object_init(struct media_request_object *obj);
344
345 /**
346  * media_request_object_bind - Bind a media request object to a request
347  *
348  * @req: The media request
349  * @ops: The object ops for this object
350  * @priv: A driver-specific priv pointer associated with this object
351  * @is_buffer: Set to true if the object a buffer object.
352  * @obj: The object
353  *
354  * Bind this object to the request and set the ops and priv values of
355  * the object so it can be found later with media_request_object_find().
356  *
357  * Every bound object must be unbound or completed by the kernel at some
358  * point in time, otherwise the request will never complete. When the
359  * request is released all completed objects will be unbound by the
360  * request core code.
361  *
362  * Buffer objects will be added to the end of the request's object
363  * list, non-buffer objects will be added to the front of the list.
364  * This ensures that all buffer objects are at the end of the list
365  * and that all non-buffer objects that they depend on are processed
366  * first.
367  */
368 int media_request_object_bind(struct media_request *req,
369                               const struct media_request_object_ops *ops,
370                               void *priv, bool is_buffer,
371                               struct media_request_object *obj);
372
373 /**
374  * media_request_object_unbind - Unbind a media request object
375  *
376  * @obj: The object
377  *
378  * Unbind the media request object from the request.
379  */
380 void media_request_object_unbind(struct media_request_object *obj);
381
382 /**
383  * media_request_object_complete - Mark the media request object as complete
384  *
385  * @obj: The object
386  *
387  * Mark the media request object as complete. Only bound objects can
388  * be completed.
389  */
390 void media_request_object_complete(struct media_request_object *obj);
391
392 #else
393
394 static inline int __must_check
395 media_request_lock_for_access(struct media_request *req)
396 {
397         return -EINVAL;
398 }
399
400 static inline void media_request_unlock_for_access(struct media_request *req)
401 {
402 }
403
404 static inline int __must_check
405 media_request_lock_for_update(struct media_request *req)
406 {
407         return -EINVAL;
408 }
409
410 static inline void media_request_unlock_for_update(struct media_request *req)
411 {
412 }
413
414 static inline void media_request_object_get(struct media_request_object *obj)
415 {
416 }
417
418 static inline void media_request_object_put(struct media_request_object *obj)
419 {
420 }
421
422 static inline struct media_request_object *
423 media_request_object_find(struct media_request *req,
424                           const struct media_request_object_ops *ops,
425                           void *priv)
426 {
427         return NULL;
428 }
429
430 static inline void media_request_object_init(struct media_request_object *obj)
431 {
432         obj->ops = NULL;
433         obj->req = NULL;
434 }
435
436 static inline int media_request_object_bind(struct media_request *req,
437                                const struct media_request_object_ops *ops,
438                                void *priv, bool is_buffer,
439                                struct media_request_object *obj)
440 {
441         return 0;
442 }
443
444 static inline void media_request_object_unbind(struct media_request_object *obj)
445 {
446 }
447
448 static inline void media_request_object_complete(struct media_request_object *obj)
449 {
450 }
451
452 #endif
453
454 #endif