1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
2 /*
3 * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved.
4 * Copyright (c) 2010-2012 Broadcom. All rights reserved.
5 */
6
7 #ifndef VCHIQ_ARM_H
8 #define VCHIQ_ARM_H
9
10 #include <linux/mutex.h>
11 #include <linux/platform_device.h>
12 #include <linux/semaphore.h>
13 #include <linux/atomic.h>
14 #include "vchiq_core.h"
15 #include "vchiq_debugfs.h"
16
17 /* Some per-instance constants */
18 #define MAX_COMPLETIONS 128
19 #define MAX_SERVICES 64
20 #define MAX_ELEMENTS 8
21 #define MSG_QUEUE_SIZE 128
22
23 enum USE_TYPE_E {
24 USE_TYPE_SERVICE,
25 USE_TYPE_VCHIQ
26 };
27
28 struct vchiq_arm_state {
29 /* Keepalive-related data */
30 struct task_struct *ka_thread;
31 struct completion ka_evt;
32 atomic_t ka_use_count;
33 atomic_t ka_use_ack_count;
34 atomic_t ka_release_count;
35
36 rwlock_t susp_res_lock;
37
38 struct vchiq_state *state;
39
40 /*
41 * Global use count for videocore.
42 * This is equal to the sum of the use counts for all services. When
43 * this hits zero the videocore suspend procedure will be initiated.
44 */
45 int videocore_use_count;
46
47 /*
48 * Use count to track requests from videocore peer.
49 * This use count is not associated with a service, so needs to be
50 * tracked separately with the state.
51 */
52 int peer_use_count;
53
54 /*
55 * Flag to indicate that the first vchiq connect has made it through.
56 * This means that both sides should be fully ready, and we should
57 * be able to suspend after this point.
58 */
59 int first_connect;
60 };
61
62 struct vchiq_drvdata {
63 const unsigned int cache_line_size;
64 struct rpi_firmware *fw;
65 };
66
67 struct user_service {
68 struct vchiq_service *service;
69 void __user *userdata;
70 struct vchiq_instance *instance;
71 char is_vchi;
72 char dequeue_pending;
73 char close_pending;
74 int message_available_pos;
75 int msg_insert;
76 int msg_remove;
77 struct completion insert_event;
78 struct completion remove_event;
79 struct completion close_event;
80 struct vchiq_header *msg_queue[MSG_QUEUE_SIZE];
81 };
82
83 struct bulk_waiter_node {
84 struct bulk_waiter bulk_waiter;
85 int pid;
86 struct list_head list;
87 };
88
89 struct vchiq_instance {
90 struct vchiq_state *state;
91 struct vchiq_completion_data_kernel completions[MAX_COMPLETIONS];
92 int completion_insert;
93 int completion_remove;
94 struct completion insert_event;
95 struct completion remove_event;
96 struct mutex completion_mutex;
97
98 int connected;
99 int closing;
100 int pid;
101 int mark;
102 int use_close_delivered;
103 int trace;
104
105 struct list_head bulk_waiter_list;
106 struct mutex bulk_waiter_list_mutex;
107
108 struct vchiq_debugfs_node debugfs_node;
109 };
110
111 struct dump_context {
112 char __user *buf;
113 size_t actual;
114 size_t space;
115 loff_t offset;
116 };
117
118 extern int vchiq_arm_log_level;
119 extern int vchiq_susp_log_level;
120
121 extern spinlock_t msg_queue_spinlock;
122 extern struct vchiq_state g_state;
123
124 int vchiq_platform_init(struct platform_device *pdev,
125 struct vchiq_state *state);
126
127 extern struct vchiq_state *
128 vchiq_get_state(void);
129
130 extern void
131 vchiq_arm_init_state(struct vchiq_state *state,
132 struct vchiq_arm_state *arm_state);
133
134 extern void
135 vchiq_check_suspend(struct vchiq_state *state);
136 enum vchiq_status
137 vchiq_use_service(unsigned int handle);
138
139 extern enum vchiq_status
140 vchiq_release_service(unsigned int handle);
141
142 extern enum vchiq_status
143 vchiq_check_service(struct vchiq_service *service);
144
145 extern void
146 vchiq_dump_platform_use_state(struct vchiq_state *state);
147
148 extern void
149 vchiq_dump_service_use_state(struct vchiq_state *state);
150
151 extern struct vchiq_arm_state*
152 vchiq_platform_get_arm_state(struct vchiq_state *state);
153
154
155 extern enum vchiq_status
156 vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service,
157 enum USE_TYPE_E use_type);
158 extern enum vchiq_status
159 vchiq_release_internal(struct vchiq_state *state,
160 struct vchiq_service *service);
161
162 extern struct vchiq_debugfs_node *
163 vchiq_instance_get_debugfs_node(struct vchiq_instance *instance);
164
165 extern int
166 vchiq_instance_get_use_count(struct vchiq_instance *instance);
167
168 extern int
169 vchiq_instance_get_pid(struct vchiq_instance *instance);
170
171 extern int
172 vchiq_instance_get_trace(struct vchiq_instance *instance);
173
174 extern void
175 vchiq_instance_set_trace(struct vchiq_instance *instance, int trace);
176
177 #if IS_ENABLED(CONFIG_VCHIQ_CDEV)
178
179 extern void
180 vchiq_deregister_chrdev(void);
181
182 extern int
183 vchiq_register_chrdev(struct device *parent);
184
185 #else
186
vchiq_deregister_chrdev(void)187 static inline void vchiq_deregister_chrdev(void) { }
vchiq_register_chrdev(struct device * parent)188 static inline int vchiq_register_chrdev(struct device *parent) { return 0; }
189
190 #endif /* IS_ENABLED(CONFIG_VCHIQ_CDEV) */
191
192 extern enum vchiq_status
193 service_callback(enum vchiq_reason reason, struct vchiq_header *header,
194 unsigned int handle, void *bulk_userdata);
195
196 extern void
197 free_bulk_waiter(struct vchiq_instance *instance);
198
199 #endif /* VCHIQ_ARM_H */
200