• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2017, NVIDIA CORPORATION.  All rights reserved.
4  */
5 #include <linux/debugfs.h>
6 #include <linux/dma-mapping.h>
7 #include <linux/slab.h>
8 #include <linux/uaccess.h>
9 
10 #include <soc/tegra/bpmp.h>
11 #include <soc/tegra/bpmp-abi.h>
12 
13 static DEFINE_MUTEX(bpmp_debug_lock);
14 
15 struct seqbuf {
16 	char *buf;
17 	size_t pos;
18 	size_t size;
19 };
20 
seqbuf_init(struct seqbuf * seqbuf,void * buf,size_t size)21 static void seqbuf_init(struct seqbuf *seqbuf, void *buf, size_t size)
22 {
23 	seqbuf->buf = buf;
24 	seqbuf->size = size;
25 	seqbuf->pos = 0;
26 }
27 
seqbuf_avail(struct seqbuf * seqbuf)28 static size_t seqbuf_avail(struct seqbuf *seqbuf)
29 {
30 	return seqbuf->pos < seqbuf->size ? seqbuf->size - seqbuf->pos : 0;
31 }
32 
seqbuf_status(struct seqbuf * seqbuf)33 static size_t seqbuf_status(struct seqbuf *seqbuf)
34 {
35 	return seqbuf->pos <= seqbuf->size ? 0 : -EOVERFLOW;
36 }
37 
seqbuf_eof(struct seqbuf * seqbuf)38 static int seqbuf_eof(struct seqbuf *seqbuf)
39 {
40 	return seqbuf->pos >= seqbuf->size;
41 }
42 
seqbuf_read(struct seqbuf * seqbuf,void * buf,size_t nbyte)43 static int seqbuf_read(struct seqbuf *seqbuf, void *buf, size_t nbyte)
44 {
45 	nbyte = min(nbyte, seqbuf_avail(seqbuf));
46 	memcpy(buf, seqbuf->buf + seqbuf->pos, nbyte);
47 	seqbuf->pos += nbyte;
48 	return seqbuf_status(seqbuf);
49 }
50 
seqbuf_read_u32(struct seqbuf * seqbuf,uint32_t * v)51 static int seqbuf_read_u32(struct seqbuf *seqbuf, uint32_t *v)
52 {
53 	int err;
54 
55 	err = seqbuf_read(seqbuf, v, 4);
56 	*v = le32_to_cpu(*v);
57 	return err;
58 }
59 
seqbuf_read_str(struct seqbuf * seqbuf,const char ** str)60 static int seqbuf_read_str(struct seqbuf *seqbuf, const char **str)
61 {
62 	*str = seqbuf->buf + seqbuf->pos;
63 	seqbuf->pos += strnlen(*str, seqbuf_avail(seqbuf));
64 	seqbuf->pos++;
65 	return seqbuf_status(seqbuf);
66 }
67 
seqbuf_seek(struct seqbuf * seqbuf,ssize_t offset)68 static void seqbuf_seek(struct seqbuf *seqbuf, ssize_t offset)
69 {
70 	seqbuf->pos += offset;
71 }
72 
73 /* map filename in Linux debugfs to corresponding entry in BPMP */
get_filename(struct tegra_bpmp * bpmp,const struct file * file,char * buf,int size)74 static const char *get_filename(struct tegra_bpmp *bpmp,
75 				const struct file *file, char *buf, int size)
76 {
77 	char root_path_buf[512];
78 	const char *root_path;
79 	const char *filename;
80 	size_t root_len;
81 
82 	root_path = dentry_path(bpmp->debugfs_mirror, root_path_buf,
83 				sizeof(root_path_buf));
84 	if (IS_ERR(root_path))
85 		return NULL;
86 
87 	root_len = strlen(root_path);
88 
89 	filename = dentry_path(file->f_path.dentry, buf, size);
90 	if (IS_ERR(filename))
91 		return NULL;
92 
93 	if (strlen(filename) < root_len ||
94 			strncmp(filename, root_path, root_len))
95 		return NULL;
96 
97 	filename += root_len;
98 
99 	return filename;
100 }
101 
mrq_debug_open(struct tegra_bpmp * bpmp,const char * name,uint32_t * fd,uint32_t * len,bool write)102 static int mrq_debug_open(struct tegra_bpmp *bpmp, const char *name,
103 			  uint32_t *fd, uint32_t *len, bool write)
104 {
105 	struct mrq_debug_request req = {
106 		.cmd = cpu_to_le32(write ? CMD_DEBUG_OPEN_WO : CMD_DEBUG_OPEN_RO),
107 	};
108 	struct mrq_debug_response resp;
109 	struct tegra_bpmp_message msg = {
110 		.mrq = MRQ_DEBUG,
111 		.tx = {
112 			.data = &req,
113 			.size = sizeof(req),
114 		},
115 		.rx = {
116 			.data = &resp,
117 			.size = sizeof(resp),
118 		},
119 	};
120 	ssize_t sz_name;
121 	int err = 0;
122 
123 	sz_name = strscpy(req.fop.name, name, sizeof(req.fop.name));
124 	if (sz_name < 0) {
125 		pr_err("File name too large: %s\n", name);
126 		return -EINVAL;
127 	}
128 
129 	err = tegra_bpmp_transfer(bpmp, &msg);
130 	if (err < 0)
131 		return err;
132 	else if (msg.rx.ret < 0)
133 		return -EINVAL;
134 
135 	*len = resp.fop.datalen;
136 	*fd = resp.fop.fd;
137 
138 	return 0;
139 }
140 
mrq_debug_close(struct tegra_bpmp * bpmp,uint32_t fd)141 static int mrq_debug_close(struct tegra_bpmp *bpmp, uint32_t fd)
142 {
143 	struct mrq_debug_request req = {
144 		.cmd = cpu_to_le32(CMD_DEBUG_CLOSE),
145 		.frd = {
146 			.fd = fd,
147 		},
148 	};
149 	struct mrq_debug_response resp;
150 	struct tegra_bpmp_message msg = {
151 		.mrq = MRQ_DEBUG,
152 		.tx = {
153 			.data = &req,
154 			.size = sizeof(req),
155 		},
156 		.rx = {
157 			.data = &resp,
158 			.size = sizeof(resp),
159 		},
160 	};
161 	int err = 0;
162 
163 	err = tegra_bpmp_transfer(bpmp, &msg);
164 	if (err < 0)
165 		return err;
166 	else if (msg.rx.ret < 0)
167 		return -EINVAL;
168 
169 	return 0;
170 }
171 
mrq_debug_read(struct tegra_bpmp * bpmp,const char * name,char * data,size_t sz_data,uint32_t * nbytes)172 static int mrq_debug_read(struct tegra_bpmp *bpmp, const char *name,
173 			  char *data, size_t sz_data, uint32_t *nbytes)
174 {
175 	struct mrq_debug_request req = {
176 		.cmd = cpu_to_le32(CMD_DEBUG_READ),
177 	};
178 	struct mrq_debug_response resp;
179 	struct tegra_bpmp_message msg = {
180 		.mrq = MRQ_DEBUG,
181 		.tx = {
182 			.data = &req,
183 			.size = sizeof(req),
184 		},
185 		.rx = {
186 			.data = &resp,
187 			.size = sizeof(resp),
188 		},
189 	};
190 	uint32_t fd = 0, len = 0;
191 	int remaining, err;
192 
193 	mutex_lock(&bpmp_debug_lock);
194 	err = mrq_debug_open(bpmp, name, &fd, &len, 0);
195 	if (err)
196 		goto out;
197 
198 	if (len > sz_data) {
199 		err = -EFBIG;
200 		goto close;
201 	}
202 
203 	req.frd.fd = fd;
204 	remaining = len;
205 
206 	while (remaining > 0) {
207 		err = tegra_bpmp_transfer(bpmp, &msg);
208 		if (err < 0) {
209 			goto close;
210 		} else if (msg.rx.ret < 0) {
211 			err = -EINVAL;
212 			goto close;
213 		}
214 
215 		if (resp.frd.readlen > remaining) {
216 			pr_err("%s: read data length invalid\n", __func__);
217 			err = -EINVAL;
218 			goto close;
219 		}
220 
221 		memcpy(data, resp.frd.data, resp.frd.readlen);
222 		data += resp.frd.readlen;
223 		remaining -= resp.frd.readlen;
224 	}
225 
226 	*nbytes = len;
227 
228 close:
229 	err = mrq_debug_close(bpmp, fd);
230 out:
231 	mutex_unlock(&bpmp_debug_lock);
232 	return err;
233 }
234 
mrq_debug_write(struct tegra_bpmp * bpmp,const char * name,uint8_t * data,size_t sz_data)235 static int mrq_debug_write(struct tegra_bpmp *bpmp, const char *name,
236 			   uint8_t *data, size_t sz_data)
237 {
238 	struct mrq_debug_request req = {
239 		.cmd = cpu_to_le32(CMD_DEBUG_WRITE)
240 	};
241 	struct mrq_debug_response resp;
242 	struct tegra_bpmp_message msg = {
243 		.mrq = MRQ_DEBUG,
244 		.tx = {
245 			.data = &req,
246 			.size = sizeof(req),
247 		},
248 		.rx = {
249 			.data = &resp,
250 			.size = sizeof(resp),
251 		},
252 	};
253 	uint32_t fd = 0, len = 0;
254 	size_t remaining;
255 	int err;
256 
257 	mutex_lock(&bpmp_debug_lock);
258 	err = mrq_debug_open(bpmp, name, &fd, &len, 1);
259 	if (err)
260 		goto out;
261 
262 	if (sz_data > len) {
263 		err = -EINVAL;
264 		goto close;
265 	}
266 
267 	req.fwr.fd = fd;
268 	remaining = sz_data;
269 
270 	while (remaining > 0) {
271 		len = min(remaining, sizeof(req.fwr.data));
272 		memcpy(req.fwr.data, data, len);
273 		req.fwr.datalen = len;
274 
275 		err = tegra_bpmp_transfer(bpmp, &msg);
276 		if (err < 0) {
277 			goto close;
278 		} else if (msg.rx.ret < 0) {
279 			err = -EINVAL;
280 			goto close;
281 		}
282 
283 		data += req.fwr.datalen;
284 		remaining -= req.fwr.datalen;
285 	}
286 
287 close:
288 	err = mrq_debug_close(bpmp, fd);
289 out:
290 	mutex_unlock(&bpmp_debug_lock);
291 	return err;
292 }
293 
bpmp_debug_show(struct seq_file * m,void * p)294 static int bpmp_debug_show(struct seq_file *m, void *p)
295 {
296 	struct file *file = m->private;
297 	struct inode *inode = file_inode(file);
298 	struct tegra_bpmp *bpmp = inode->i_private;
299 	char *databuf = NULL;
300 	char fnamebuf[256];
301 	const char *filename;
302 	uint32_t nbytes = 0;
303 	size_t len;
304 	int err;
305 
306 	len = seq_get_buf(m, &databuf);
307 	if (!databuf)
308 		return -ENOMEM;
309 
310 	filename = get_filename(bpmp, file, fnamebuf, sizeof(fnamebuf));
311 	if (!filename)
312 		return -ENOENT;
313 
314 	err = mrq_debug_read(bpmp, filename, databuf, len, &nbytes);
315 	if (!err)
316 		seq_commit(m, nbytes);
317 
318 	return err;
319 }
320 
bpmp_debug_store(struct file * file,const char __user * buf,size_t count,loff_t * f_pos)321 static ssize_t bpmp_debug_store(struct file *file, const char __user *buf,
322 		size_t count, loff_t *f_pos)
323 {
324 	struct inode *inode = file_inode(file);
325 	struct tegra_bpmp *bpmp = inode->i_private;
326 	char *databuf = NULL;
327 	char fnamebuf[256];
328 	const char *filename;
329 	ssize_t err;
330 
331 	filename = get_filename(bpmp, file, fnamebuf, sizeof(fnamebuf));
332 	if (!filename)
333 		return -ENOENT;
334 
335 	databuf = kmalloc(count, GFP_KERNEL);
336 	if (!databuf)
337 		return -ENOMEM;
338 
339 	if (copy_from_user(databuf, buf, count)) {
340 		err = -EFAULT;
341 		goto free_ret;
342 	}
343 
344 	err = mrq_debug_write(bpmp, filename, databuf, count);
345 
346 free_ret:
347 	kfree(databuf);
348 
349 	return err ?: count;
350 }
351 
bpmp_debug_open(struct inode * inode,struct file * file)352 static int bpmp_debug_open(struct inode *inode, struct file *file)
353 {
354 	return single_open_size(file, bpmp_debug_show, file, SZ_256K);
355 }
356 
357 static const struct file_operations bpmp_debug_fops = {
358 	.open		= bpmp_debug_open,
359 	.read		= seq_read,
360 	.llseek		= seq_lseek,
361 	.write		= bpmp_debug_store,
362 	.release	= single_release,
363 };
364 
bpmp_populate_debugfs_inband(struct tegra_bpmp * bpmp,struct dentry * parent,char * ppath)365 static int bpmp_populate_debugfs_inband(struct tegra_bpmp *bpmp,
366 					struct dentry *parent,
367 					char *ppath)
368 {
369 	const size_t pathlen = SZ_256;
370 	const size_t bufsize = SZ_16K;
371 	uint32_t dsize, attrs = 0;
372 	struct dentry *dentry;
373 	struct seqbuf seqbuf;
374 	char *buf, *pathbuf;
375 	const char *name;
376 	int err = 0;
377 
378 	if (!bpmp || !parent || !ppath)
379 		return -EINVAL;
380 
381 	buf = kmalloc(bufsize, GFP_KERNEL);
382 	if (!buf)
383 		return -ENOMEM;
384 
385 	pathbuf = kzalloc(pathlen, GFP_KERNEL);
386 	if (!pathbuf) {
387 		kfree(buf);
388 		return -ENOMEM;
389 	}
390 
391 	err = mrq_debug_read(bpmp, ppath, buf, bufsize, &dsize);
392 	if (err)
393 		goto out;
394 
395 	seqbuf_init(&seqbuf, buf, dsize);
396 
397 	while (!seqbuf_eof(&seqbuf)) {
398 		err = seqbuf_read_u32(&seqbuf, &attrs);
399 		if (err)
400 			goto out;
401 
402 		err = seqbuf_read_str(&seqbuf, &name);
403 		if (err < 0)
404 			goto out;
405 
406 		if (attrs & DEBUGFS_S_ISDIR) {
407 			size_t len;
408 
409 			dentry = debugfs_create_dir(name, parent);
410 			if (IS_ERR(dentry)) {
411 				err = PTR_ERR(dentry);
412 				goto out;
413 			}
414 
415 			len = snprintf(pathbuf, pathlen, "%s%s/", ppath, name);
416 			if (len >= pathlen) {
417 				err = -EINVAL;
418 				goto out;
419 			}
420 
421 			err = bpmp_populate_debugfs_inband(bpmp, dentry,
422 							   pathbuf);
423 			if (err < 0)
424 				goto out;
425 		} else {
426 			umode_t mode;
427 
428 			mode = attrs & DEBUGFS_S_IRUSR ? 0400 : 0;
429 			mode |= attrs & DEBUGFS_S_IWUSR ? 0200 : 0;
430 			dentry = debugfs_create_file(name, mode, parent, bpmp,
431 						     &bpmp_debug_fops);
432 			if (!dentry) {
433 				err = -ENOMEM;
434 				goto out;
435 			}
436 		}
437 	}
438 
439 out:
440 	kfree(pathbuf);
441 	kfree(buf);
442 
443 	return err;
444 }
445 
mrq_debugfs_read(struct tegra_bpmp * bpmp,dma_addr_t name,size_t sz_name,dma_addr_t data,size_t sz_data,size_t * nbytes)446 static int mrq_debugfs_read(struct tegra_bpmp *bpmp,
447 			    dma_addr_t name, size_t sz_name,
448 			    dma_addr_t data, size_t sz_data,
449 			    size_t *nbytes)
450 {
451 	struct mrq_debugfs_request req = {
452 		.cmd = cpu_to_le32(CMD_DEBUGFS_READ),
453 		.fop = {
454 			.fnameaddr = cpu_to_le32((uint32_t)name),
455 			.fnamelen = cpu_to_le32((uint32_t)sz_name),
456 			.dataaddr = cpu_to_le32((uint32_t)data),
457 			.datalen = cpu_to_le32((uint32_t)sz_data),
458 		},
459 	};
460 	struct mrq_debugfs_response resp;
461 	struct tegra_bpmp_message msg = {
462 		.mrq = MRQ_DEBUGFS,
463 		.tx = {
464 			.data = &req,
465 			.size = sizeof(req),
466 		},
467 		.rx = {
468 			.data = &resp,
469 			.size = sizeof(resp),
470 		},
471 	};
472 	int err;
473 
474 	err = tegra_bpmp_transfer(bpmp, &msg);
475 	if (err < 0)
476 		return err;
477 	else if (msg.rx.ret < 0)
478 		return -EINVAL;
479 
480 	*nbytes = (size_t)resp.fop.nbytes;
481 
482 	return 0;
483 }
484 
mrq_debugfs_write(struct tegra_bpmp * bpmp,dma_addr_t name,size_t sz_name,dma_addr_t data,size_t sz_data)485 static int mrq_debugfs_write(struct tegra_bpmp *bpmp,
486 			     dma_addr_t name, size_t sz_name,
487 			     dma_addr_t data, size_t sz_data)
488 {
489 	const struct mrq_debugfs_request req = {
490 		.cmd = cpu_to_le32(CMD_DEBUGFS_WRITE),
491 		.fop = {
492 			.fnameaddr = cpu_to_le32((uint32_t)name),
493 			.fnamelen = cpu_to_le32((uint32_t)sz_name),
494 			.dataaddr = cpu_to_le32((uint32_t)data),
495 			.datalen = cpu_to_le32((uint32_t)sz_data),
496 		},
497 	};
498 	struct tegra_bpmp_message msg = {
499 		.mrq = MRQ_DEBUGFS,
500 		.tx = {
501 			.data = &req,
502 			.size = sizeof(req),
503 		},
504 	};
505 
506 	return tegra_bpmp_transfer(bpmp, &msg);
507 }
508 
mrq_debugfs_dumpdir(struct tegra_bpmp * bpmp,dma_addr_t addr,size_t size,size_t * nbytes)509 static int mrq_debugfs_dumpdir(struct tegra_bpmp *bpmp, dma_addr_t addr,
510 			       size_t size, size_t *nbytes)
511 {
512 	const struct mrq_debugfs_request req = {
513 		.cmd = cpu_to_le32(CMD_DEBUGFS_DUMPDIR),
514 		.dumpdir = {
515 			.dataaddr = cpu_to_le32((uint32_t)addr),
516 			.datalen = cpu_to_le32((uint32_t)size),
517 		},
518 	};
519 	struct mrq_debugfs_response resp;
520 	struct tegra_bpmp_message msg = {
521 		.mrq = MRQ_DEBUGFS,
522 		.tx = {
523 			.data = &req,
524 			.size = sizeof(req),
525 		},
526 		.rx = {
527 			.data = &resp,
528 			.size = sizeof(resp),
529 		},
530 	};
531 	int err;
532 
533 	err = tegra_bpmp_transfer(bpmp, &msg);
534 	if (err < 0)
535 		return err;
536 	else if (msg.rx.ret < 0)
537 		return -EINVAL;
538 
539 	*nbytes = (size_t)resp.dumpdir.nbytes;
540 
541 	return 0;
542 }
543 
debugfs_show(struct seq_file * m,void * p)544 static int debugfs_show(struct seq_file *m, void *p)
545 {
546 	struct file *file = m->private;
547 	struct inode *inode = file_inode(file);
548 	struct tegra_bpmp *bpmp = inode->i_private;
549 	const size_t datasize = m->size;
550 	const size_t namesize = SZ_256;
551 	void *datavirt, *namevirt;
552 	dma_addr_t dataphys, namephys;
553 	char buf[256];
554 	const char *filename;
555 	size_t len, nbytes;
556 	int err;
557 
558 	filename = get_filename(bpmp, file, buf, sizeof(buf));
559 	if (!filename)
560 		return -ENOENT;
561 
562 	namevirt = dma_alloc_coherent(bpmp->dev, namesize, &namephys,
563 				      GFP_KERNEL | GFP_DMA32);
564 	if (!namevirt)
565 		return -ENOMEM;
566 
567 	datavirt = dma_alloc_coherent(bpmp->dev, datasize, &dataphys,
568 				      GFP_KERNEL | GFP_DMA32);
569 	if (!datavirt) {
570 		err = -ENOMEM;
571 		goto free_namebuf;
572 	}
573 
574 	len = strlen(filename);
575 	strncpy(namevirt, filename, namesize);
576 
577 	err = mrq_debugfs_read(bpmp, namephys, len, dataphys, datasize,
578 			       &nbytes);
579 
580 	if (!err)
581 		seq_write(m, datavirt, nbytes);
582 
583 	dma_free_coherent(bpmp->dev, datasize, datavirt, dataphys);
584 free_namebuf:
585 	dma_free_coherent(bpmp->dev, namesize, namevirt, namephys);
586 
587 	return err;
588 }
589 
debugfs_open(struct inode * inode,struct file * file)590 static int debugfs_open(struct inode *inode, struct file *file)
591 {
592 	return single_open_size(file, debugfs_show, file, SZ_128K);
593 }
594 
debugfs_store(struct file * file,const char __user * buf,size_t count,loff_t * f_pos)595 static ssize_t debugfs_store(struct file *file, const char __user *buf,
596 		size_t count, loff_t *f_pos)
597 {
598 	struct inode *inode = file_inode(file);
599 	struct tegra_bpmp *bpmp = inode->i_private;
600 	const size_t datasize = count;
601 	const size_t namesize = SZ_256;
602 	void *datavirt, *namevirt;
603 	dma_addr_t dataphys, namephys;
604 	char fnamebuf[256];
605 	const char *filename;
606 	size_t len;
607 	int err;
608 
609 	filename = get_filename(bpmp, file, fnamebuf, sizeof(fnamebuf));
610 	if (!filename)
611 		return -ENOENT;
612 
613 	namevirt = dma_alloc_coherent(bpmp->dev, namesize, &namephys,
614 				      GFP_KERNEL | GFP_DMA32);
615 	if (!namevirt)
616 		return -ENOMEM;
617 
618 	datavirt = dma_alloc_coherent(bpmp->dev, datasize, &dataphys,
619 				      GFP_KERNEL | GFP_DMA32);
620 	if (!datavirt) {
621 		err = -ENOMEM;
622 		goto free_namebuf;
623 	}
624 
625 	len = strlen(filename);
626 	strncpy(namevirt, filename, namesize);
627 
628 	if (copy_from_user(datavirt, buf, count)) {
629 		err = -EFAULT;
630 		goto free_databuf;
631 	}
632 
633 	err = mrq_debugfs_write(bpmp, namephys, len, dataphys,
634 				count);
635 
636 free_databuf:
637 	dma_free_coherent(bpmp->dev, datasize, datavirt, dataphys);
638 free_namebuf:
639 	dma_free_coherent(bpmp->dev, namesize, namevirt, namephys);
640 
641 	return err ?: count;
642 }
643 
644 static const struct file_operations debugfs_fops = {
645 	.open		= debugfs_open,
646 	.read		= seq_read,
647 	.llseek		= seq_lseek,
648 	.write		= debugfs_store,
649 	.release	= single_release,
650 };
651 
bpmp_populate_dir(struct tegra_bpmp * bpmp,struct seqbuf * seqbuf,struct dentry * parent,uint32_t depth)652 static int bpmp_populate_dir(struct tegra_bpmp *bpmp, struct seqbuf *seqbuf,
653 			     struct dentry *parent, uint32_t depth)
654 {
655 	int err;
656 	uint32_t d, t;
657 	const char *name;
658 	struct dentry *dentry;
659 
660 	while (!seqbuf_eof(seqbuf)) {
661 		err = seqbuf_read_u32(seqbuf, &d);
662 		if (err < 0)
663 			return err;
664 
665 		if (d < depth) {
666 			seqbuf_seek(seqbuf, -4);
667 			/* go up a level */
668 			return 0;
669 		} else if (d != depth) {
670 			/* malformed data received from BPMP */
671 			return -EIO;
672 		}
673 
674 		err = seqbuf_read_u32(seqbuf, &t);
675 		if (err < 0)
676 			return err;
677 		err = seqbuf_read_str(seqbuf, &name);
678 		if (err < 0)
679 			return err;
680 
681 		if (t & DEBUGFS_S_ISDIR) {
682 			dentry = debugfs_create_dir(name, parent);
683 			if (!dentry)
684 				return -ENOMEM;
685 			err = bpmp_populate_dir(bpmp, seqbuf, dentry, depth+1);
686 			if (err < 0)
687 				return err;
688 		} else {
689 			umode_t mode;
690 
691 			mode = t & DEBUGFS_S_IRUSR ? S_IRUSR : 0;
692 			mode |= t & DEBUGFS_S_IWUSR ? S_IWUSR : 0;
693 			dentry = debugfs_create_file(name, mode,
694 						     parent, bpmp,
695 						     &debugfs_fops);
696 			if (!dentry)
697 				return -ENOMEM;
698 		}
699 	}
700 
701 	return 0;
702 }
703 
bpmp_populate_debugfs_shmem(struct tegra_bpmp * bpmp)704 static int bpmp_populate_debugfs_shmem(struct tegra_bpmp *bpmp)
705 {
706 	struct seqbuf seqbuf;
707 	const size_t sz = SZ_512K;
708 	dma_addr_t phys;
709 	size_t nbytes;
710 	void *virt;
711 	int err;
712 
713 	virt = dma_alloc_coherent(bpmp->dev, sz, &phys,
714 				  GFP_KERNEL | GFP_DMA32);
715 	if (!virt)
716 		return -ENOMEM;
717 
718 	err = mrq_debugfs_dumpdir(bpmp, phys, sz, &nbytes);
719 	if (err < 0) {
720 		goto free;
721 	} else if (nbytes > sz) {
722 		err = -EINVAL;
723 		goto free;
724 	}
725 
726 	seqbuf_init(&seqbuf, virt, nbytes);
727 	err = bpmp_populate_dir(bpmp, &seqbuf, bpmp->debugfs_mirror, 0);
728 free:
729 	dma_free_coherent(bpmp->dev, sz, virt, phys);
730 
731 	return err;
732 }
733 
tegra_bpmp_init_debugfs(struct tegra_bpmp * bpmp)734 int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp)
735 {
736 	struct dentry *root;
737 	bool inband;
738 	int err;
739 
740 	inband = tegra_bpmp_mrq_is_supported(bpmp, MRQ_DEBUG);
741 
742 	if (!inband && !tegra_bpmp_mrq_is_supported(bpmp, MRQ_DEBUGFS))
743 		return 0;
744 
745 	root = debugfs_create_dir("bpmp", NULL);
746 	if (!root)
747 		return -ENOMEM;
748 
749 	bpmp->debugfs_mirror = debugfs_create_dir("debug", root);
750 	if (!bpmp->debugfs_mirror) {
751 		err = -ENOMEM;
752 		goto out;
753 	}
754 
755 	if (inband)
756 		err = bpmp_populate_debugfs_inband(bpmp, bpmp->debugfs_mirror,
757 						   "/");
758 	else
759 		err = bpmp_populate_debugfs_shmem(bpmp);
760 
761 out:
762 	if (err < 0)
763 		debugfs_remove_recursive(root);
764 
765 	return err;
766 }
767