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 extern enum vchiq_status
155 vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service,
156 		   enum USE_TYPE_E use_type);
157 extern enum vchiq_status
158 vchiq_release_internal(struct vchiq_state *state,
159 		       struct vchiq_service *service);
160 
161 extern struct vchiq_debugfs_node *
162 vchiq_instance_get_debugfs_node(struct vchiq_instance *instance);
163 
164 extern int
165 vchiq_instance_get_use_count(struct vchiq_instance *instance);
166 
167 extern int
168 vchiq_instance_get_pid(struct vchiq_instance *instance);
169 
170 extern int
171 vchiq_instance_get_trace(struct vchiq_instance *instance);
172 
173 extern void
174 vchiq_instance_set_trace(struct vchiq_instance *instance, int trace);
175 
176 #if IS_ENABLED(CONFIG_VCHIQ_CDEV)
177 
178 extern void
179 vchiq_deregister_chrdev(void);
180 
181 extern int
182 vchiq_register_chrdev(struct device *parent);
183 
184 #else
185 
186 static inline void vchiq_deregister_chrdev(void) { }
187 static inline int vchiq_register_chrdev(struct device *parent) { return 0; }
188 
189 #endif /* IS_ENABLED(CONFIG_VCHIQ_CDEV) */
190 
191 extern enum vchiq_status
192 service_callback(enum vchiq_reason reason, struct vchiq_header *header,
193 		 unsigned int handle, void *bulk_userdata);
194 
195 extern void
196 free_bulk_waiter(struct vchiq_instance *instance);
197 
198 #endif /* VCHIQ_ARM_H */
199