static ssize_t l2_all_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id)
{
	char buf[64];
	long val;
	int ret;
	u32 l2_id;
	struct mali_l2_cache_core *l2_cache;

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

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

	buf[cnt] = 0;

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

	if (val < 0)
	{
		/* any negative input will disable counter */
		val = MALI_HW_CORE_NO_COUNTER;
	}

	l2_id = 0;
	l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id);
	while (NULL != l2_cache)
	{
		if (0 == src_id)
		{
			if (MALI_TRUE != mali_l2_cache_core_set_counter_src0(l2_cache, (u32)val))
			{
				return 0;
			}
		}
		else
		{
			if (MALI_TRUE != mali_l2_cache_core_set_counter_src1(l2_cache, (u32)val))
			{
				return 0;
			}
		}				
		
		/* try next L2 */
		l2_id++;
		l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id);
	}

	*ppos += cnt;
	return cnt;
}
Exemple #2
0
void mali_l2_cache_pause_all(mali_bool pause)
{
	
	int i;
	struct mali_l2_cache_core * cache;
	u32 num_cores = mali_l2_cache_core_get_glob_num_l2_cores();
	MALI_L2_STATUS status = MALI_L2_NORMAL;

	if (pause)
	{
		status = MALI_L2_PAUSE;
	}

	for (i = 0; i < num_cores; i++)
	{
		cache = mali_l2_cache_core_get_glob_l2_core(i);
		if (NULL != cache)
		{
			_mali_osk_lock_wait(cache->counter_lock, _MALI_OSK_LOCKMODE_RW);
			_mali_osk_lock_wait(cache->command_lock, _MALI_OSK_LOCKMODE_RW);
			cache->mali_l2_status = status;
			_mali_osk_lock_signal(cache->command_lock, _MALI_OSK_LOCKMODE_RW);
			_mali_osk_lock_signal(cache->counter_lock, _MALI_OSK_LOCKMODE_RW);
		}
	}

	/* Change from pause, do the cache invalidation here to prevent any loss of cache
	** operation during the pause period to make sure the SW status is consistent
	** with L2 cache status
	*/
	if(!pause)
	{
		mali_l2_cache_invalidate_all();
	}
}
/**
 * Called by gator.ko to set HW counters
 *
 * @param counter_id The counter ID.
 * @param event_id Event ID that the counter should count (HW counter value from TRM).
 *
 * @return 1 on success, 0 on failure.
 */
