brintos

brintos / linux-shallow public Read only

0
0
Text · 17.8 KiB · c8241f5 Raw
711 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* Copyright (c) 2023 Intel Corporation. */3#define dev_fmt(fmt) "Telemetry debugfs: " fmt4 5#include <linux/atomic.h>6#include <linux/debugfs.h>7#include <linux/dev_printk.h>8#include <linux/dcache.h>9#include <linux/file.h>10#include <linux/kernel.h>11#include <linux/math64.h>12#include <linux/mutex.h>13#include <linux/seq_file.h>14#include <linux/slab.h>15#include <linux/units.h>16 17#include "adf_accel_devices.h"18#include "adf_cfg_strings.h"19#include "adf_telemetry.h"20#include "adf_tl_debugfs.h"21 22#define TL_VALUE_MIN_PADDING	2023#define TL_KEY_MIN_PADDING	2324#define TL_RP_SRV_UNKNOWN	"Unknown"25 26static int tl_collect_values_u32(struct adf_telemetry *telemetry,27				 size_t counter_offset, u64 *arr)28{29	unsigned int samples, hb_idx, i;30	u32 *regs_hist_buff;31	u32 counter_val;32 33	samples = min(telemetry->msg_cnt, telemetry->hbuffs);34	hb_idx = telemetry->hb_num + telemetry->hbuffs - samples;35 36	mutex_lock(&telemetry->regs_hist_lock);37 38	for (i = 0; i < samples; i++) {39		regs_hist_buff = telemetry->regs_hist_buff[hb_idx % telemetry->hbuffs];40		counter_val = regs_hist_buff[counter_offset / sizeof(counter_val)];41		arr[i] = counter_val;42		hb_idx++;43	}44 45	mutex_unlock(&telemetry->regs_hist_lock);46 47	return samples;48}49 50static int tl_collect_values_u64(struct adf_telemetry *telemetry,51				 size_t counter_offset, u64 *arr)52{53	unsigned int samples, hb_idx, i;54	u64 *regs_hist_buff;55	u64 counter_val;56 57	samples = min(telemetry->msg_cnt, telemetry->hbuffs);58	hb_idx = telemetry->hb_num + telemetry->hbuffs - samples;59 60	mutex_lock(&telemetry->regs_hist_lock);61 62	for (i = 0; i < samples; i++) {63		regs_hist_buff = telemetry->regs_hist_buff[hb_idx % telemetry->hbuffs];64		counter_val = regs_hist_buff[counter_offset / sizeof(counter_val)];65		arr[i] = counter_val;66		hb_idx++;67	}68 69	mutex_unlock(&telemetry->regs_hist_lock);70 71	return samples;72}73 74/**75 * avg_array() - Return average of values within an array.76 * @array: Array of values.77 * @len: Number of elements.78 *79 * This algorithm computes average of an array without running into overflow.80 *81 * Return: average of values.82 */83#define avg_array(array, len) (				\84{							\85	typeof(&(array)[0]) _array = (array);		\86	__unqual_scalar_typeof(_array[0]) _x = 0;	\87	__unqual_scalar_typeof(_array[0]) _y = 0;	\88	__unqual_scalar_typeof(_array[0]) _a, _b;	\89	typeof(len) _len = (len);			\90	size_t _i;					\91							\92	for (_i = 0; _i < _len; _i++) {			\93		_a = _array[_i];			\94		_b = do_div(_a, _len);			\95		_x += _a;				\96		if (_y >= _len - _b) {			\97			_x++;				\98			_y -= _len - _b;		\99		} else {				\100			_y += _b;			\101		}					\102	}						\103	do_div(_y, _len);				\104	(_x + _y);					\105})106 107/* Calculation function for simple counter. */108static int tl_calc_count(struct adf_telemetry *telemetry,109			 const struct adf_tl_dbg_counter *ctr,110			 struct adf_tl_dbg_aggr_values *vals)111{112	struct adf_tl_hw_data *tl_data = &GET_TL_DATA(telemetry->accel_dev);113	u64 *hist_vals;114	int sample_cnt;115	int ret = 0;116 117	hist_vals = kmalloc_array(tl_data->num_hbuff, sizeof(*hist_vals),118				  GFP_KERNEL);119	if (!hist_vals)120		return -ENOMEM;121 122	memset(vals, 0, sizeof(*vals));123	sample_cnt = tl_collect_values_u32(telemetry, ctr->offset1, hist_vals);124	if (!sample_cnt)125		goto out_free_hist_vals;126 127	vals->curr = hist_vals[sample_cnt - 1];128	vals->min = min_array(hist_vals, sample_cnt);129	vals->max = max_array(hist_vals, sample_cnt);130	vals->avg = avg_array(hist_vals, sample_cnt);131 132out_free_hist_vals:133	kfree(hist_vals);134	return ret;135}136 137/* Convert CPP bus cycles to ns. */138static int tl_cycles_to_ns(struct adf_telemetry *telemetry,139			   const struct adf_tl_dbg_counter *ctr,140			   struct adf_tl_dbg_aggr_values *vals)141{142	struct adf_tl_hw_data *tl_data = &GET_TL_DATA(telemetry->accel_dev);143	u8 cpp_ns_per_cycle = tl_data->cpp_ns_per_cycle;144	int ret;145 146	ret = tl_calc_count(telemetry, ctr, vals);147	if (ret)148		return ret;149 150	vals->curr *= cpp_ns_per_cycle;151	vals->min *= cpp_ns_per_cycle;152	vals->max *= cpp_ns_per_cycle;153	vals->avg *= cpp_ns_per_cycle;154 155	return 0;156}157 158/*159 * Compute latency cumulative average with division of accumulated value160 * by sample count. Returned value is in ns.161 */162static int tl_lat_acc_avg(struct adf_telemetry *telemetry,163			  const struct adf_tl_dbg_counter *ctr,164			  struct adf_tl_dbg_aggr_values *vals)165{166	struct adf_tl_hw_data *tl_data = &GET_TL_DATA(telemetry->accel_dev);167	u8 cpp_ns_per_cycle = tl_data->cpp_ns_per_cycle;168	u8 num_hbuff = tl_data->num_hbuff;169	int sample_cnt, i;170	u64 *hist_vals;171	u64 *hist_cnt;172	int ret = 0;173 174	hist_vals = kmalloc_array(num_hbuff, sizeof(*hist_vals), GFP_KERNEL);175	if (!hist_vals)176		return -ENOMEM;177 178	hist_cnt = kmalloc_array(num_hbuff, sizeof(*hist_cnt), GFP_KERNEL);179	if (!hist_cnt) {180		ret = -ENOMEM;181		goto out_free_hist_vals;182	}183 184	memset(vals, 0, sizeof(*vals));185	sample_cnt = tl_collect_values_u64(telemetry, ctr->offset1, hist_vals);186	if (!sample_cnt)187		goto out_free_hist_cnt;188 189	tl_collect_values_u32(telemetry, ctr->offset2, hist_cnt);190 191	for (i = 0; i < sample_cnt; i++) {192		/* Avoid division by 0 if count is 0. */193		if (hist_cnt[i])194			hist_vals[i] = div_u64(hist_vals[i] * cpp_ns_per_cycle,195					       hist_cnt[i]);196		else197			hist_vals[i] = 0;198	}199 200	vals->curr = hist_vals[sample_cnt - 1];201	vals->min = min_array(hist_vals, sample_cnt);202	vals->max = max_array(hist_vals, sample_cnt);203	vals->avg = avg_array(hist_vals, sample_cnt);204 205out_free_hist_cnt:206	kfree(hist_cnt);207out_free_hist_vals:208	kfree(hist_vals);209	return ret;210}211 212/* Convert HW raw bandwidth units to Mbps. */213static int tl_bw_hw_units_to_mbps(struct adf_telemetry *telemetry,214				  const struct adf_tl_dbg_counter *ctr,215				  struct adf_tl_dbg_aggr_values *vals)216{217	struct adf_tl_hw_data *tl_data = &GET_TL_DATA(telemetry->accel_dev);218	u16 bw_hw_2_bits = tl_data->bw_units_to_bytes * BITS_PER_BYTE;219	u64 *hist_vals;220	int sample_cnt;221	int ret = 0;222 223	hist_vals = kmalloc_array(tl_data->num_hbuff, sizeof(*hist_vals),224				  GFP_KERNEL);225	if (!hist_vals)226		return -ENOMEM;227 228	memset(vals, 0, sizeof(*vals));229	sample_cnt = tl_collect_values_u32(telemetry, ctr->offset1, hist_vals);230	if (!sample_cnt)231		goto out_free_hist_vals;232 233	vals->curr = div_u64(hist_vals[sample_cnt - 1] * bw_hw_2_bits, MEGA);234	vals->min = div_u64(min_array(hist_vals, sample_cnt) * bw_hw_2_bits, MEGA);235	vals->max = div_u64(max_array(hist_vals, sample_cnt) * bw_hw_2_bits, MEGA);236	vals->avg = div_u64(avg_array(hist_vals, sample_cnt) * bw_hw_2_bits, MEGA);237 238out_free_hist_vals:239	kfree(hist_vals);240	return ret;241}242 243static void tl_seq_printf_counter(struct adf_telemetry *telemetry,244				  struct seq_file *s, const char *name,245				  struct adf_tl_dbg_aggr_values *vals)246{247	seq_printf(s, "%-*s", TL_KEY_MIN_PADDING, name);248	seq_printf(s, "%*llu", TL_VALUE_MIN_PADDING, vals->curr);249	if (atomic_read(&telemetry->state) > 1) {250		seq_printf(s, "%*llu", TL_VALUE_MIN_PADDING, vals->min);251		seq_printf(s, "%*llu", TL_VALUE_MIN_PADDING, vals->max);252		seq_printf(s, "%*llu", TL_VALUE_MIN_PADDING, vals->avg);253	}254	seq_puts(s, "\n");255}256 257static int tl_calc_and_print_counter(struct adf_telemetry *telemetry,258				     struct seq_file *s,259				     const struct adf_tl_dbg_counter *ctr,260				     const char *name)261{262	const char *counter_name = name ? name : ctr->name;263	enum adf_tl_counter_type type = ctr->type;264	struct adf_tl_dbg_aggr_values vals;265	int ret;266 267	switch (type) {268	case ADF_TL_SIMPLE_COUNT:269		ret = tl_calc_count(telemetry, ctr, &vals);270		break;271	case ADF_TL_COUNTER_NS:272		ret = tl_cycles_to_ns(telemetry, ctr, &vals);273		break;274	case ADF_TL_COUNTER_NS_AVG:275		ret = tl_lat_acc_avg(telemetry, ctr, &vals);276		break;277	case ADF_TL_COUNTER_MBPS:278		ret = tl_bw_hw_units_to_mbps(telemetry, ctr, &vals);279		break;280	default:281		return -EINVAL;282	}283 284	if (ret)285		return ret;286 287	tl_seq_printf_counter(telemetry, s, counter_name, &vals);288 289	return 0;290}291 292static int tl_print_sl_counter(struct adf_telemetry *telemetry,293			       const struct adf_tl_dbg_counter *ctr,294			       struct seq_file *s, u8 cnt_id)295{296	size_t sl_regs_sz = GET_TL_DATA(telemetry->accel_dev).slice_reg_sz;297	struct adf_tl_dbg_counter slice_ctr;298	size_t offset_inc = cnt_id * sl_regs_sz;299	char cnt_name[MAX_COUNT_NAME_SIZE];300 301	snprintf(cnt_name, MAX_COUNT_NAME_SIZE, "%s%d", ctr->name, cnt_id);302	slice_ctr = *ctr;303	slice_ctr.offset1 += offset_inc;304 305	return tl_calc_and_print_counter(telemetry, s, &slice_ctr, cnt_name);306}307 308static int tl_calc_and_print_sl_counters(struct adf_accel_dev *accel_dev,309					 struct seq_file *s, u8 cnt_type, u8 cnt_id)310{311	struct adf_tl_hw_data *tl_data = &GET_TL_DATA(accel_dev);312	struct adf_telemetry *telemetry = accel_dev->telemetry;313	const struct adf_tl_dbg_counter *sl_tl_util_counters;314	const struct adf_tl_dbg_counter *sl_tl_exec_counters;315	const struct adf_tl_dbg_counter *ctr;316	int ret;317 318	sl_tl_util_counters = tl_data->sl_util_counters;319	sl_tl_exec_counters = tl_data->sl_exec_counters;320 321	ctr = &sl_tl_util_counters[cnt_type];322 323	ret = tl_print_sl_counter(telemetry, ctr, s, cnt_id);324	if (ret) {325		dev_notice(&GET_DEV(accel_dev),326			   "invalid slice utilization counter type\n");327		return ret;328	}329 330	ctr = &sl_tl_exec_counters[cnt_type];331 332	ret = tl_print_sl_counter(telemetry, ctr, s, cnt_id);333	if (ret) {334		dev_notice(&GET_DEV(accel_dev),335			   "invalid slice execution counter type\n");336		return ret;337	}338 339	return 0;340}341 342static void tl_print_msg_cnt(struct seq_file *s, u32 msg_cnt)343{344	seq_printf(s, "%-*s", TL_KEY_MIN_PADDING, SNAPSHOT_CNT_MSG);345	seq_printf(s, "%*u\n", TL_VALUE_MIN_PADDING, msg_cnt);346}347 348static int tl_print_dev_data(struct adf_accel_dev *accel_dev,349			     struct seq_file *s)350{351	struct adf_tl_hw_data *tl_data = &GET_TL_DATA(accel_dev);352	struct adf_telemetry *telemetry = accel_dev->telemetry;353	const struct adf_tl_dbg_counter *dev_tl_counters;354	u8 num_dev_counters = tl_data->num_dev_counters;355	u8 *sl_cnt = (u8 *)&telemetry->slice_cnt;356	const struct adf_tl_dbg_counter *ctr;357	unsigned int i;358	int ret;359	u8 j;360 361	if (!atomic_read(&telemetry->state)) {362		dev_info(&GET_DEV(accel_dev), "not enabled\n");363		return -EPERM;364	}365 366	dev_tl_counters = tl_data->dev_counters;367 368	tl_print_msg_cnt(s, telemetry->msg_cnt);369 370	/* Print device level telemetry. */371	for (i = 0; i < num_dev_counters; i++) {372		ctr = &dev_tl_counters[i];373		ret = tl_calc_and_print_counter(telemetry, s, ctr, NULL);374		if (ret) {375			dev_notice(&GET_DEV(accel_dev),376				   "invalid counter type\n");377			return ret;378		}379	}380 381	/* Print per slice telemetry. */382	for (i = 0; i < ADF_TL_SL_CNT_COUNT; i++) {383		for (j = 0; j < sl_cnt[i]; j++) {384			ret = tl_calc_and_print_sl_counters(accel_dev, s, i, j);385			if (ret)386				return ret;387		}388	}389 390	return 0;391}392 393static int tl_dev_data_show(struct seq_file *s, void *unused)394{395	struct adf_accel_dev *accel_dev = s->private;396 397	if (!accel_dev)398		return -EINVAL;399 400	return tl_print_dev_data(accel_dev, s);401}402DEFINE_SHOW_ATTRIBUTE(tl_dev_data);403 404static int tl_control_show(struct seq_file *s, void *unused)405{406	struct adf_accel_dev *accel_dev = s->private;407 408	if (!accel_dev)409		return -EINVAL;410 411	seq_printf(s, "%d\n", atomic_read(&accel_dev->telemetry->state));412 413	return 0;414}415 416static ssize_t tl_control_write(struct file *file, const char __user *userbuf,417				size_t count, loff_t *ppos)418{419	struct seq_file *seq_f = file->private_data;420	struct adf_accel_dev *accel_dev;421	struct adf_telemetry *telemetry;422	struct adf_tl_hw_data *tl_data;423	struct device *dev;424	u32 input;425	int ret;426 427	accel_dev = seq_f->private;428	if (!accel_dev)429		return -EINVAL;430 431	tl_data = &GET_TL_DATA(accel_dev);432	telemetry = accel_dev->telemetry;433	dev = &GET_DEV(accel_dev);434 435	mutex_lock(&telemetry->wr_lock);436 437	ret = kstrtou32_from_user(userbuf, count, 10, &input);438	if (ret)439		goto unlock_and_exit;440 441	if (input > tl_data->num_hbuff) {442		dev_info(dev, "invalid control input\n");443		ret = -EINVAL;444		goto unlock_and_exit;445	}446 447	/* If input is 0, just stop telemetry. */448	if (!input) {449		ret = adf_tl_halt(accel_dev);450		if (!ret)451			ret = count;452 453		goto unlock_and_exit;454	}455 456	/* If TL is already enabled, stop it. */457	if (atomic_read(&telemetry->state)) {458		dev_info(dev, "already enabled, restarting.\n");459		ret = adf_tl_halt(accel_dev);460		if (ret)461			goto unlock_and_exit;462	}463 464	ret = adf_tl_run(accel_dev, input);465	if (ret)466		goto unlock_and_exit;467 468	ret = count;469 470unlock_and_exit:471	mutex_unlock(&telemetry->wr_lock);472	return ret;473}474DEFINE_SHOW_STORE_ATTRIBUTE(tl_control);475 476static int get_rp_index_from_file(const struct file *f, u8 *rp_id, u8 rp_num)477{478	char alpha;479	u8 index;480	int ret;481 482	ret = sscanf(f->f_path.dentry->d_name.name, ADF_TL_RP_REGS_FNAME, &alpha);483	if (ret != 1)484		return -EINVAL;485 486	index = ADF_TL_DBG_RP_INDEX_ALPHA(alpha);487	*rp_id = index;488 489	return 0;490}491 492static int adf_tl_dbg_change_rp_index(struct adf_accel_dev *accel_dev,493				      unsigned int new_rp_num,494				      unsigned int rp_regs_index)495{496	struct adf_hw_device_data *hw_data = GET_HW_DATA(accel_dev);497	struct adf_telemetry *telemetry = accel_dev->telemetry;498	struct device *dev = &GET_DEV(accel_dev);499	unsigned int i;500	u8 curr_state;501	int ret;502 503	if (new_rp_num >= hw_data->num_rps) {504		dev_info(dev, "invalid Ring Pair number selected\n");505		return -EINVAL;506	}507 508	for (i = 0; i < hw_data->tl_data.max_rp; i++) {509		if (telemetry->rp_num_indexes[i] == new_rp_num) {510			dev_info(dev, "RP nr: %d is already selected in slot rp_%c_data\n",511				 new_rp_num, ADF_TL_DBG_RP_ALPHA_INDEX(i));512			return 0;513		}514	}515 516	dev_dbg(dev, "selecting RP nr %u into slot rp_%c_data\n",517		new_rp_num, ADF_TL_DBG_RP_ALPHA_INDEX(rp_regs_index));518 519	curr_state = atomic_read(&telemetry->state);520 521	if (curr_state) {522		ret = adf_tl_halt(accel_dev);523		if (ret)524			return ret;525 526		telemetry->rp_num_indexes[rp_regs_index] = new_rp_num;527 528		ret = adf_tl_run(accel_dev, curr_state);529		if (ret)530			return ret;531	} else {532		telemetry->rp_num_indexes[rp_regs_index] = new_rp_num;533	}534 535	return 0;536}537 538static void tl_print_rp_srv(struct adf_accel_dev *accel_dev, struct seq_file *s,539			    u8 rp_idx)540{541	u32 banks_per_vf = GET_HW_DATA(accel_dev)->num_banks_per_vf;542	enum adf_cfg_service_type svc;543 544	seq_printf(s, "%-*s", TL_KEY_MIN_PADDING, RP_SERVICE_TYPE);545 546	svc = GET_SRV_TYPE(accel_dev, rp_idx % banks_per_vf);547	switch (svc) {548	case COMP:549		seq_printf(s, "%*s\n", TL_VALUE_MIN_PADDING, ADF_CFG_DC);550		break;551	case SYM:552		seq_printf(s, "%*s\n", TL_VALUE_MIN_PADDING, ADF_CFG_SYM);553		break;554	case ASYM:555		seq_printf(s, "%*s\n", TL_VALUE_MIN_PADDING, ADF_CFG_ASYM);556		break;557	default:558		seq_printf(s, "%*s\n", TL_VALUE_MIN_PADDING, TL_RP_SRV_UNKNOWN);559		break;560	}561}562 563static int tl_print_rp_data(struct adf_accel_dev *accel_dev, struct seq_file *s,564			    u8 rp_regs_index)565{566	struct adf_tl_hw_data *tl_data = &GET_TL_DATA(accel_dev);567	struct adf_telemetry *telemetry = accel_dev->telemetry;568	const struct adf_tl_dbg_counter *rp_tl_counters;569	u8 num_rp_counters = tl_data->num_rp_counters;570	size_t rp_regs_sz = tl_data->rp_reg_sz;571	struct adf_tl_dbg_counter ctr;572	unsigned int i;573	u8 rp_idx;574	int ret;575 576	if (!atomic_read(&telemetry->state)) {577		dev_info(&GET_DEV(accel_dev), "not enabled\n");578		return -EPERM;579	}580 581	rp_tl_counters = tl_data->rp_counters;582	rp_idx = telemetry->rp_num_indexes[rp_regs_index];583 584	if (rp_idx == ADF_TL_RP_REGS_DISABLED) {585		dev_info(&GET_DEV(accel_dev), "no RP number selected in rp_%c_data\n",586			 ADF_TL_DBG_RP_ALPHA_INDEX(rp_regs_index));587		return -EPERM;588	}589 590	tl_print_msg_cnt(s, telemetry->msg_cnt);591	seq_printf(s, "%-*s", TL_KEY_MIN_PADDING, RP_NUM_INDEX);592	seq_printf(s, "%*d\n", TL_VALUE_MIN_PADDING, rp_idx);593	tl_print_rp_srv(accel_dev, s, rp_idx);594 595	for (i = 0; i < num_rp_counters; i++) {596		ctr = rp_tl_counters[i];597		ctr.offset1 += rp_regs_sz * rp_regs_index;598		ctr.offset2 += rp_regs_sz * rp_regs_index;599		ret = tl_calc_and_print_counter(telemetry, s, &ctr, NULL);600		if (ret) {601			dev_dbg(&GET_DEV(accel_dev),602				"invalid RP counter type\n");603			return ret;604		}605	}606 607	return 0;608}609 610static int tl_rp_data_show(struct seq_file *s, void *unused)611{612	struct adf_accel_dev *accel_dev = s->private;613	u8 rp_regs_index;614	u8 max_rp;615	int ret;616 617	if (!accel_dev)618		return -EINVAL;619 620	max_rp = GET_TL_DATA(accel_dev).max_rp;621	ret = get_rp_index_from_file(s->file, &rp_regs_index, max_rp);622	if (ret) {623		dev_dbg(&GET_DEV(accel_dev), "invalid RP data file name\n");624		return ret;625	}626 627	return tl_print_rp_data(accel_dev, s, rp_regs_index);628}629 630static ssize_t tl_rp_data_write(struct file *file, const char __user *userbuf,631				size_t count, loff_t *ppos)632{633	struct seq_file *seq_f = file->private_data;634	struct adf_accel_dev *accel_dev;635	struct adf_telemetry *telemetry;636	unsigned int new_rp_num;637	u8 rp_regs_index;638	u8 max_rp;639	int ret;640 641	accel_dev = seq_f->private;642	if (!accel_dev)643		return -EINVAL;644 645	telemetry = accel_dev->telemetry;646	max_rp = GET_TL_DATA(accel_dev).max_rp;647 648	mutex_lock(&telemetry->wr_lock);649 650	ret = get_rp_index_from_file(file, &rp_regs_index, max_rp);651	if (ret) {652		dev_dbg(&GET_DEV(accel_dev), "invalid RP data file name\n");653		goto unlock_and_exit;654	}655 656	ret = kstrtou32_from_user(userbuf, count, 10, &new_rp_num);657	if (ret)658		goto unlock_and_exit;659 660	ret = adf_tl_dbg_change_rp_index(accel_dev, new_rp_num, rp_regs_index);661	if (ret)662		goto unlock_and_exit;663 664	ret = count;665 666unlock_and_exit:667	mutex_unlock(&telemetry->wr_lock);668	return ret;669}670DEFINE_SHOW_STORE_ATTRIBUTE(tl_rp_data);671 672void adf_tl_dbgfs_add(struct adf_accel_dev *accel_dev)673{674	struct adf_telemetry *telemetry = accel_dev->telemetry;675	struct dentry *parent = accel_dev->debugfs_dir;676	u8 max_rp = GET_TL_DATA(accel_dev).max_rp;677	char name[ADF_TL_RP_REGS_FNAME_SIZE];678	struct dentry *dir;679	unsigned int i;680 681	if (!telemetry)682		return;683 684	dir = debugfs_create_dir("telemetry", parent);685	accel_dev->telemetry->dbg_dir = dir;686	debugfs_create_file("device_data", 0444, dir, accel_dev, &tl_dev_data_fops);687	debugfs_create_file("control", 0644, dir, accel_dev, &tl_control_fops);688 689	for (i = 0; i < max_rp; i++) {690		snprintf(name, sizeof(name), ADF_TL_RP_REGS_FNAME,691			 ADF_TL_DBG_RP_ALPHA_INDEX(i));692		debugfs_create_file(name, 0644, dir, accel_dev, &tl_rp_data_fops);693	}694}695 696void adf_tl_dbgfs_rm(struct adf_accel_dev *accel_dev)697{698	struct adf_telemetry *telemetry = accel_dev->telemetry;699	struct dentry *dbg_dir;700 701	if (!telemetry)702		return;703 704	dbg_dir = telemetry->dbg_dir;705 706	debugfs_remove_recursive(dbg_dir);707 708	if (atomic_read(&telemetry->state))709		adf_tl_halt(accel_dev);710}711