_mali_osk_errcode_t _mali_osk_profiling_init(mali_bool auto_start)
{
    profile_entries = NULL;
    profile_entry_count = 0;
    _mali_osk_atomic_init(&profile_insert_index, 0);
    _mali_osk_atomic_init(&profile_entries_written, 0);

    lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_PROFILING);
    if (NULL == lock)
    {
        return _MALI_OSK_ERR_FAULT;
    }

    prof_state = MALI_PROFILING_STATE_IDLE;

    if (MALI_TRUE == auto_start)
    {
        u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* Use maximum buffer size */

        mali_set_user_setting(_MALI_UK_USER_SETTING_SW_EVENTS_ENABLE, MALI_TRUE);
        if (_MALI_OSK_ERR_OK != _mali_osk_profiling_start(&limit))
        {
            return _MALI_OSK_ERR_FAULT;
        }
    }

    return _MALI_OSK_ERR_OK;
}
_mali_osk_errcode_t _mali_osk_profiling_init(mali_bool auto_start)
{
	profile_entries = NULL;
	profile_entry_count = 0;
	_mali_osk_atomic_init(&profile_insert_index, 0);
	_mali_osk_atomic_init(&profile_entries_written, 0);

	lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, 0 );
	if (NULL == lock)
	{
		return _MALI_OSK_ERR_FAULT;
	}

	prof_state = MALI_PROFILING_STATE_IDLE;

	if (MALI_TRUE == auto_start)
	{
		u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* Use maximum buffer size */

		mali_profiling_default_enable = MALI_TRUE; /* save this so user space can query this on their startup */
		if (_MALI_OSK_ERR_OK != _mali_osk_profiling_start(&limit))
		{
			return _MALI_OSK_ERR_FAULT;
		}
	}

	return _MALI_OSK_ERR_OK;
}
_mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args)
{
	return _mali_osk_profiling_start(&args->limit);
}
static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
{
	char buf[64];
	unsigned long val;
	int ret;

	if (cnt >= sizeof(buf))
	{
		return -EINVAL;
	}

	if (copy_from_user(&buf, ubuf, cnt))
	{
		return -EFAULT;
	}

	buf[cnt] = 0;

	ret = strict_strtoul(buf, 10, &val);
	if (ret < 0)
	{
		return ret;
	}

	if (val != 0)
	{
		u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* This can be made configurable at a later stage if we need to */

		/* check if we are already recording */
		if (MALI_TRUE == _mali_osk_profiling_is_recording())
		{
			MALI_DEBUG_PRINT(3, ("Recording of profiling events already in progress\n"));
			return -EFAULT;
		}

		/* check if we need to clear out an old recording first */
		if (MALI_TRUE == _mali_osk_profiling_have_recording())
		{
			if (_MALI_OSK_ERR_OK != _mali_osk_profiling_clear())
			{
				MALI_DEBUG_PRINT(3, ("Failed to clear existing recording of profiling events\n"));
				return -EFAULT;
			}
		}

		/* start recording profiling data */
		if (_MALI_OSK_ERR_OK != _mali_osk_profiling_start(&limit))
		{
			MALI_DEBUG_PRINT(3, ("Failed to start recording of profiling events\n"));
			return -EFAULT;
		}

		MALI_DEBUG_PRINT(3, ("Profiling recording started (max %u events)\n", limit));
	}
	else
	{
		/* stop recording profiling data */
		u32 count = 0;
		if (_MALI_OSK_ERR_OK != _mali_osk_profiling_stop(&count))
		{
			MALI_DEBUG_PRINT(2, ("Failed to stop recording of profiling events\n"));
			return -EFAULT;
		}
		
		MALI_DEBUG_PRINT(2, ("Profiling recording stopped (recorded %u events)\n", count));
	}

	*ppos += cnt;
	return cnt;
}