staging: vchiq: Pass vchiq's message when holding a message
[linux-2.6-microblaze.git] / drivers / staging / vc04_services / interface / vchiq_arm / vchiq_shim.c
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright (c) 2010-2012 Broadcom. All rights reserved. */
3 #include <linux/module.h>
4 #include <linux/types.h>
5 #include <linux/slab.h>
6 #include <linux/delay.h>
7
8 #include "vchiq_if.h"
9 #include "../vchi/vchi.h"
10 #include "vchiq.h"
11 #include "vchiq_core.h"
12
13 int vchi_queue_kernel_message(unsigned handle, void *data, unsigned int size)
14 {
15         enum vchiq_status status;
16
17         while (1) {
18                 status = vchiq_queue_kernel_message(handle, data, size);
19
20                 /*
21                  * vchiq_queue_message() may return VCHIQ_RETRY, so we need to
22                  * implement a retry mechanism since this function is supposed
23                  * to block until queued
24                  */
25                 if (status != VCHIQ_RETRY)
26                         break;
27
28                 msleep(1);
29         }
30
31         return status;
32 }
33 EXPORT_SYMBOL(vchi_queue_kernel_message);
34
35 /***********************************************************
36  * Name: vchi_bulk_queue_receive
37  *
38  * Arguments:  VCHI_BULK_HANDLE_T handle,
39  *             void *data_dst,
40  *             const uint32_t data_size,
41  *             enum vchi_flags flags
42  *             void *bulk_handle
43  *
44  * Description: Routine to setup a rcv buffer
45  *
46  * Returns: int32_t - success == 0
47  *
48  ***********************************************************/
49 int32_t vchi_bulk_queue_receive(unsigned handle, void *data_dst,
50                                 uint32_t data_size, enum vchiq_bulk_mode mode,
51                                 void *bulk_handle)
52 {
53         enum vchiq_status status;
54
55         while (1) {
56                 status = vchiq_bulk_receive(handle, data_dst, data_size,
57                                             bulk_handle, mode);
58                 /*
59                  * vchiq_bulk_receive() may return VCHIQ_RETRY, so we need to
60                  * implement a retry mechanism since this function is supposed
61                  * to block until queued
62                  */
63                 if (status != VCHIQ_RETRY)
64                         break;
65
66                 msleep(1);
67         }
68
69         return status;
70 }
71 EXPORT_SYMBOL(vchi_bulk_queue_receive);
72
73 /***********************************************************
74  * Name: vchi_bulk_queue_transmit
75  *
76  * Arguments:  VCHI_BULK_HANDLE_T handle,
77  *             const void *data_src,
78  *             uint32_t data_size,
79  *             enum vchi_flags flags,
80  *             void *bulk_handle
81  *
82  * Description: Routine to transmit some data
83  *
84  * Returns: int32_t - success == 0
85  *
86  ***********************************************************/
87 int32_t vchi_bulk_queue_transmit(unsigned handle, const void *data_src,
88                                  uint32_t data_size, enum vchiq_bulk_mode mode,
89                                  void *bulk_handle)
90 {
91         enum vchiq_status status;
92
93         while (1) {
94                 status = vchiq_bulk_transmit(handle, data_src, data_size,
95                                              bulk_handle, mode);
96
97                 /*
98                  * vchiq_bulk_transmit() may return VCHIQ_RETRY, so we need to
99                  * implement a retry mechanism since this function is supposed
100                  * to block until queued
101                  */
102                 if (status != VCHIQ_RETRY)
103                         break;
104
105                 msleep(1);
106         }
107
108         return status;
109 }
110 EXPORT_SYMBOL(vchi_bulk_queue_transmit);
111
112
113 /***********************************************************
114  * Name: vchi_held_msg_release
115  *
116  * Arguments:  unsgined handle
117  *             struct vchiq_header *message
118  *
119  * Description: Routine to release a held message (after it has been read with
120  *              vchi_msg_hold)
121  *
122  * Returns: int32_t - success == 0
123  *
124  ***********************************************************/
125 int32_t vchi_held_msg_release(unsigned handle, struct vchiq_header *message)
126 {
127         /*
128          * Convert the service field pointer back to an
129          * unsigned int which is an int.
130          * This pointer is opaque to everything except
131          * vchi_msg_hold which simply upcasted the int
132          * to a pointer.
133          */
134
135         vchiq_release_message(handle, message);
136
137         return 0;
138 }
139 EXPORT_SYMBOL(vchi_held_msg_release);
140
141 /***********************************************************
142  * Name: vchi_msg_hold
143  *
144  * Arguments:  struct vchi_service *service,
145  *             void **data,
146  *             uint32_t *msg_size,
147  *             struct vchiq_header **message
148  *
149  * Description: Routine to return a pointer to the current message (to allow
150  *              in place processing). The message is dequeued - don't forget
151  *              to release the message using vchi_held_msg_release when you're
152  *              finished.
153  *
154  * Returns: int32_t - success == 0
155  *
156  ***********************************************************/
157 int32_t vchi_msg_hold(unsigned handle, void **data, uint32_t *msg_size,
158                       struct vchiq_header **message)
159 {
160         struct vchiq_header *header;
161
162         header = vchiq_msg_hold(handle);
163         if (!header)
164                 return -ENOENT;
165
166         *data = header->data;
167         *msg_size = header->size;
168         *message = header;
169
170         return 0;
171 }
172 EXPORT_SYMBOL(vchi_msg_hold);
173
174 /***********************************************************
175  * Name: vchi_initialise
176  *
177  * Arguments: struct vchiq_instance **instance
178  *
179  * Description: Initialises the hardware but does not transmit anything
180  *              When run as a Host App this will be called twice hence the need
181  *              to malloc the state information
182  *
183  * Returns: 0 if successful, failure otherwise
184  *
185  ***********************************************************/
186
187 int32_t vchi_initialise(struct vchiq_instance **instance)
188 {
189         return vchiq_initialise(instance);
190 }
191 EXPORT_SYMBOL(vchi_initialise);
192
193 /***********************************************************
194  * Name: vchi_connect
195  *
196  * Arguments: struct vchiq_instance *instance
197  *
198  * Description: Starts the command service on each connection,
199  *              causing INIT messages to be pinged back and forth
200  *
201  * Returns: 0 if successful, failure otherwise
202  *
203  ***********************************************************/
204 int32_t vchi_connect(struct vchiq_instance *instance)
205 {
206         return vchiq_connect(instance);
207 }
208 EXPORT_SYMBOL(vchi_connect);
209
210 /***********************************************************
211  * Name: vchi_disconnect
212  *
213  * Arguments: struct vchiq_instance *instance
214  *
215  * Description: Stops the command service on each connection,
216  *              causing DE-INIT messages to be pinged back and forth
217  *
218  * Returns: 0 if successful, failure otherwise
219  *
220  ***********************************************************/
221 int32_t vchi_disconnect(struct vchiq_instance *instance)
222 {
223         return vchiq_shutdown(instance);
224 }
225 EXPORT_SYMBOL(vchi_disconnect);
226
227 /***********************************************************
228  * Name: vchi_service_open
229  * Name: vchi_service_create
230  *
231  * Arguments: struct vchiq_instance *instance
232  *            struct service_creation *setup,
233  *            unsigned *handle
234  *
235  * Description: Routine to open a service
236  *
237  * Returns: int32_t - success == 0
238  *
239  ***********************************************************/
240
241 int32_t vchi_service_open(struct vchiq_instance *instance,
242                       struct vchiq_service_params *params,
243                       unsigned *handle)
244 {
245         return vchiq_open_service(instance, params, handle);
246 }
247 EXPORT_SYMBOL(vchi_service_open);
248
249 int32_t vchi_service_close(unsigned handle)
250 {
251         return vchiq_close_service(handle);
252 }
253 EXPORT_SYMBOL(vchi_service_close);
254
255 int32_t vchi_get_peer_version(unsigned handle, short *peer_version)
256 {
257         return vchiq_get_peer_version(handle, peer_version);
258 }
259 EXPORT_SYMBOL(vchi_get_peer_version);
260
261 /***********************************************************
262  * Name: vchi_service_use
263  *
264  * Arguments: unsigned handle
265  *
266  * Description: Routine to increment refcount on a service
267  *
268  * Returns: void
269  *
270  ***********************************************************/
271 int32_t vchi_service_use(unsigned handle)
272 {
273         return vchiq_use_service(handle);
274 }
275 EXPORT_SYMBOL(vchi_service_use);
276
277 /***********************************************************
278  * Name: vchi_service_release
279  *
280  * Arguments: unsigned handle
281  *
282  * Description: Routine to decrement refcount on a service
283  *
284  * Returns: void
285  *
286  ***********************************************************/
287 int32_t vchi_service_release(unsigned handle)
288 {
289         return vchiq_release_service(handle);
290 }
291 EXPORT_SYMBOL(vchi_service_release);