void kbasep_js_devdata_term( kbase_device *kbdev )
{
	kbasep_js_device_data *js_devdata;

	OSK_ASSERT( kbdev != NULL );

	js_devdata = &kbdev->js_data;

	if ( (js_devdata->init_status & JS_DEVDATA_INIT_CONSTANTS) )
	{
		/* The caller must de-register all contexts before calling this */
		OSK_ASSERT( js_devdata->nr_contexts_running == 0 );
		OSK_ASSERT( js_devdata->runpool_irq.nr_nss_ctxs_running == 0 );
	}
	if ( (js_devdata->init_status & JS_DEVDATA_INIT_POLICY) )
	{
		kbasep_js_policy_term( &js_devdata->policy );
	}
	if ( (js_devdata->init_status & JS_DEVDATA_INIT_RUNPOOL_IRQ_LOCK) )
	{
		osk_spinlock_irq_term( &js_devdata->runpool_irq.lock );
	}
	if ( (js_devdata->init_status & JS_DEVDATA_INIT_QUEUE_MUTEX) )
	{
		osk_mutex_term( &js_devdata->queue_mutex );
	}
	if ( (js_devdata->init_status & JS_DEVDATA_INIT_RUNPOOL_MUTEX) )
	{
		osk_mutex_term( &js_devdata->runpool_mutex );
	}

	js_devdata->init_status = JS_DEVDATA_INIT_NONE;
}
mali_error kbasep_pm_metrics_init(kbase_device *kbdev)
{
	osk_error osk_err;
	mali_error ret;

	OSK_ASSERT(kbdev != NULL);

	kbdev->pm.metrics.vsync_hit = 0;
	kbdev->pm.metrics.utilisation = 0;

	kbdev->pm.metrics.time_period_start = osk_time_now();
	kbdev->pm.metrics.time_busy = 0;
	kbdev->pm.metrics.time_idle = 0;
	kbdev->pm.metrics.gpu_active = MALI_TRUE;
	kbdev->pm.metrics.timer_active = MALI_TRUE;
#ifdef CONFIG_VITHAR_RT_PM
	kbdev->pm.cmu_pmu_status = 0;
#endif

	osk_err = osk_spinlock_irq_init(&kbdev->pm.metrics.lock, OSK_LOCK_ORDER_PM_METRICS);
	if (OSK_ERR_NONE != osk_err)
	{
		ret = MALI_ERROR_FUNCTION_FAILED;
		goto out;
	}

	osk_err = osk_timer_init(&kbdev->pm.metrics.timer);
	if (OSK_ERR_NONE != osk_err)
	{
		ret = MALI_ERROR_FUNCTION_FAILED;
		goto spinlock_free;
	}
	osk_timer_callback_set(&kbdev->pm.metrics.timer, dvfs_callback, kbdev);
	osk_err = osk_timer_start(&kbdev->pm.metrics.timer, KBASE_PM_DVFS_FREQUENCY);
	if (OSK_ERR_NONE != osk_err)
	{
		ret = MALI_ERROR_FUNCTION_FAILED;
		goto timer_free;
	}

	kbase_pm_register_vsync_callback(kbdev);
	ret = MALI_ERROR_NONE;
	goto out;

timer_free:
	osk_timer_stop(&kbdev->pm.metrics.timer);
	osk_timer_term(&kbdev->pm.metrics.timer);
spinlock_free:
	osk_spinlock_irq_term(&kbdev->pm.metrics.lock);
out:
	return ret;
}
void kbasep_pm_metrics_term(kbase_device *kbdev)
{
	OSK_ASSERT(kbdev != NULL);

	osk_spinlock_irq_lock(&kbdev->pm.metrics.lock);
	kbdev->pm.metrics.timer_active = MALI_FALSE;
	osk_spinlock_irq_unlock(&kbdev->pm.metrics.lock);

	osk_timer_stop(&kbdev->pm.metrics.timer);
	osk_timer_term(&kbdev->pm.metrics.timer);

	kbase_pm_unregister_vsync_callback(kbdev);

	osk_spinlock_irq_term(&kbdev->pm.metrics.lock);
}