int _mali_profiling_set_event(u32 counter_id, s32 event_id)
{
	if (COUNTER_VP_0_C0 == counter_id)
	{
		if (MALI_TRUE == mali_gp_job_set_gp_counter_src0(event_id))
		{
			return 1;
		}
	}

	if (COUNTER_VP_0_C1 == counter_id)
	{
		if (MALI_TRUE == mali_gp_job_set_gp_counter_src1(event_id))
		{
			return 1;
		}
	}

	if (COUNTER_FP_0_C0 == counter_id)
	{
		if (MALI_TRUE == mali_pp_job_set_pp_counter_src0(event_id))
		{
			return 1;
		}
	}

	if (COUNTER_FP_0_C1 == counter_id)
	{
		if (MALI_TRUE == mali_pp_job_set_pp_counter_src1(event_id))
		{
			return 1;
		}
	}

	if (COUNTER_L2_0_C0 <= counter_id && COUNTER_L2_2_C1 >= counter_id)
	{
		u32 core_id = (counter_id - COUNTER_L2_0_C0) >> 1;
		struct mali_l2_cache_core* l2_cache_core = mali_l2_cache_core_get_glob_l2_core(core_id);

		if (NULL != l2_cache_core)
		{
			u32 counter_src = (counter_id - COUNTER_L2_0_C0) & 1;
			if (0 == counter_src)
			{
				if (MALI_TRUE == mali_l2_cache_core_set_counter_src0(l2_cache_core, event_id))
				{
					return 1;
				}
			}
			else
			{
				if (MALI_TRUE == mali_l2_cache_core_set_counter_src1(l2_cache_core, event_id))
				{
					return 1;
				}
			}
		}
	}
Exemple #4
0
void mali_l2_cache_reset_all(void)
{
	int i;
	u32 num_cores = mali_l2_cache_core_get_glob_num_l2_cores();

	for (i = 0; i < num_cores; i++)
	{
		mali_l2_cache_reset(mali_l2_cache_core_get_glob_l2_core(i));
	}
}
Exemple #5
0
static void mali_gp_post_process_job(struct mali_gp_core *core, mali_bool suspend)
{
    MALI_ASSERT_GROUP_LOCKED(core->group);

    if (NULL != core->running_job)
    {
        u32 val0 = 0;
        u32 val1 = 0;
#if MALI_TIMELINE_PROFILING_ENABLED
        u32 event_id;
#endif

#if PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH
        {
            u32 src0, value0, src1, value1, sum, per_thousand, per_thousand_now, diff0, diff1;
            static u32 print_nr=0;
            static u32 prev0=0;
            static u32 prev1=0;
            if ( !(++print_nr&511) )
            {
                mali_l2_cache_core_get_counter_values(mali_l2_cache_core_get_glob_l2_core(0), &src0, &value0, &src1, &value1);
                MALI_DEBUG_ASSERT( src0==20 );
                MALI_DEBUG_ASSERT( src1==21 );

                sum = value0+value1;
                if ( sum > 1000000 )
                {
                    per_thousand = value0 / (sum/1000);
                }
                else
                {
                    per_thousand = (value0*1000) / (sum);
                }
                diff0 = value0-prev0;
                diff1 = value1-prev1;

                sum = diff0 + diff1 ;
                if ( sum > 1000000 )
                {
                    per_thousand_now = diff0 / (sum/1000);
                }
                else
                {
                    per_thousand_now = (diff0*1000) / (sum);
                }

                prev0=value0;
                prev1=value1;
                if (per_thousand_now<=1000)
                {
                    MALI_DEBUG_PRINT(2, ("Mali L2: Read hits/misses:  %d/%d  =  %d thousand_parts total, since previous: %d\n", value0, value1, per_thousand, per_thousand_now));
                }

            }
        }
#endif

        if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used)
        {
            val0 = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE);
            if (mali_gp_job_get_perf_counter_flag(core->running_job) &&
                    _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE && mali_gp_job_get_perf_counter_src0(core->running_job) == core->counter_src0_used)
            {

                mali_gp_job_set_perf_counter_value0(core->running_job, val0);
            }
            else
            {

                mali_gp_job_set_perf_counter_value0(core->running_job, MALI_HW_CORE_INVALID_VALUE);
            }

#if MALI_TIMELINE_PROFILING_ENABLED
            _mali_osk_profiling_report_hw_counter(COUNTER_VP_C0, val0);
#endif

        }

        if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used)
        {
            val1 = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE);
            if (mali_gp_job_get_perf_counter_flag(core->running_job) &&
                    _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE && mali_gp_job_get_perf_counter_src1(core->running_job) == core->counter_src1_used)
            {

                mali_gp_job_set_perf_counter_value1(core->running_job, val1);
            }
            else
            {

                mali_gp_job_set_perf_counter_value1(core->running_job, MALI_HW_CORE_INVALID_VALUE);
            }

#if MALI_TIMELINE_PROFILING_ENABLED
            _mali_osk_profiling_report_hw_counter(COUNTER_VP_C1, val1);
#endif
        }

#if MALI_TIMELINE_PROFILING_ENABLED
        if (MALI_TRUE == suspend)
        {
            event_id = MALI_PROFILING_EVENT_TYPE_SUSPEND|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0);
        }
        else
        {
            event_id = MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0);
        }
        _mali_osk_profiling_add_event(event_id, val0, val1, core->counter_src0_used | (core->counter_src1_used << 8), 0, 0);
#endif

        mali_gp_job_set_current_heap_addr(core->running_job,
                                          mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR));

        if (MALI_TRUE != suspend)
        {

            core->running_job = NULL;
            _mali_osk_timer_del(core->timeout_timer);
        }
    }
}
Exemple #6
0
void mali_gp_job_start(struct mali_gp_core *core, struct mali_gp_job *job)
{
    u32 startcmd = 0;
    u32 *frame_registers = mali_gp_job_get_frame_registers(job);
    core->counter_src0_used = core->counter_src0;
    core->counter_src1_used = core->counter_src1;

    MALI_DEBUG_ASSERT_POINTER(core);
    MALI_ASSERT_GROUP_LOCKED(core->group);

    if (mali_gp_job_has_vs_job(job))
    {
        startcmd |= (u32) MALIGP2_REG_VAL_CMD_START_VS;
    }

    if (mali_gp_job_has_plbu_job(job))
    {
        startcmd |= (u32) MALIGP2_REG_VAL_CMD_START_PLBU;
    }

    MALI_DEBUG_ASSERT(0 != startcmd);

    mali_hw_core_register_write_array_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR, frame_registers, MALIGP2_NUM_REGS_FRAME);

