2 * Copyright (c) 2010-2012 Broadcom. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions, and the following disclaimer,
9 * without modification.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The names of the above-listed copyright holders may not be used
14 * to endorse or promote products derived from this software without
15 * specific prior written permission.
17 * ALTERNATIVELY, this software may be distributed under the terms of the
18 * GNU General Public License ("GPL") version 2, as published by the Free
19 * Software Foundation.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
25 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include <linux/module.h>
34 #include <linux/types.h>
36 #include "interface/vchi/vchi.h"
38 #include "vchiq_core.h"
40 #include "vchiq_util.h"
44 #define vchiq_status_to_vchi(status) ((int32_t)status)
47 VCHIQ_SERVICE_HANDLE_T handle;
51 VCHI_CALLBACK_T callback;
55 /* ----------------------------------------------------------------------
56 * return pointer to the mphi message driver function table
57 * -------------------------------------------------------------------- */
58 const VCHI_MESSAGE_DRIVER_T *
59 vchi_mphi_message_driver_func_table(void)
64 /* ----------------------------------------------------------------------
65 * return a pointer to the 'single' connection driver fops
66 * -------------------------------------------------------------------- */
67 const VCHI_CONNECTION_API_T *
68 single_get_func_table(void)
73 VCHI_CONNECTION_T *vchi_create_connection(
74 const VCHI_CONNECTION_API_T *function_table,
75 const VCHI_MESSAGE_DRIVER_T *low_level)
82 /***********************************************************
85 * Arguments: const VCHI_SERVICE_HANDLE_T handle,
92 * Description: Routine to return a pointer to the current message (to allow in
93 * place processing). The message can be removed using
94 * vchi_msg_remove when you're finished
96 * Returns: int32_t - success == 0
98 ***********************************************************/
99 int32_t vchi_msg_peek(VCHI_SERVICE_HANDLE_T handle,
104 SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
105 VCHIQ_HEADER_T *header;
107 WARN_ON((flags != VCHI_FLAGS_NONE) &&
108 (flags != VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE));
110 if (flags == VCHI_FLAGS_NONE)
111 if (vchiu_queue_is_empty(&service->queue))
114 header = vchiu_queue_peek(&service->queue);
116 *data = header->data;
117 *msg_size = header->size;
121 EXPORT_SYMBOL(vchi_msg_peek);
123 /***********************************************************
124 * Name: vchi_msg_remove
126 * Arguments: const VCHI_SERVICE_HANDLE_T handle,
128 * Description: Routine to remove a message (after it has been read with
131 * Returns: int32_t - success == 0
133 ***********************************************************/
134 int32_t vchi_msg_remove(VCHI_SERVICE_HANDLE_T handle)
136 SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
137 VCHIQ_HEADER_T *header;
139 header = vchiu_queue_pop(&service->queue);
141 vchiq_release_message(service->handle, header);
145 EXPORT_SYMBOL(vchi_msg_remove);
147 /***********************************************************
148 * Name: vchi_msg_queue
150 * Arguments: VCHI_SERVICE_HANDLE_T handle,
152 * uint32_t data_size,
153 * VCHI_FLAGS_T flags,
156 * Description: Thin wrapper to queue a message onto a connection
158 * Returns: int32_t - success == 0
160 ***********************************************************/
161 int32_t vchi_msg_queue(VCHI_SERVICE_HANDLE_T handle,
167 SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
168 VCHIQ_ELEMENT_T element = {data, data_size};
169 VCHIQ_STATUS_T status;
173 WARN_ON(flags != VCHI_FLAGS_BLOCK_UNTIL_QUEUED);
175 status = vchiq_queue_message(service->handle, &element, 1);
177 /* vchiq_queue_message() may return VCHIQ_RETRY, so we need to
178 ** implement a retry mechanism since this function is supposed
179 ** to block until queued
181 while (status == VCHIQ_RETRY) {
183 status = vchiq_queue_message(service->handle, &element, 1);
186 return vchiq_status_to_vchi(status);
188 EXPORT_SYMBOL(vchi_msg_queue);
190 /***********************************************************
191 * Name: vchi_bulk_queue_receive
193 * Arguments: VCHI_BULK_HANDLE_T handle,
195 * const uint32_t data_size,
199 * Description: Routine to setup a rcv buffer
201 * Returns: int32_t - success == 0
203 ***********************************************************/
204 int32_t vchi_bulk_queue_receive(VCHI_SERVICE_HANDLE_T handle,
210 SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
211 VCHIQ_BULK_MODE_T mode;
212 VCHIQ_STATUS_T status;
214 switch ((int)flags) {
215 case VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE
216 | VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
217 WARN_ON(!service->callback);
218 mode = VCHIQ_BULK_MODE_CALLBACK;
220 case VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE:
221 mode = VCHIQ_BULK_MODE_BLOCKING;
223 case VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
224 case VCHI_FLAGS_NONE:
225 mode = VCHIQ_BULK_MODE_NOCALLBACK;
228 WARN(1, "unsupported message\n");
229 return vchiq_status_to_vchi(VCHIQ_ERROR);
232 status = vchiq_bulk_receive(service->handle, data_dst, data_size,
235 /* vchiq_bulk_receive() may return VCHIQ_RETRY, so we need to
236 ** implement a retry mechanism since this function is supposed
237 ** to block until queued
239 while (status == VCHIQ_RETRY) {
241 status = vchiq_bulk_receive(service->handle, data_dst,
242 data_size, bulk_handle, mode);
245 return vchiq_status_to_vchi(status);
247 EXPORT_SYMBOL(vchi_bulk_queue_receive);
249 /***********************************************************
250 * Name: vchi_bulk_queue_transmit
252 * Arguments: VCHI_BULK_HANDLE_T handle,
253 * const void *data_src,
254 * uint32_t data_size,
255 * VCHI_FLAGS_T flags,
258 * Description: Routine to transmit some data
260 * Returns: int32_t - success == 0
262 ***********************************************************/
263 int32_t vchi_bulk_queue_transmit(VCHI_SERVICE_HANDLE_T handle,
264 const void *data_src,
269 SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
270 VCHIQ_BULK_MODE_T mode;
271 VCHIQ_STATUS_T status;
273 switch ((int)flags) {
274 case VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE
275 | VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
276 WARN_ON(!service->callback);
277 mode = VCHIQ_BULK_MODE_CALLBACK;
279 case VCHI_FLAGS_BLOCK_UNTIL_DATA_READ:
280 case VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE:
281 mode = VCHIQ_BULK_MODE_BLOCKING;
283 case VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
284 case VCHI_FLAGS_NONE:
285 mode = VCHIQ_BULK_MODE_NOCALLBACK;
288 WARN(1, "unsupported message\n");
289 return vchiq_status_to_vchi(VCHIQ_ERROR);
292 status = vchiq_bulk_transmit(service->handle, data_src, data_size,
295 /* vchiq_bulk_transmit() may return VCHIQ_RETRY, so we need to
296 ** implement a retry mechanism since this function is supposed
297 ** to block until queued
299 while (status == VCHIQ_RETRY) {
301 status = vchiq_bulk_transmit(service->handle, data_src,
302 data_size, bulk_handle, mode);
305 return vchiq_status_to_vchi(status);
307 EXPORT_SYMBOL(vchi_bulk_queue_transmit);
309 /***********************************************************
310 * Name: vchi_msg_dequeue
312 * Arguments: VCHI_SERVICE_HANDLE_T handle,
314 * uint32_t max_data_size_to_read,
315 * uint32_t *actual_msg_size
318 * Description: Routine to dequeue a message into the supplied buffer
320 * Returns: int32_t - success == 0
322 ***********************************************************/
323 int32_t vchi_msg_dequeue(VCHI_SERVICE_HANDLE_T handle,
325 uint32_t max_data_size_to_read,
326 uint32_t *actual_msg_size,
329 SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
330 VCHIQ_HEADER_T *header;
332 WARN_ON((flags != VCHI_FLAGS_NONE) &&
333 (flags != VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE));
335 if (flags == VCHI_FLAGS_NONE)
336 if (vchiu_queue_is_empty(&service->queue))
339 header = vchiu_queue_pop(&service->queue);
341 memcpy(data, header->data, header->size < max_data_size_to_read ?
342 header->size : max_data_size_to_read);
344 *actual_msg_size = header->size;
346 vchiq_release_message(service->handle, header);
350 EXPORT_SYMBOL(vchi_msg_dequeue);
352 /***********************************************************
353 * Name: vchi_msg_queuev
355 * Arguments: VCHI_SERVICE_HANDLE_T handle,
356 * VCHI_MSG_VECTOR_T *vector,
358 * VCHI_FLAGS_T flags,
361 * Description: Thin wrapper to queue a message onto a connection
363 * Returns: int32_t - success == 0
365 ***********************************************************/
367 vchiq_static_assert(sizeof(VCHI_MSG_VECTOR_T) == sizeof(VCHIQ_ELEMENT_T));
368 vchiq_static_assert(offsetof(VCHI_MSG_VECTOR_T, vec_base) ==
369 offsetof(VCHIQ_ELEMENT_T, data));
370 vchiq_static_assert(offsetof(VCHI_MSG_VECTOR_T, vec_len) ==
371 offsetof(VCHIQ_ELEMENT_T, size));
373 int32_t vchi_msg_queuev(VCHI_SERVICE_HANDLE_T handle,
374 VCHI_MSG_VECTOR_T *vector,
379 SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
383 WARN_ON(flags != VCHI_FLAGS_BLOCK_UNTIL_QUEUED);
385 return vchiq_status_to_vchi(vchiq_queue_message(service->handle,
386 (const VCHIQ_ELEMENT_T *)vector, count));
388 EXPORT_SYMBOL(vchi_msg_queuev);
390 /***********************************************************
391 * Name: vchi_held_msg_release
393 * Arguments: VCHI_HELD_MSG_T *message
395 * Description: Routine to release a held message (after it has been read with
398 * Returns: int32_t - success == 0
400 ***********************************************************/
401 int32_t vchi_held_msg_release(VCHI_HELD_MSG_T *message)
403 vchiq_release_message((VCHIQ_SERVICE_HANDLE_T)message->service,
404 (VCHIQ_HEADER_T *)message->message);
408 EXPORT_SYMBOL(vchi_held_msg_release);
410 /***********************************************************
411 * Name: vchi_msg_hold
413 * Arguments: VCHI_SERVICE_HANDLE_T handle,
415 * uint32_t *msg_size,
416 * VCHI_FLAGS_T flags,
417 * VCHI_HELD_MSG_T *message_handle
419 * Description: Routine to return a pointer to the current message (to allow
420 * in place processing). The message is dequeued - don't forget
421 * to release the message using vchi_held_msg_release when you're
424 * Returns: int32_t - success == 0
426 ***********************************************************/
427 int32_t vchi_msg_hold(VCHI_SERVICE_HANDLE_T handle,
431 VCHI_HELD_MSG_T *message_handle)
433 SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
434 VCHIQ_HEADER_T *header;
436 WARN_ON((flags != VCHI_FLAGS_NONE) &&
437 (flags != VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE));
439 if (flags == VCHI_FLAGS_NONE)
440 if (vchiu_queue_is_empty(&service->queue))
443 header = vchiu_queue_pop(&service->queue);
445 *data = header->data;
446 *msg_size = header->size;
448 message_handle->service =
449 (struct opaque_vchi_service_t *)service->handle;
450 message_handle->message = header;
454 EXPORT_SYMBOL(vchi_msg_hold);
456 /***********************************************************
457 * Name: vchi_initialise
459 * Arguments: VCHI_INSTANCE_T *instance_handle
461 * Description: Initialises the hardware but does not transmit anything
462 * When run as a Host App this will be called twice hence the need
463 * to malloc the state information
465 * Returns: 0 if successful, failure otherwise
467 ***********************************************************/
469 int32_t vchi_initialise(VCHI_INSTANCE_T *instance_handle)
471 VCHIQ_INSTANCE_T instance;
472 VCHIQ_STATUS_T status;
474 status = vchiq_initialise(&instance);
476 *instance_handle = (VCHI_INSTANCE_T)instance;
478 return vchiq_status_to_vchi(status);
480 EXPORT_SYMBOL(vchi_initialise);
482 /***********************************************************
485 * Arguments: VCHI_CONNECTION_T **connections
486 * const uint32_t num_connections
487 * VCHI_INSTANCE_T instance_handle)
489 * Description: Starts the command service on each connection,
490 * causing INIT messages to be pinged back and forth
492 * Returns: 0 if successful, failure otherwise
494 ***********************************************************/
495 int32_t vchi_connect(VCHI_CONNECTION_T **connections,
496 const uint32_t num_connections,
497 VCHI_INSTANCE_T instance_handle)
499 VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;
502 (void)num_connections;
504 return vchiq_connect(instance);
506 EXPORT_SYMBOL(vchi_connect);
509 /***********************************************************
510 * Name: vchi_disconnect
512 * Arguments: VCHI_INSTANCE_T instance_handle
514 * Description: Stops the command service on each connection,
515 * causing DE-INIT messages to be pinged back and forth
517 * Returns: 0 if successful, failure otherwise
519 ***********************************************************/
520 int32_t vchi_disconnect(VCHI_INSTANCE_T instance_handle)
522 VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;
523 return vchiq_status_to_vchi(vchiq_shutdown(instance));
525 EXPORT_SYMBOL(vchi_disconnect);
528 /***********************************************************
529 * Name: vchi_service_open
530 * Name: vchi_service_create
532 * Arguments: VCHI_INSTANCE_T *instance_handle
533 * SERVICE_CREATION_T *setup,
534 * VCHI_SERVICE_HANDLE_T *handle
536 * Description: Routine to open a service
538 * Returns: int32_t - success == 0
540 ***********************************************************/
542 static VCHIQ_STATUS_T shim_callback(VCHIQ_REASON_T reason,
543 VCHIQ_HEADER_T *header, VCHIQ_SERVICE_HANDLE_T handle, void *bulk_user)
545 SHIM_SERVICE_T *service =
546 (SHIM_SERVICE_T *)VCHIQ_GET_SERVICE_USERDATA(handle);
548 if (!service->callback)
552 case VCHIQ_MESSAGE_AVAILABLE:
553 vchiu_queue_push(&service->queue, header);
555 service->callback(service->callback_param,
556 VCHI_CALLBACK_MSG_AVAILABLE, NULL);
561 case VCHIQ_BULK_TRANSMIT_DONE:
562 service->callback(service->callback_param,
563 VCHI_CALLBACK_BULK_SENT, bulk_user);
566 case VCHIQ_BULK_RECEIVE_DONE:
567 service->callback(service->callback_param,
568 VCHI_CALLBACK_BULK_RECEIVED, bulk_user);
571 case VCHIQ_SERVICE_CLOSED:
572 service->callback(service->callback_param,
573 VCHI_CALLBACK_SERVICE_CLOSED, NULL);
576 case VCHIQ_SERVICE_OPENED:
577 /* No equivalent VCHI reason */
580 case VCHIQ_BULK_TRANSMIT_ABORTED:
581 service->callback(service->callback_param,
582 VCHI_CALLBACK_BULK_TRANSMIT_ABORTED,
586 case VCHIQ_BULK_RECEIVE_ABORTED:
587 service->callback(service->callback_param,
588 VCHI_CALLBACK_BULK_RECEIVE_ABORTED,
593 WARN(1, "not supported\n");
598 vchiq_release_message(service->handle, header);
600 return VCHIQ_SUCCESS;
603 static SHIM_SERVICE_T *service_alloc(VCHIQ_INSTANCE_T instance,
604 SERVICE_CREATION_T *setup)
606 SHIM_SERVICE_T *service = kzalloc(sizeof(SHIM_SERVICE_T), GFP_KERNEL);
611 if (vchiu_queue_init(&service->queue, 64)) {
612 service->callback = setup->callback;
613 service->callback_param = setup->callback_param;
623 static void service_free(SHIM_SERVICE_T *service)
626 vchiu_queue_delete(&service->queue);
631 int32_t vchi_service_open(VCHI_INSTANCE_T instance_handle,
632 SERVICE_CREATION_T *setup,
633 VCHI_SERVICE_HANDLE_T *handle)
635 VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;
636 SHIM_SERVICE_T *service = service_alloc(instance, setup);
638 *handle = (VCHI_SERVICE_HANDLE_T)service;
641 VCHIQ_SERVICE_PARAMS_T params;
642 VCHIQ_STATUS_T status;
644 memset(¶ms, 0, sizeof(params));
645 params.fourcc = setup->service_id;
646 params.callback = shim_callback;
647 params.userdata = service;
648 params.version = setup->version.version;
649 params.version_min = setup->version.version_min;
651 status = vchiq_open_service(instance, ¶ms,
653 if (status != VCHIQ_SUCCESS) {
654 service_free(service);
660 return (service != NULL) ? 0 : -1;
662 EXPORT_SYMBOL(vchi_service_open);
664 int32_t vchi_service_create(VCHI_INSTANCE_T instance_handle,
665 SERVICE_CREATION_T *setup,
666 VCHI_SERVICE_HANDLE_T *handle)
668 VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;
669 SHIM_SERVICE_T *service = service_alloc(instance, setup);
671 *handle = (VCHI_SERVICE_HANDLE_T)service;
674 VCHIQ_SERVICE_PARAMS_T params;
675 VCHIQ_STATUS_T status;
677 memset(¶ms, 0, sizeof(params));
678 params.fourcc = setup->service_id;
679 params.callback = shim_callback;
680 params.userdata = service;
681 params.version = setup->version.version;
682 params.version_min = setup->version.version_min;
683 status = vchiq_add_service(instance, ¶ms, &service->handle);
685 if (status != VCHIQ_SUCCESS) {
686 service_free(service);
692 return (service != NULL) ? 0 : -1;
694 EXPORT_SYMBOL(vchi_service_create);
696 int32_t vchi_service_close(const VCHI_SERVICE_HANDLE_T handle)
699 SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
701 VCHIQ_STATUS_T status = vchiq_close_service(service->handle);
702 if (status == VCHIQ_SUCCESS) {
703 service_free(service);
707 ret = vchiq_status_to_vchi(status);
711 EXPORT_SYMBOL(vchi_service_close);
713 int32_t vchi_service_destroy(const VCHI_SERVICE_HANDLE_T handle)
716 SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
718 VCHIQ_STATUS_T status = vchiq_remove_service(service->handle);
719 if (status == VCHIQ_SUCCESS) {
720 service_free(service);
724 ret = vchiq_status_to_vchi(status);
728 EXPORT_SYMBOL(vchi_service_destroy);
730 int32_t vchi_service_set_option(const VCHI_SERVICE_HANDLE_T handle,
731 VCHI_SERVICE_OPTION_T option,
735 SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
736 VCHIQ_SERVICE_OPTION_T vchiq_option;
738 case VCHI_SERVICE_OPTION_TRACE:
739 vchiq_option = VCHIQ_SERVICE_OPTION_TRACE;
741 case VCHI_SERVICE_OPTION_SYNCHRONOUS:
742 vchiq_option = VCHIQ_SERVICE_OPTION_SYNCHRONOUS;
749 VCHIQ_STATUS_T status =
750 vchiq_set_service_option(service->handle,
754 ret = vchiq_status_to_vchi(status);
758 EXPORT_SYMBOL(vchi_service_set_option);
760 int32_t vchi_get_peer_version( const VCHI_SERVICE_HANDLE_T handle, short *peer_version )
763 SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
766 VCHIQ_STATUS_T status = vchiq_get_peer_version(service->handle, peer_version);
767 ret = vchiq_status_to_vchi( status );
771 EXPORT_SYMBOL(vchi_get_peer_version);
773 /* ----------------------------------------------------------------------
774 * read a uint32_t from buffer.
775 * network format is defined to be little endian
776 * -------------------------------------------------------------------- */
778 vchi_readbuf_uint32(const void *_ptr)
780 const unsigned char *ptr = _ptr;
781 return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24);
784 /* ----------------------------------------------------------------------
785 * write a uint32_t to buffer.
786 * network format is defined to be little endian
787 * -------------------------------------------------------------------- */
789 vchi_writebuf_uint32(void *_ptr, uint32_t value)
791 unsigned char *ptr = _ptr;
792 ptr[0] = (unsigned char)((value >> 0) & 0xFF);
793 ptr[1] = (unsigned char)((value >> 8) & 0xFF);
794 ptr[2] = (unsigned char)((value >> 16) & 0xFF);
795 ptr[3] = (unsigned char)((value >> 24) & 0xFF);
798 /* ----------------------------------------------------------------------
799 * read a uint16_t from buffer.
800 * network format is defined to be little endian
801 * -------------------------------------------------------------------- */
803 vchi_readbuf_uint16(const void *_ptr)
805 const unsigned char *ptr = _ptr;
806 return ptr[0] | (ptr[1] << 8);
809 /* ----------------------------------------------------------------------
810 * write a uint16_t into the buffer.
811 * network format is defined to be little endian
812 * -------------------------------------------------------------------- */
814 vchi_writebuf_uint16(void *_ptr, uint16_t value)
816 unsigned char *ptr = _ptr;
817 ptr[0] = (value >> 0) & 0xFF;
818 ptr[1] = (value >> 8) & 0xFF;
821 /***********************************************************
822 * Name: vchi_service_use
824 * Arguments: const VCHI_SERVICE_HANDLE_T handle
826 * Description: Routine to increment refcount on a service
830 ***********************************************************/
831 int32_t vchi_service_use(const VCHI_SERVICE_HANDLE_T handle)
834 SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
836 ret = vchiq_status_to_vchi(vchiq_use_service(service->handle));
839 EXPORT_SYMBOL(vchi_service_use);
841 /***********************************************************
842 * Name: vchi_service_release
844 * Arguments: const VCHI_SERVICE_HANDLE_T handle
846 * Description: Routine to decrement refcount on a service
850 ***********************************************************/
851 int32_t vchi_service_release(const VCHI_SERVICE_HANDLE_T handle)
854 SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
856 ret = vchiq_status_to_vchi(
857 vchiq_release_service(service->handle));
860 EXPORT_SYMBOL(vchi_service_release);