summaryrefslogtreecommitdiff
path: root/gxp-mailbox-impl.h
blob: 2f4b5d8baaccf387ba9a7437a2d65fe5e2b18933 (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
135
136
137
138
139
140
141
142
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Legacy implementation of the GXP mailbox interface.
 * This file must be used only when the kernel driver has to compile the implementation of the
 * mailbox by itself (i.e, when the target chip can't be compiled with GCIP).
 *
 * Copyright (C) 2022 Google LLC
 */

#ifndef __GXP_MAILBOX_IMPL_H__
#define __GXP_MAILBOX_IMPL_H__

#include <linux/spinlock_types.h>
#include <linux/types.h>
#include <linux/wait.h>
#include <linux/workqueue.h>

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

/*
 * Basic Buffer descriptor struct for message payloads.
 */
struct buffer_descriptor {
	/* Address in the device's virtual address space. */
	u64 address;
	/* Size in bytes. */
	u32 size;
	/* Flags can be used to indicate message type, etc. */
	u32 flags;
};

/*
 * Format used for mailbox command queues.
 */
struct gxp_command {
	/* Sequence number. Should match the corresponding response. */
	u64 seq;
	/*
	 * Identifies the type of command.
	 * Should be a value from `gxp_mailbox_command_code`
	 */
	u16 code;
	/*
	 * Priority level from 0 to 99, with 0 being the highest. Pending
	 * commands with higher priorities will be executed before lower
	 * priority ones.
	 */
	u8 priority;
	/*
	 * Insert spaces to make padding explicit. This does not affect
	 * alignment.
	 */
	u8 reserved[5];
	/* Struct describing the buffer containing the message payload */
	struct buffer_descriptor buffer_descriptor;
};

/*
 * Format used for mailbox response queues from kernel.
 */
struct gxp_response {
	/* Sequence number. Should match the corresponding command. */
	u64 seq;
	/* The status code. Either SUCCESS or an error. */
	u16 status;
	/* Padding. */
	u16 reserved;
	/* Return value, dependent on the command this responds to. */
	u32 retval;
};

/*
 * Wrapper struct for responses consumed by a thread other than the one which
 * sent the command.
 */
struct gxp_async_response {
	struct list_head list_entry;
	struct gxp_response resp;
	struct delayed_work timeout_work;
	/*
	 * If this response times out, this pointer to the owning mailbox is
	 * needed to delete this response from the list of pending responses.
	 */
	struct gxp_mailbox *mailbox;
	/* Queue to add the response to once it is complete or timed out */
	struct list_head *dest_queue;
	/*
	 * The lock that protects queue pointed to by `dest_queue`.
	 * The mailbox code also uses this lock to protect changes to the
	 * `dest_queue` pointer itself when processing this response.
	 */
	spinlock_t *dest_queue_lock;
	/* Queue of clients to notify when this response is processed */
	wait_queue_head_t *dest_queue_waitq;
	/* Specified power states vote during the command execution */
	struct gxp_power_states requested_states;
	/* gxp_eventfd to signal when the response completes. May be NULL */
	struct gxp_eventfd *eventfd;
};

struct gxp_mailbox_wait_list {
	struct list_head list;
	struct gxp_response *resp;
	bool is_async;
};

struct gxp_mailbox;
struct gxp_mailbox_args;
struct gxp_mailbox_manager;

extern const struct gxp_mailbox_args gxp_mailbox_default_args;

/* Initializes operators of @mgr to work with the legacy implementation of mailbox. */
void gxp_mailbox_init(struct gxp_mailbox_manager *mgr);

/*
 * Following functions will be called by the `gxp-mailbox.c` according to its internal logic.
 * You may not call these functions directly.
 */

/*
 * Initializes the mailbox to be able to wait and consume responses.
 * This function will be called when the `gxp_mailbox_alloc` function is called.
 */
int gxp_mailbox_init_consume_responses(struct gxp_mailbox *mailbox);

/*
 * Flushes all pending responses in the mailbox.
 * This function will be called when the `gxp_mailbox_release` function is called.
 */
void gxp_mailbox_release_consume_responses(struct gxp_mailbox *mailbox);

/*
 * Fetches and handles responses, then wakes up threads that are waiting for a response.
 * This function will be called by a worker which is scheduled in the IRQ handler. (See the
 * `gxp_mailbox_consume_responses_work` function) To prevent use-after-free or race-condition
 * bugs, gxp_mailbox_release() must be called before free the mailbox.
 */
void gxp_mailbox_consume_responses(struct gxp_mailbox *mailbox);

#endif /* __GXP_MAILBOX_IMPL_H__ */