#if PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH
    {

        mali_l2_cache_core_set_counter_src0(mali_l2_cache_core_get_glob_l2_core(0), 20);
        mali_l2_cache_core_set_counter_src1(mali_l2_cache_core_get_glob_l2_core(0), 21);
    }
#endif


    if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used || MALI_HW_CORE_NO_COUNTER != core->counter_src0_used)
    {

        if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used)
        {
            mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used);
            mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE);
        }
        if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used)
        {
            mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used);
            mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE);
        }
    }
    else
    {

        u32 perf_counter_flag = mali_gp_job_get_perf_counter_flag(job);
        if (0 != perf_counter_flag)
        {
            if (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE)
            {
                core->counter_src0_used = mali_gp_job_get_perf_counter_src0(job);
                mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used);
                mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE);
            }

            if (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE)
            {
                core->counter_src1_used = mali_gp_job_get_perf_counter_src1(job);
                mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used);
                mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE);
            }
        }
    }

    MALI_DEBUG_PRINT(3, ("Mali GP: Starting job (0x%08x) on core %s with command 0x%08X\n", job, core->hw_core.description, startcmd));


    _mali_osk_write_mem_barrier();


    mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, startcmd);


    _mali_osk_write_mem_barrier();



    _mali_osk_timer_add(core->timeout_timer, _mali_osk_time_mstoticks(mali_max_job_runtime));
    core->timeout_job_id = mali_gp_job_get_id(job);

#if MALI_TIMELINE_PROFILING_ENABLED
    _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0) | MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH,
                                  job->frame_builder_id, job->flush_id, 0, 0, 0);
    _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0), job->pid, job->tid, 0, 0, 0);
#endif

    core->running_job = job;
}
void mali_gp_job_start(struct mali_gp_core *core, struct mali_gp_job *job)
{
	u32 startcmd = 0;
	u32 *frame_registers = mali_gp_job_get_frame_registers(job);
	core->counter_src0_used = core->counter_src0;
	core->counter_src1_used = core->counter_src1;

	MALI_DEBUG_ASSERT_POINTER(core);
	MALI_ASSERT_GROUP_LOCKED(core->group);

	if (mali_gp_job_has_vs_job(job))
	{
		startcmd |= (u32) MALIGP2_REG_VAL_CMD_START_VS;
	}

	if (mali_gp_job_has_plbu_job(job))
	{
		startcmd |= (u32) MALIGP2_REG_VAL_CMD_START_PLBU;
	}

	MALI_DEBUG_ASSERT(0 != startcmd);

	mali_hw_core_register_write_array_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR, frame_registers, MALIGP2_NUM_REGS_FRAME);

#if PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH
	{
		/* Read hits and Read misses*/
		mali_l2_cache_core_set_counter_src0(mali_l2_cache_core_get_glob_l2_core(0), 20);
		mali_l2_cache_core_set_counter_src1(mali_l2_cache_core_get_glob_l2_core(0), 21);
	}
#endif

	/* This selects which performance counters we are reading */
	if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used || MALI_HW_CORE_NO_COUNTER != core->counter_src0_used)
	{
		/* global_config has enabled HW counters, this will override anything specified by user space */
		if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used)
		{
			mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used);
			mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE);
		}
		if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used)
		{
			mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used);
			mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE);
		}
	}
	else
	{
		/* Use HW counters from job object, if any */
		u32 perf_counter_flag = mali_gp_job_get_perf_counter_flag(job);
		if (0 != perf_counter_flag)
		{
			if (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE)
			{
				core->counter_src0_used = mali_gp_job_get_perf_counter_src0(job);
				mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used);
				mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE);
			}

			if (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE)
			{
				core->counter_src1_used = mali_gp_job_get_perf_counter_src1(job);
				mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used);
				mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE);
			}
		}
	}

	MALI_DEBUG_PRINT(3, ("Mali GP: Starting job (0x%08x) on core %s with command 0x%08X\n", job, core->hw_core.description, startcmd));

	/* Barrier to make sure the previous register write is finished */
	_mali_osk_write_mem_barrier();

	/* This is the command that starts the core. */
	mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, startcmd);

	/* Barrier to make sure the previous register write is finished */
	_mali_osk_write_mem_barrier();

	/* Setup the timeout timer value and save the job id for the job running on the gp core */

	_mali_osk_timer_add(core->timeout_timer, _mali_osk_time_mstoticks(mali_max_job_runtime));
	core->timeout_job_id = mali_gp_job_get_id(job);

