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 #define VCHIQ_DRV_MAX_CALLBACKS 10
24 
25 struct rpi_firmware;
26 struct vchiq_device;
27 
28 enum USE_TYPE_E {
29 	USE_TYPE_SERVICE,
30 	USE_TYPE_VCHIQ
31 };
32 
33 struct vchiq_platform_info {
34 	unsigned int cache_line_size;
35 };
36 
37 struct vchiq_drv_mgmt {
38 	struct rpi_firmware *fw;
39 	const struct vchiq_platform_info *info;
40 
41 	bool connected;
42 	int num_deferred_callbacks;
43 	/* Protects connected and num_deferred_callbacks */
44 	struct mutex connected_mutex;
45 
46 	void (*deferred_callback[VCHIQ_DRV_MAX_CALLBACKS])(void);
47 
48 	struct semaphore free_fragments_sema;
49 	struct semaphore free_fragments_mutex;
50 	char *fragments_base;
51 	char *free_fragments;
52 	unsigned int fragments_size;
53 
54 	void __iomem *regs;
55 
56 	struct vchiq_state state;
57 };
58 
59 struct user_service {
60 	struct vchiq_service *service;
61 	void __user *userdata;
62 	struct vchiq_instance *instance;
63 	char is_vchi;
64 	char dequeue_pending;
65 	char close_pending;
66 	int message_available_pos;
67 	int msg_insert;
68 	int msg_remove;
69 	struct completion insert_event;
70 	struct completion remove_event;
71 	struct completion close_event;
72 	struct vchiq_header *msg_queue[MSG_QUEUE_SIZE];
73 };
74 
75 struct bulk_waiter_node {
76 	struct bulk_waiter bulk_waiter;
77 	int pid;
78 	struct list_head list;
79 };
80 
81 struct vchiq_instance {
82 	struct vchiq_state *state;
83 	struct vchiq_completion_data_kernel completions[MAX_COMPLETIONS];
84 	int completion_insert;
85 	int completion_remove;
86 	struct completion insert_event;
87 	struct completion remove_event;
88 	struct mutex completion_mutex;
89 
90 	int connected;
91 	int closing;
92 	int pid;
93 	int mark;
94 	int use_close_delivered;
95 	int trace;
96 
97 	struct list_head bulk_waiter_list;
98 	struct mutex bulk_waiter_list_mutex;
99 
100 	struct vchiq_debugfs_node debugfs_node;
101 };
102 
103 int
104 vchiq_use_service(struct vchiq_instance *instance, unsigned int handle);
105 
106 extern int
107 vchiq_release_service(struct vchiq_instance *instance, unsigned int handle);
108 
109 extern int
110 vchiq_check_service(struct vchiq_service *service);
111 
112 extern void
113 vchiq_dump_service_use_state(struct vchiq_state *state);
114 
115 extern int
116 vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service,
117 		   enum USE_TYPE_E use_type);
118 extern int
119 vchiq_release_internal(struct vchiq_state *state,
120 		       struct vchiq_service *service);
121 
122 extern struct vchiq_debugfs_node *
123 vchiq_instance_get_debugfs_node(struct vchiq_instance *instance);
124 
125 extern int
126 vchiq_instance_get_use_count(struct vchiq_instance *instance);
127 
128 extern int
129 vchiq_instance_get_pid(struct vchiq_instance *instance);
130 
131 extern int
132 vchiq_instance_get_trace(struct vchiq_instance *instance);
133 
134 extern void
135 vchiq_instance_set_trace(struct vchiq_instance *instance, int trace);
136 
137 extern void
138 vchiq_add_connected_callback(struct vchiq_device *device,
139 			     void (*callback)(void));
140 
141 #if IS_ENABLED(CONFIG_VCHIQ_CDEV)
142 
143 extern void
144 vchiq_deregister_chrdev(void);
145 
146 extern int
147 vchiq_register_chrdev(struct device *parent);
148 
149 #else
150 
vchiq_deregister_chrdev(void)151 static inline void vchiq_deregister_chrdev(void) { }
vchiq_register_chrdev(struct device * parent)152 static inline int vchiq_register_chrdev(struct device *parent) { return 0; }
153 
154 #endif /* IS_ENABLED(CONFIG_VCHIQ_CDEV) */
155 
156 extern int
157 service_callback(struct vchiq_instance *vchiq_instance, enum vchiq_reason reason,
158 		 struct vchiq_header *header, unsigned int handle, void *bulk_userdata);
159 
160 extern void
161 free_bulk_waiter(struct vchiq_instance *instance);
162 
163 #endif /* VCHIQ_ARM_H */
164