void malipmm_kernel_subsystem_terminate( mali_kernel_subsystem_identifier id ) { /* Check this is the right system */ MALI_DEBUG_ASSERT( id == mali_subsystem_pmm_id ); MALI_DEBUG_ASSERT_POINTER(pmm_state); if( pmm_state ) { _mali_osk_resource_type_t t = PMU; #if PMM_OS_TEST power_test_end(); #endif /* Get the lock so we can shutdown */ MALI_PMM_LOCK(pmm_state); pmm_state->status = MALI_PMM_STATUS_OFF; MALI_PMM_UNLOCK(pmm_state); pmm_policy_term(pmm_state); _mali_osk_irq_term( pmm_state->irq ); #ifdef CONFIG_SMP _mali_osk_lock_term(mali_pmm_lock); #endif /* CONFIG_SMP */ _mali_osk_notification_queue_term( pmm_state->queue ); _mali_osk_notification_queue_term( pmm_state->iqueue ); if( pmm_state->pmu_initialized ) mali_platform_deinit(&t); _mali_osk_atomic_term( &(pmm_state->messages_queued) ); MALI_PMM_LOCK_TERM(pmm_state); _mali_osk_free(pmm_state); pmm_state = NULL; } MALIPMM_DEBUG_PRINT( ("PMM: subsystem terminated\n") ); }
_mali_osk_errcode_t _mali_ukk_close(void **context) { int i; struct mali_session_data * session_data; MALI_CHECK_NON_NULL(context, _MALI_OSK_ERR_INVALID_ARGS); session_data = (struct mali_session_data *)*context; MALI_DEBUG_PRINT(2, ("Session ending\n")); /* end subsystem sessions in the reverse order they where started in */ for (i = SUBSYSTEMS_COUNT - 1; i >= 0; --i) { if (NULL != subsystems[i]->session_end) subsystems[i]->session_end(session_data, &session_data->subsystem_data[i]); } _mali_osk_notification_queue_term(session_data->ioctl_queue); _mali_osk_free(session_data); *context = NULL; MALI_DEBUG_PRINT(2, ("Session has ended\n")); MALI_SUCCESS; }
void malipmm_kernel_subsystem_terminate( mali_kernel_subsystem_identifier id ) { /* Check this is the right system */ MALI_DEBUG_ASSERT( id == mali_subsystem_pmm_id ); MALI_DEBUG_ASSERT_POINTER(pmm_state); if( pmm_state ) { #if PMM_OS_TEST power_test_end(); #endif /* Get the lock so we can shutdown */ MALI_PMM_LOCK(pmm_state); #if MALI_STATE_TRACKING pmm_state->mali_pmm_lock_acquired = 1; #endif /* MALI_STATE_TRACKING */ pmm_state->status = MALI_PMM_STATUS_OFF; #if MALI_STATE_TRACKING pmm_state->mali_pmm_lock_acquired = 0; #endif /* MALI_STATE_TRACKING */ MALI_PMM_UNLOCK(pmm_state); _mali_osk_pmm_ospmm_cleanup(); pmm_policy_term(pmm_state); _mali_osk_irq_term( pmm_state->irq ); _mali_osk_notification_queue_term( pmm_state->queue ); _mali_osk_notification_queue_term( pmm_state->iqueue ); if (pmm_state->cores_registered) malipmm_powerdown(pmm_state->cores_registered,MALI_POWER_MODE_LIGHT_SLEEP); #if USING_MALI_PMU if( pmm_state->pmu_initialized ) { _mali_osk_resource_type_t t = PMU; mali_pmm_pmu_deinit(&t); } #endif /* USING_MALI_PMU */ _mali_osk_atomic_term( &(pmm_state->messages_queued) ); MALI_PMM_LOCK_TERM(pmm_state); _mali_osk_free(pmm_state); pmm_state = NULL; } MALIPMM_DEBUG_PRINT( ("PMM: subsystem terminated\n") ); }
_mali_osk_errcode_t _mali_ukk_open(void **context) { int i; _mali_osk_errcode_t err; struct mali_session_data * session_data; /* allocated struct to track this session */ session_data = (struct mali_session_data *)_mali_osk_malloc(sizeof(struct mali_session_data)); MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_NOMEM); _mali_osk_memset(session_data->subsystem_data, 0, sizeof(session_data->subsystem_data)); /* create a response queue for this session */ session_data->ioctl_queue = _mali_osk_notification_queue_init(); if (NULL == session_data->ioctl_queue) { _mali_osk_free(session_data); MALI_ERROR(_MALI_OSK_ERR_NOMEM); } MALI_DEBUG_PRINT(3, ("Session starting\n")); /* call session_begin on all subsystems */ for (i = 0; i < (int)SUBSYSTEMS_COUNT; ++i) { if (NULL != subsystems[i]->session_begin) { /* subsystem has a session_begin */ err = subsystems[i]->session_begin(session_data, &session_data->subsystem_data[i], session_data->ioctl_queue); MALI_CHECK_GOTO(err == _MALI_OSK_ERR_OK, cleanup); } } *context = (void*)session_data; MALI_DEBUG_PRINT(3, ("Session started\n")); MALI_SUCCESS; cleanup: MALI_DEBUG_PRINT(2, ("Session startup failed\n")); /* i is index of subsystem which failed session begin, all indices before that has to be ended */ /* end subsystem sessions in the reverse order they where started in */ for (i = i - 1; i >= 0; --i) { if (NULL != subsystems[i]->session_end) subsystems[i]->session_end(session_data, &session_data->subsystem_data[i]); } _mali_osk_notification_queue_term(session_data->ioctl_queue); _mali_osk_free(session_data); /* return what the subsystem which failed session start returned */ MALI_ERROR(err); }
_mali_osk_errcode_t _mali_ukk_close(void **context) { int i; #ifdef MALI_SESSION_MEMORY_USAGE struct mali_session_data_list * session_data_list; #endif struct mali_session_data * session_data; MALI_CHECK_NON_NULL(context, _MALI_OSK_ERR_INVALID_ARGS); session_data = (struct mali_session_data *)*context; #ifdef MALI_SESSION_MEMORY_USAGE session_data_list = (struct mali_session_data_list *)session_data->list; #endif MALI_DEBUG_PRINT(2, ("Session ending\n")); /* end subsystem sessions in the reverse order they where started in */ for (i = SUBSYSTEMS_COUNT - 1; i >= 0; --i) { if (NULL != subsystems[i]->session_end) subsystems[i]->session_end(session_data, &session_data->subsystem_data[i]); } _mali_osk_notification_queue_term(session_data->ioctl_queue); _mali_osk_free(session_data); #ifdef MALI_SESSION_MEMORY_USAGE _mali_osk_lock_wait( session_data_lock, _MALI_OSK_LOCKMODE_RW ); _mali_osk_list_del(&session_data_list->list_head); _mali_osk_lock_signal( session_data_lock, _MALI_OSK_LOCKMODE_RW ); _mali_osk_free(session_data_list); #endif *context = NULL; MALI_DEBUG_PRINT(2, ("Session has ended\n")); MALI_SUCCESS; }
_mali_osk_errcode_t malipmm_create(_mali_osk_resource_t *resource) { /* Create PMM state memory */ MALI_DEBUG_ASSERT( pmm_state == NULL ); pmm_state = (_mali_pmm_internal_state_t *) _mali_osk_malloc(sizeof(*pmm_state)); MALI_CHECK_NON_NULL( pmm_state, _MALI_OSK_ERR_NOMEM ); /* All values get 0 as default */ _mali_osk_memset(pmm_state, 0, sizeof(*pmm_state)); /* Set up the initial PMM state */ pmm_state->waiting = 0; pmm_state->status = MALI_PMM_STATUS_IDLE; pmm_state->state = MALI_PMM_STATE_UNAVAILABLE; /* Until a core registers */ /* Set up policy via compile time option for the moment */ #if MALI_PMM_ALWAYS_ON pmm_state->policy = MALI_PMM_POLICY_ALWAYS_ON; #else pmm_state->policy = MALI_PMM_POLICY_JOB_CONTROL; #endif #if MALI_PMM_TRACE _mali_pmm_trace_policy_change( MALI_PMM_POLICY_NONE, pmm_state->policy ); #endif /* Set up assumes all values are initialized to NULL or MALI_FALSE, so * we can exit halfway through set up and perform clean up */ #if !MALI_PMM_NO_PMU if( mali_platform_init(resource) != _MALI_OSK_ERR_OK ) goto pmm_fail_cleanup; pmm_state->pmu_initialized = MALI_TRUE; #endif pmm_state->queue = _mali_osk_notification_queue_init(); if( !pmm_state->queue ) goto pmm_fail_cleanup; pmm_state->iqueue = _mali_osk_notification_queue_init(); if( !pmm_state->iqueue ) goto pmm_fail_cleanup; /* We are creating an IRQ handler just for the worker thread it gives us */ pmm_state->irq = _mali_osk_irq_init( _MALI_OSK_IRQ_NUMBER_PMM, malipmm_irq_uhandler, malipmm_irq_bhandler, NULL, NULL, (void *)pmm_state, /* PMM state is passed to IRQ */ "PMM handler" ); if( !pmm_state->irq ) goto pmm_fail_cleanup; #ifdef CONFIG_SMP mali_pmm_lock = _mali_osk_lock_init((_mali_osk_lock_flags_t)( _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_ORDERED), 0, 0); if( !mali_pmm_lock ) goto pmm_fail_cleanup; #endif /* CONFIG_SMP */ pmm_state->lock = _mali_osk_lock_init((_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_ORDERED), 0, 75); if( !pmm_state->lock ) goto pmm_fail_cleanup; if( _mali_osk_atomic_init( &(pmm_state->messages_queued), 0 ) != _MALI_OSK_ERR_OK ) { goto pmm_fail_cleanup; } MALIPMM_DEBUG_PRINT( ("PMM: subsystem created, policy=%d\n", pmm_state->policy) ); MALI_SUCCESS; pmm_fail_cleanup: MALI_PRINT_ERROR( ("PMM: subsystem failed to be created\n") ); if( pmm_state ) { _mali_osk_resource_type_t t = PMU; if( pmm_state->lock ) _mali_osk_lock_term( pmm_state->lock ); if( pmm_state->irq ) _mali_osk_irq_term( pmm_state->irq ); if( pmm_state->queue ) _mali_osk_notification_queue_term( pmm_state->queue ); if( pmm_state->iqueue ) _mali_osk_notification_queue_term( pmm_state->iqueue ); if( pmm_state->pmu_initialized ) ( mali_platform_deinit(&t) ); _mali_osk_free(pmm_state); pmm_state = NULL; } MALI_ERROR( _MALI_OSK_ERR_FAULT ); }
_mali_osk_errcode_t _mali_ukk_open(void **context) { int i; _mali_osk_errcode_t err; #ifdef MALI_SESSION_MEMORY_USAGE struct mali_session_data_list * session_data_list; #endif struct mali_session_data * session_data; /* allocated struct to track this session */ session_data = (struct mali_session_data *)_mali_osk_malloc(sizeof(struct mali_session_data)); MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_NOMEM); #ifdef MALI_SESSION_MEMORY_USAGE session_data_list = (struct mali_session_data_list *)_mali_osk_malloc(sizeof(struct mali_session_data_list)); if (session_data_list == NULL) { _mali_osk_free(session_data); return _MALI_OSK_ERR_NOMEM; } _MALI_OSK_INIT_LIST_HEAD(&session_data_list->list_head); session_data_list->pid = _mali_osk_get_pid(); session_data_list->session_data = session_data; session_data->list = session_data_list; #endif _mali_osk_memset(session_data->subsystem_data, 0, sizeof(session_data->subsystem_data)); /* create a response queue for this session */ session_data->ioctl_queue = _mali_osk_notification_queue_init(); if (NULL == session_data->ioctl_queue) { _mali_osk_free(session_data); #ifdef MALI_SESSION_MEMORY_USAGE _mali_osk_free(session_data_list); #endif MALI_ERROR(_MALI_OSK_ERR_NOMEM); } MALI_DEBUG_PRINT(3, ("Session starting\n")); /* call session_begin on all subsystems */ for (i = 0; i < (int)SUBSYSTEMS_COUNT; ++i) { if (NULL != subsystems[i]->session_begin) { /* subsystem has a session_begin */ err = subsystems[i]->session_begin(session_data, &session_data->subsystem_data[i], session_data->ioctl_queue); MALI_CHECK_GOTO(err == _MALI_OSK_ERR_OK, cleanup); } } *context = (void*)session_data; #ifdef MALI_SESSION_MEMORY_USAGE _mali_osk_lock_wait( session_data_lock, _MALI_OSK_LOCKMODE_RW ); _mali_osk_list_addtail(&session_data_list->list_head, &session_data_head); _mali_osk_lock_signal( session_data_lock, _MALI_OSK_LOCKMODE_RW ); #endif MALI_DEBUG_PRINT(3, ("Session started\n")); MALI_SUCCESS; cleanup: MALI_DEBUG_PRINT(2, ("Session startup failed\n")); /* i is index of subsystem which failed session begin, all indices before that has to be ended */ /* end subsystem sessions in the reverse order they where started in */ for (i = i - 1; i >= 0; --i) { if (NULL != subsystems[i]->session_end) subsystems[i]->session_end(session_data, &session_data->subsystem_data[i]); } _mali_osk_notification_queue_term(session_data->ioctl_queue); _mali_osk_free(session_data); #ifdef MALI_SESSION_MEMORY_USAGE _mali_osk_free(session_data_list); #endif /* return what the subsystem which failed session start returned */ MALI_ERROR(err); }