/*********************************************************** * Name: vc_dispmanx_stop * * Arguments: * - * * Description: Stops the Host side part of dispmanx * * Returns: - * ***********************************************************/ VCHPRE_ void VCHPOST_ vc_dispmanx_stop( void ) { // Wait for the current lock-holder to finish before zapping dispmanx. //TODO: kill the notifier task void *dummy; uint32_t i; if (!dispmanx_client.initialised) return; lock_obtain(); for (i=0; i<dispmanx_client.num_connections; i++) { int32_t result; result = vchi_service_close(dispmanx_client.client_handle[i]); vcos_assert( result == 0 ); result = vchi_service_close(dispmanx_client.notify_handle[i]); vcos_assert( result == 0 ); } lock_release(); dispmanx_client.initialised = 0; vcos_event_signal(&dispmanx_notify_available_event); vcos_thread_join(&dispmanx_notify_task, &dummy); vcos_mutex_delete(&dispmanx_client.lock); vcos_event_delete(&dispmanx_message_available_event); vcos_event_delete(&dispmanx_notify_available_event); }
/*********************************************************** * Name: vc_vchi_cec_stop * * Arguments: * - * * Description: Stops the Host side part of CEC service * * Returns: - * ***********************************************************/ VCHPRE_ void VCHPOST_ vc_vchi_cec_stop( void ) { // Wait for the current lock-holder to finish before zapping TV service uint32_t i; lock_obtain(); //TODO: there is no API to stop the notifier task at the moment for (i=0; i < cecservice_client.num_connections; i++) { int32_t result; result = vchi_service_close(cecservice_client.client_handle[i]); assert( result == 0 ); result = vchi_service_close(cecservice_client.notify_handle[i]); assert( result == 0 ); } cecservice_client.initialised = 0; lock_release(); }
void vc_gencmd_stop () { // Assume a "power down" gencmd has been sent and the lock is held. There will // be no response so this should be called instead. int32_t success,i; if (!gencmd_client.initialised) return; if(lock_obtain() == 0) { use_gencmd_service(); for(i = 0; i< (int32_t)gencmd_client.num_connections; i++) { success = vchi_service_close( gencmd_client.open_handle[i]); assert(success == 0); } gencmd_client.initialised = 0; lock_release(); vcos_mutex_delete(&gencmd_client.lock); vcos_event_delete(&gencmd_client.message_available_event); } }
void vc_gencmd_stop () { // Assume a "power down" gencmd has been sent and the lock is held. There will // be no response so this should be called instead. int32_t success,i; for(i = 0; i< (int32_t)gencmd_client.num_connections; i++) { success = vchi_service_close( gencmd_client.open_handle[i]); assert(success == 0); } }
void vc_gpuserv_deinit( void ) { vcos_mutex_lock(&gpuserv_client.lock); if (gpuserv_client.refcount > 0 && --gpuserv_client.refcount == 0) { vchi_service_close(gpuserv_client.service); gpuserv_client.service = 0; } vcos_mutex_unlock(&gpuserv_client.lock); }
void vc_hostreq_stop () { // Don't want anyone to be using this when we zap it. int i, success; lock_obtain(); for(i = 0; i < hostreq_client.num_connections; i++) { success = vchi_service_close(hostreq_client.client_handle[i]); assert(success == 0); } lock_release(); memset(&hostreq_client, 0, sizeof(hostreq_client)); }
static void bcm2835_audio_release(struct bcm2835_audio_info *sc) { int success; if (sc->vchi_handle != VCHIQ_SERVICE_HANDLE_INVALID) { vchi_service_use(sc->vchi_handle); success = vchi_service_close(sc->vchi_handle); if (success != 0) printf("vchi_service_close failed: %d\n", success); sc->vchi_handle = VCHIQ_SERVICE_HANDLE_INVALID; } vchi_disconnect(sc->vchi_instance); }
static int32_t vc_vchi_audio_deinit(AUDIO_INSTANCE_T * instance) { uint32_t i; LOG_DBG(" .. IN\n"); if (instance == NULL) { LOG_ERR("%s: invalid handle %p\n", __func__, instance); return -1; } LOG_DBG(" .. about to lock (%d)\n", instance->num_connections); if(mutex_lock_interruptible(&instance->vchi_mutex)) { LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",instance->num_connections); return -EINTR; } /* Close all VCHI service connections */ for (i = 0; i < instance->num_connections; i++) { int32_t success; LOG_DBG(" .. %i:closing %p\n", i, instance->vchi_handle[i]); vchi_service_use(instance->vchi_handle[i]); success = vchi_service_close(instance->vchi_handle[i]); if (success != 0) { LOG_DBG ("%s: failed to close VCHI service connection (status=%d)\n", __func__, success); } } mutex_unlock(&instance->vchi_mutex); kfree(instance); LOG_DBG(" .. OUT\n"); return 0; }
int32_t vc_vchi_fb_stop(VC_VCHI_FB_HANDLE_T * handle) { FB_INSTANCE_T *instance; uint32_t i; if (handle == NULL) { LOG_ERR("%s: invalid pointer to handle %p", __func__, handle); return -1; } if (*handle == NULL) { LOG_ERR("%s: invalid handle %p", __func__, *handle); return -1; } instance = *handle; mutex_lock(&instance->vchi_mutex); /* Close all VCHI service connections */ for (i = 0; i < instance->num_connections; i++) { int32_t success; vchi_service_use(instance->vchi_handle[i]); success = vchi_service_close(instance->vchi_handle[i]); } mutex_unlock(&instance->vchi_mutex); kfree(instance); /* NULLify the handle to prevent the user from using it */ *handle = NULL; return 0; }
VC_VCHI_FB_HANDLE_T vc_vchi_fb_init(VCHI_INSTANCE_T vchi_instance, VCHI_CONNECTION_T ** vchi_connections, uint32_t num_connections) { uint32_t i; FB_INSTANCE_T *instance; int32_t status; LOG_DBG("%s: start", __func__); if (num_connections > VCHI_MAX_NUM_CONNECTIONS) { LOG_ERR("%s: unsupported number of connections %u (max=%u)", __func__, num_connections, VCHI_MAX_NUM_CONNECTIONS); return NULL; } /* Allocate memory for this instance */ instance = kzalloc(sizeof(*instance), GFP_KERNEL); memset(instance, 0, sizeof(*instance)); instance->num_connections = num_connections; /* Create the message available semaphore */ sema_init(&instance->msg_avail, 0); /* Create a lock for exclusive, serialized VCHI connection access */ mutex_init(&instance->vchi_mutex); /* Open the VCHI service connections */ for (i = 0; i < num_connections; i++) { SERVICE_CREATION_T params = { VCHI_VERSION_EX(VC_FB_VER, VC_FB_VER_MIN), VC_FB_SERVER_NAME, vchi_connections[i], 0, 0, fb_vchi_callback, instance, 0, 0, 0 }; status = vchi_service_open(vchi_instance, ¶ms, &instance->vchi_handle[i]); if (status) { LOG_ERR ("%s: failed to open VCHI service (%d)", __func__, status); goto err_close_services; } /* Finished with the service for now */ vchi_service_release(instance->vchi_handle[i]); } return instance; err_close_services: for (i = 0; i < instance->num_connections; i++) vchi_service_close(instance->vchi_handle[i]); kfree(instance); return NULL; }
static AUDIO_INSTANCE_T *vc_vchi_audio_init(VCHI_INSTANCE_T vchi_instance, VCHI_CONNECTION_T ** vchi_connections, uint32_t num_connections) { uint32_t i; AUDIO_INSTANCE_T *instance; int status; LOG_DBG("%s: start", __func__); if (num_connections > VCHI_MAX_NUM_CONNECTIONS) { LOG_ERR("%s: unsupported number of connections %u (max=%u)\n", __func__, num_connections, VCHI_MAX_NUM_CONNECTIONS); return NULL; } /* Allocate memory for this instance */ instance = kmalloc(sizeof(*instance), GFP_KERNEL); if (!instance) return NULL; memset(instance, 0, sizeof(*instance)); instance->num_connections = num_connections; /* Create a lock for exclusive, serialized VCHI connection access */ mutex_init(&instance->vchi_mutex); /* Open the VCHI service connections */ for (i = 0; i < num_connections; i++) { SERVICE_CREATION_T params = { VCHI_VERSION_EX(VC_AUDIOSERV_VER, VC_AUDIOSERV_MIN_VER), VC_AUDIO_SERVER_NAME, // 4cc service code vchi_connections[i], // passed in fn pointers 0, // rx fifo size (unused) 0, // tx fifo size (unused) audio_vchi_callback, // service callback instance, // service callback parameter 1, //TODO: remove VCOS_FALSE, // unaligned bulk recieves 1, //TODO: remove VCOS_FALSE, // unaligned bulk transmits 0 // want crc check on bulk transfers }; LOG_DBG("%s: about to open %i\n", __func__, i); status = vchi_service_open(vchi_instance, ¶ms, &instance->vchi_handle[i]); LOG_DBG("%s: opened %i: %p=%d\n", __func__, i, instance->vchi_handle[i], status); if (status) { LOG_ERR ("%s: failed to open VCHI service connection (status=%d)\n", __func__, status); goto err_close_services; } /* Finished with the service for now */ vchi_service_release(instance->vchi_handle[i]); } LOG_DBG("%s: okay\n", __func__); return instance; err_close_services: for (i = 0; i < instance->num_connections; i++) { LOG_ERR("%s: closing %i: %p\n", __func__, i, instance->vchi_handle[i]); if (instance->vchi_handle[i]) vchi_service_close(instance->vchi_handle[i]); } kfree(instance); LOG_ERR("%s: error\n", __func__); return NULL; }