#if MALI_TIMELINE_PROFILING_ENABLED
	_mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0) | MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH,
	                              mali_gp_job_get_frame_builder_id(job), mali_gp_job_get_flush_id(job), 0, 0, 0);
	_mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0), mali_gp_job_get_pid(job), mali_gp_job_get_tid(job), 0, 0, 0);
#endif

	core->running_job = job;
}
int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev_name)
{
	int err = 0;

	device->mali_class = class_create(THIS_MODULE, mali_dev_name);
	if (IS_ERR(device->mali_class))
	{
		err = PTR_ERR(device->mali_class);
		goto init_class_err;
	}
	mali_device = device_create(device->mali_class, NULL, dev, NULL, mali_dev_name);
	if (IS_ERR(mali_device))
	{
		err = PTR_ERR(mali_device);
		goto init_mdev_err;
	}

	mali_debugfs_dir = debugfs_create_dir(mali_dev_name, NULL);
	if(ERR_PTR(-ENODEV) == mali_debugfs_dir)
	{
		/* Debugfs not supported. */
		mali_debugfs_dir = NULL;
	}
	else
	{
		if(NULL != mali_debugfs_dir)
		{
			/* Debugfs directory created successfully; create files now */
			struct dentry *mali_power_dir;
			struct dentry *mali_gp_dir;
			struct dentry *mali_pp_dir;
			struct dentry *mali_l2_dir;
#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
			struct dentry *mali_profiling_dir;
#endif

			mali_power_dir = debugfs_create_dir("power", mali_debugfs_dir);
			if (mali_power_dir != NULL)
			{
				debugfs_create_file("power_events", 0400, mali_power_dir, NULL, &power_events_fops);
			}

			mali_gp_dir = debugfs_create_dir("gp", mali_debugfs_dir);
			if (mali_gp_dir != NULL)
			{
				struct dentry *mali_gp_all_dir;
				u32 ci;
				struct mali_cluster *cluster;

				mali_gp_all_dir = debugfs_create_dir("all", mali_gp_dir);
				if (mali_gp_all_dir != NULL)
				{
					debugfs_create_file("counter_src0", 0400, mali_gp_all_dir, NULL, &gp_all_counter_src0_fops);
					debugfs_create_file("counter_src1", 0400, mali_gp_all_dir, NULL, &gp_all_counter_src1_fops);
				}

				ci = 0;
				cluster = mali_cluster_get_global_cluster(ci);
				while (NULL != cluster)
				{
					u32 gi = 0;
					struct mali_group *group = mali_cluster_get_group(cluster, gi);
					while (NULL != group)
					{
						struct mali_gp_core *gp_core = mali_group_get_gp_core(group);
						if (NULL != gp_core)
						{
							struct dentry *mali_gp_gpx_dir;
							mali_gp_gpx_dir = debugfs_create_dir("gp0", mali_gp_dir);
							if (NULL != mali_gp_gpx_dir)
							{
								debugfs_create_file("counter_src0", 0600, mali_gp_gpx_dir, gp_core, &gp_gpx_counter_src0_fops);
								debugfs_create_file("counter_src1", 0600, mali_gp_gpx_dir, gp_core, &gp_gpx_counter_src1_fops);
							}
							break; /* no need to look for any other GP cores */
						}

						/* try next group */
						gi++;
						group = mali_cluster_get_group(cluster, gi);
					}

					/* try next cluster */
					ci++;
					cluster = mali_cluster_get_global_cluster(ci);
				}
			}

			mali_pp_dir = debugfs_create_dir("pp", mali_debugfs_dir);
			if (mali_pp_dir != NULL)
			{
				struct dentry *mali_pp_all_dir;
				u32 ci;
				struct mali_cluster *cluster;

				mali_pp_all_dir = debugfs_create_dir("all", mali_pp_dir);
				if (mali_pp_all_dir != NULL)
				{
					debugfs_create_file("counter_src0", 0400, mali_pp_all_dir, NULL, &pp_all_counter_src0_fops);
					debugfs_create_file("counter_src1", 0400, mali_pp_all_dir, NULL, &pp_all_counter_src1_fops);
				}

				ci = 0;
				cluster = mali_cluster_get_global_cluster(ci);
				while (NULL != cluster)
				{
					u32 gi = 0;
					struct mali_group *group = mali_cluster_get_group(cluster, gi);
					while (NULL != group)
					{
						struct mali_pp_core *pp_core = mali_group_get_pp_core(group);
						if (NULL != pp_core)
						{
							char buf[16];
							struct dentry *mali_pp_ppx_dir;
							_mali_osk_snprintf(buf, sizeof(buf), "pp%u", mali_pp_core_get_id(pp_core));
							mali_pp_ppx_dir = debugfs_create_dir(buf, mali_pp_dir);
							if (NULL != mali_pp_ppx_dir)
							{
								debugfs_create_file("counter_src0", 0600, mali_pp_ppx_dir, pp_core, &pp_ppx_counter_src0_fops);
								debugfs_create_file("counter_src1", 0600, mali_pp_ppx_dir, pp_core, &pp_ppx_counter_src1_fops);
							}
						}

						/* try next group */
						gi++;
						group = mali_cluster_get_group(cluster, gi);
					}

					/* try next cluster */
					ci++;
					cluster = mali_cluster_get_global_cluster(ci);
				}
			}

			mali_l2_dir = debugfs_create_dir("l2", mali_debugfs_dir);
			if (mali_l2_dir != NULL)
			{
				struct dentry *mali_l2_all_dir;
				u32 l2_id;
				struct mali_l2_cache_core *l2_cache;

				mali_l2_all_dir = debugfs_create_dir("all", mali_l2_dir);
				if (mali_l2_all_dir != NULL)
				{
					debugfs_create_file("counter_src0", 0400, mali_l2_all_dir, NULL, &l2_all_counter_src0_fops);
					debugfs_create_file("counter_src1", 0400, mali_l2_all_dir, NULL, &l2_all_counter_src1_fops);
				}

				l2_id = 0;
				l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id);
				while (NULL != l2_cache)
				{
					char buf[16];
					struct dentry *mali_l2_l2x_dir;
					_mali_osk_snprintf(buf, sizeof(buf), "l2%u", l2_id);
					mali_l2_l2x_dir = debugfs_create_dir(buf, mali_l2_dir);
					if (NULL != mali_l2_l2x_dir)
					{
						debugfs_create_file("counter_src0", 0600, mali_l2_l2x_dir, l2_cache, &l2_l2x_counter_src0_fops);
						debugfs_create_file("counter_src1", 0600, mali_l2_l2x_dir, l2_cache, &l2_l2x_counter_src1_fops);
					}
					
					/* try next L2 */
					l2_id++;
					l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id);
				}
			}

			debugfs_create_file("memory_usage", 0400, mali_debugfs_dir, NULL, &memory_usage_fops);

#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
			mali_profiling_dir = debugfs_create_dir("profiling", mali_debugfs_dir);
			if (mali_profiling_dir != NULL)
			{
				struct dentry *mali_profiling_proc_dir = debugfs_create_dir("proc", mali_profiling_dir);
				if (mali_profiling_proc_dir != NULL)
				{
					struct dentry *mali_profiling_proc_default_dir = debugfs_create_dir("default", mali_profiling_proc_dir);
					if (mali_profiling_proc_default_dir != NULL)
					{
						debugfs_create_file("enable", 0600, mali_profiling_proc_default_dir, (void*)_MALI_UK_USER_SETTING_SW_EVENTS_ENABLE, &user_settings_fops);
					}
				}
				debugfs_create_file("record", 0600, mali_profiling_dir, NULL, &profiling_record_fops);
				debugfs_create_file("events", 0400, mali_profiling_dir, NULL, &profiling_events_fops);
			}
#endif

#if MALI_STATE_TRACKING
			debugfs_create_file("state_dump", 0400, mali_debugfs_dir, NULL, &mali_seq_internal_state_fops);
#endif

			if (mali_sysfs_user_settings_register())
			{
				/* Failed to create the debugfs entries for the user settings DB. */
				MALI_DEBUG_PRINT(2, ("Failed to create user setting debugfs files. Ignoring...\n"));
			}
		}
	}

	/* Success! */
	return 0;

	/* Error handling */
init_mdev_err:
	class_destroy(device->mali_class);
init_class_err:

	return err;
}