summaryrefslogtreecommitdiff
path: root/gxp-client.h
blob: 470622b112840c2872d0a01aca697afbbae4c4f1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * GXP client structure.
 *
 * Copyright (C) 2022 Google LLC
 */
#ifndef __GXP_CLIENT_H__
#define __GXP_CLIENT_H__

#include <linux/file.h>
#include <linux/rwsem.h>
#include <linux/sched.h>
#include <linux/types.h>

#include "gxp-eventfd.h"
#include "gxp-internal.h"
#include "gxp-pm.h"
#include "gxp-vd.h"

/* Holds state belonging to a client */
struct gxp_client {
	struct list_head list_entry;
	struct gxp_dev *gxp;

	/*
	 * Protects all state of this client instance.
	 * Any operation that requires a client hold a particular wakelock must
	 * lock this semaphore for reading for the duration of that operation.
	 */
	struct rw_semaphore semaphore;
	struct lock_class_key key;

	bool has_block_wakelock;
	bool has_vd_wakelock;

	struct gxp_power_states requested_states;

	struct gxp_virtual_device *vd;
	struct file *tpu_file;
	struct gxp_tpu_mbx_desc mbx_desc;

	struct gxp_eventfd *mb_eventfds[GXP_NUM_CORES];

	/* client process thread group ID is really the main process ID. */
	pid_t tgid;
	/* client process ID is really the thread ID, may be transient. */
	pid_t pid;
};

/*
 * Allocates and initializes a client container.
 */
struct gxp_client *gxp_client_create(struct gxp_dev *gxp);

/*
 * Frees up the client container cleaning up any wakelocks, virtual devices, or
 * TPU mailboxes it holds.
 */
void gxp_client_destroy(struct gxp_client *client);
/**
 * gxp_client_allocate_virtual_device() - Allocates a virtual device for the
 * client.
 *
 * @client: The client to allocate a virtual device
 * @core_count: The requested core count of the virtual device.
 * @flags: The flags passed from the runtime's request.
 *
 * The caller must have locked client->semaphore.
 *
 * Return:
 * * 0          - Success
 * * -EINVAL    - A virtual device of the client has been allocated
 * * Otherwise  - Errno returned by virtual device allocation
 */
int gxp_client_allocate_virtual_device(struct gxp_client *client,
				       uint core_count, u8 flags);
/**
 * gxp_client_acquire_block_wakelock() - Acquires a block wakelock.
 *
 * @client: The client to acquire wakelock.
 * @acquired_wakelock: True if block wakelock has been acquired by this client.
 *
 * The caller must have locked client->semaphore.
 *
 * Return:
 * * 0          - Success
 * * Otherwise  - Errno returned by block wakelock acquisition
 */
int gxp_client_acquire_block_wakelock(struct gxp_client *client,
				      bool *acquired_wakelock);
/**
 * gxp_client_release_block_wakelock() - Releases the holded block wakelock and
 * revokes the power votes.
 *
 * The caller must have locked client->semaphore.
 */
void gxp_client_release_block_wakelock(struct gxp_client *client);
/**
 * gxp_client_acquire_vd_wakelock() - Acquires a VD wakelock for the current
 * virtual device to start the virtual device or resume it if it's suspended.
 * Also the client can request the power votes tied with the acquired wakelock.
 *
 * @client: The client to acquire wakelock and request power votes.
 * @requested_states: The requested power states.
 *
 * The caller must have locked client->semaphore.
 *
 * Return:
 * * 0          - Success
 * * -EINVAL    - No holded block wakelock
 * * -ENODEV    - VD state is unavailable
 */
int gxp_client_acquire_vd_wakelock(struct gxp_client *client,
				   struct gxp_power_states requested_states);
/**
 * gxp_client_release_vd_wakelock() - Releases the holded VD wakelock to suspend
 * the current virtual device.
 *
 * The caller must have locked client->semaphore.
 */
void gxp_client_release_vd_wakelock(struct gxp_client *client);

/**
 * gxp_client_has_available_vd() - Returns whether @client has an available
 * virtual device.
 *
 * @client: The client to check.
 * @name: The string used for logging when the client has an invalid VD.
 *
 * The caller must have locked client->semaphore.
 */
bool gxp_client_has_available_vd(struct gxp_client *client, const char *name);

#endif /* __GXP_CLIENT_H__ */