MAJOR=4
MINOR=19
DEVNAME=tty19
  +   	ˆl–Ü4ý( ©³( 	Å€fàB¦-ÿÀ„„Ó_†I|¥�+ÄÃ /Õ    	// SPDX-License-Identifier: GPL-2.0
/*
 * Media device request objects
 *
 * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
 * Copyright (C) 2018 Intel Corporation
 *
 * Author: Hans Verkuil <hans.verkuil@cisco.com>
 * Author: Sakari Ailus <sakari.ailus@linux.intel.com>
 */

#ifndef MEDIA_REQUEST_H
#define MEDIA_REQUEST_H

#include <linux/list.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/refcount.h>

#include <media/media-device.h>

/**
 * enum media_request_state - media request state
 *
 * @MEDIA_REQUEST_STATE_IDLE:		Idle
 * @MEDIA_REQUEST_STATE_VALIDATING:	Validating the request, no state changes
 *					allowed
 * @MEDIA_REQUEST_STATE_QUEUED:		Queued
 * @MEDIA_REQUEST_STATE_COMPLETE:	Completed, the request is done
 * @MEDIA_REQUEST_STATE_CLEANING:	Cleaning, the request is being re-inited
 * @MEDIA_REQUEST_STATE_UPDATING:	The request is being updated, i.e.
 *					request objects are being added,
 *					modified or removed
 * @NR_OF_MEDIA_REQUEST_STATE:		The number of media request states, used
 *					internally for sanity check purposes
 */
enum media_request_state {
	MEDIA_REQUEST_STATE_IDLE,
	MEDIA_REQUEST_STATE_VALIDATING,
	MEDIA_REQUEST_STATE_QUEUED,
	MEDIA_REQUEST_STATE_COMPLETE,
	MEDIA_REQUEST_STATE_CLEANING,
	MEDIA_REQUEST_STATE_UPDATING,
	NR_OF_MEDIA_REQUEST_STATE,
};

struct media_request_object;

/**
 * struct media_request - Media device request
 * @mdev: Media device this request belongs to
 * @kref: Reference count
 * @debug_str: Prefix for debug messages (process name:fd)
 * @state: The state of the request
 * @updating_count: count the number of request updates that are in progress
 * @access_count: count the number of request accesses that are in progress
 * @objects: List of @struct media_request_object request objects
 * @num_incomplete_objects: The number of incomplete objects in the request
 * @poll_wait: Wait queue for poll
 * @lock: Serializes access to this struct
 */
struct media_request {
	struct media_device *mdev;
	struct kref kref;
	char debug_str[TASK_COMM_LEN + 11];
	enum media_request_state state;
	unsigned int updating_count;
	unsigned int access_count;
	struct list_head objects;
	unsigned int num_incomplete_objects;
	wait_queue_head_t poll_wait;
	spinlock_t lock;
};

#ifdef CONFIG_MEDIA_CONTROLLER

/**
 * media_request_lock_for_access - Lock the request to access its objects
 *
 * @req: The media request
 *
 * Use before accessing a completed request. A reference to the request must
 * be held during the access. This usually takes place automatically through
 * a file handle. Use @media_request_unlock_for_access when done.
 */
static inline int __must_check
media_request_lock_for_access(struct media_request *req)
{
	unsigned long flags;
	int ret = -EBUSY;

	spin_lock_irqsave(&req->lock, flags);
	if (req->state == MEDIA_REQUEST_STATE_COMPLETE) {
		req->access_count++;
		ret = 0;
	}
	spin_unlock_irqrestore(&req->lock, flags);

	return ret;
}

/**
 * media_request_unlock_for_access - Unlock a request previously locked for
 *				     access
 *
 * @req: The media request
 *
 * Unlock a request that has previously been locked using
 * @media_request_lock_for_access.
 */
static inline void media_request_unlock_for_access(struct media_request *req)
{
	unsigned long flags;

	spin_lock_irqsave(&req->lock, flags);
	if (!WARN_ON(!req->access_count))
		req->access_count--;
	spin_unlock_irqrestore(&req->lock, flags);
}

/**
 * media_request_lock_for_update - Lock the request for updating its objects
 *
 * @req: The media request
 *
 * Use before updating a request, i.e. adding, modifying or removing a request
 * object in it. A reference to the request must be held during the update. This
 * usually takes place automatically through a file handle. Use
 * @media_request_unlock_for_update when done.
 */
static inline int __must_check
media_request_lock_for_update(struct media_request *req)
{
	unsigned long flags;
	int ret = 0;

	spin_lock_irqsave(&req->lo