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