0001
0002
0003
0004
0005 #include <linux/debugfs.h>
0006 #include <linux/dma-mapping.h>
0007 #include <linux/slab.h>
0008 #include <linux/uaccess.h>
0009
0010 #include <soc/tegra/bpmp.h>
0011 #include <soc/tegra/bpmp-abi.h>
0012
0013 static DEFINE_MUTEX(bpmp_debug_lock);
0014
0015 struct seqbuf {
0016 char *buf;
0017 size_t pos;
0018 size_t size;
0019 };
0020
0021 static void seqbuf_init(struct seqbuf *seqbuf, void *buf, size_t size)
0022 {
0023 seqbuf->buf = buf;
0024 seqbuf->size = size;
0025 seqbuf->pos = 0;
0026 }
0027
0028 static size_t seqbuf_avail(struct seqbuf *seqbuf)
0029 {
0030 return seqbuf->pos < seqbuf->size ? seqbuf->size - seqbuf->pos : 0;
0031 }
0032
0033 static size_t seqbuf_status(struct seqbuf *seqbuf)
0034 {
0035 return seqbuf->pos <= seqbuf->size ? 0 : -EOVERFLOW;
0036 }
0037
0038 static int seqbuf_eof(struct seqbuf *seqbuf)
0039 {
0040 return seqbuf->pos >= seqbuf->size;
0041 }
0042
0043 static int seqbuf_read(struct seqbuf *seqbuf, void *buf, size_t nbyte)
0044 {
0045 nbyte = min(nbyte, seqbuf_avail(seqbuf));
0046 memcpy(buf, seqbuf->buf + seqbuf->pos, nbyte);
0047 seqbuf->pos += nbyte;
0048 return seqbuf_status(seqbuf);
0049 }
0050
0051 static int seqbuf_read_u32(struct seqbuf *seqbuf, uint32_t *v)
0052 {
0053 int err;
0054
0055 err = seqbuf_read(seqbuf, v, 4);
0056 *v = le32_to_cpu(*v);
0057 return err;
0058 }
0059
0060 static int seqbuf_read_str(struct seqbuf *seqbuf, const char **str)
0061 {
0062 *str = seqbuf->buf + seqbuf->pos;
0063 seqbuf->pos += strnlen(*str, seqbuf_avail(seqbuf));
0064 seqbuf->pos++;
0065 return seqbuf_status(seqbuf);
0066 }
0067
0068 static void seqbuf_seek(struct seqbuf *seqbuf, ssize_t offset)
0069 {
0070 seqbuf->pos += offset;
0071 }
0072
0073
0074 static const char *get_filename(struct tegra_bpmp *bpmp,
0075 const struct file *file, char *buf, int size)
0076 {
0077 const char *root_path, *filename = NULL;
0078 char *root_path_buf;
0079 size_t root_len;
0080 size_t root_path_buf_len = 512;
0081
0082 root_path_buf = kzalloc(root_path_buf_len, GFP_KERNEL);
0083 if (!root_path_buf)
0084 goto out;
0085
0086 root_path = dentry_path(bpmp->debugfs_mirror, root_path_buf,
0087 root_path_buf_len);
0088 if (IS_ERR(root_path))
0089 goto out;
0090
0091 root_len = strlen(root_path);
0092
0093 filename = dentry_path(file->f_path.dentry, buf, size);
0094 if (IS_ERR(filename)) {
0095 filename = NULL;
0096 goto out;
0097 }
0098
0099 if (strlen(filename) < root_len || strncmp(filename, root_path, root_len)) {
0100 filename = NULL;
0101 goto out;
0102 }
0103
0104 filename += root_len;
0105
0106 out:
0107 kfree(root_path_buf);
0108 return filename;
0109 }
0110
0111 static int mrq_debug_open(struct tegra_bpmp *bpmp, const char *name,
0112 uint32_t *fd, uint32_t *len, bool write)
0113 {
0114 struct mrq_debug_request req = {
0115 .cmd = cpu_to_le32(write ? CMD_DEBUG_OPEN_WO : CMD_DEBUG_OPEN_RO),
0116 };
0117 struct mrq_debug_response resp;
0118 struct tegra_bpmp_message msg = {
0119 .mrq = MRQ_DEBUG,
0120 .tx = {
0121 .data = &req,
0122 .size = sizeof(req),
0123 },
0124 .rx = {
0125 .data = &resp,
0126 .size = sizeof(resp),
0127 },
0128 };
0129 ssize_t sz_name;
0130 int err = 0;
0131
0132 sz_name = strscpy(req.fop.name, name, sizeof(req.fop.name));
0133 if (sz_name < 0) {
0134 pr_err("File name too large: %s\n", name);
0135 return -EINVAL;
0136 }
0137
0138 err = tegra_bpmp_transfer(bpmp, &msg);
0139 if (err < 0)
0140 return err;
0141 else if (msg.rx.ret < 0)
0142 return -EINVAL;
0143
0144 *len = resp.fop.datalen;
0145 *fd = resp.fop.fd;
0146
0147 return 0;
0148 }
0149
0150 static int mrq_debug_close(struct tegra_bpmp *bpmp, uint32_t fd)
0151 {
0152 struct mrq_debug_request req = {
0153 .cmd = cpu_to_le32(CMD_DEBUG_CLOSE),
0154 .frd = {
0155 .fd = fd,
0156 },
0157 };
0158 struct mrq_debug_response resp;
0159 struct tegra_bpmp_message msg = {
0160 .mrq = MRQ_DEBUG,
0161 .tx = {
0162 .data = &req,
0163 .size = sizeof(req),
0164 },
0165 .rx = {
0166 .data = &resp,
0167 .size = sizeof(resp),
0168 },
0169 };
0170 int err = 0;
0171
0172 err = tegra_bpmp_transfer(bpmp, &msg);
0173 if (err < 0)
0174 return err;
0175 else if (msg.rx.ret < 0)
0176 return -EINVAL;
0177
0178 return 0;
0179 }
0180
0181 static int mrq_debug_read(struct tegra_bpmp *bpmp, const char *name,
0182 char *data, size_t sz_data, uint32_t *nbytes)
0183 {
0184 struct mrq_debug_request req = {
0185 .cmd = cpu_to_le32(CMD_DEBUG_READ),
0186 };
0187 struct mrq_debug_response resp;
0188 struct tegra_bpmp_message msg = {
0189 .mrq = MRQ_DEBUG,
0190 .tx = {
0191 .data = &req,
0192 .size = sizeof(req),
0193 },
0194 .rx = {
0195 .data = &resp,
0196 .size = sizeof(resp),
0197 },
0198 };
0199 uint32_t fd = 0, len = 0;
0200 int remaining, err;
0201
0202 mutex_lock(&bpmp_debug_lock);
0203 err = mrq_debug_open(bpmp, name, &fd, &len, 0);
0204 if (err)
0205 goto out;
0206
0207 if (len > sz_data) {
0208 err = -EFBIG;
0209 goto close;
0210 }
0211
0212 req.frd.fd = fd;
0213 remaining = len;
0214
0215 while (remaining > 0) {
0216 err = tegra_bpmp_transfer(bpmp, &msg);
0217 if (err < 0) {
0218 goto close;
0219 } else if (msg.rx.ret < 0) {
0220 err = -EINVAL;
0221 goto close;
0222 }
0223
0224 if (resp.frd.readlen > remaining) {
0225 pr_err("%s: read data length invalid\n", __func__);
0226 err = -EINVAL;
0227 goto close;
0228 }
0229
0230 memcpy(data, resp.frd.data, resp.frd.readlen);
0231 data += resp.frd.readlen;
0232 remaining -= resp.frd.readlen;
0233 }
0234
0235 *nbytes = len;
0236
0237 close:
0238 err = mrq_debug_close(bpmp, fd);
0239 out:
0240 mutex_unlock(&bpmp_debug_lock);
0241 return err;
0242 }
0243
0244 static int mrq_debug_write(struct tegra_bpmp *bpmp, const char *name,
0245 uint8_t *data, size_t sz_data)
0246 {
0247 struct mrq_debug_request req = {
0248 .cmd = cpu_to_le32(CMD_DEBUG_WRITE)
0249 };
0250 struct mrq_debug_response resp;
0251 struct tegra_bpmp_message msg = {
0252 .mrq = MRQ_DEBUG,
0253 .tx = {
0254 .data = &req,
0255 .size = sizeof(req),
0256 },
0257 .rx = {
0258 .data = &resp,
0259 .size = sizeof(resp),
0260 },
0261 };
0262 uint32_t fd = 0, len = 0;
0263 size_t remaining;
0264 int err;
0265
0266 mutex_lock(&bpmp_debug_lock);
0267 err = mrq_debug_open(bpmp, name, &fd, &len, 1);
0268 if (err)
0269 goto out;
0270
0271 if (sz_data > len) {
0272 err = -EINVAL;
0273 goto close;
0274 }
0275
0276 req.fwr.fd = fd;
0277 remaining = sz_data;
0278
0279 while (remaining > 0) {
0280 len = min(remaining, sizeof(req.fwr.data));
0281 memcpy(req.fwr.data, data, len);
0282 req.fwr.datalen = len;
0283
0284 err = tegra_bpmp_transfer(bpmp, &msg);
0285 if (err < 0) {
0286 goto close;
0287 } else if (msg.rx.ret < 0) {
0288 err = -EINVAL;
0289 goto close;
0290 }
0291
0292 data += req.fwr.datalen;
0293 remaining -= req.fwr.datalen;
0294 }
0295
0296 close:
0297 err = mrq_debug_close(bpmp, fd);
0298 out:
0299 mutex_unlock(&bpmp_debug_lock);
0300 return err;
0301 }
0302
0303 static int bpmp_debug_show(struct seq_file *m, void *p)
0304 {
0305 struct file *file = m->private;
0306 struct inode *inode = file_inode(file);
0307 struct tegra_bpmp *bpmp = inode->i_private;
0308 char fnamebuf[256];
0309 const char *filename;
0310 struct mrq_debug_request req = {
0311 .cmd = cpu_to_le32(CMD_DEBUG_READ),
0312 };
0313 struct mrq_debug_response resp;
0314 struct tegra_bpmp_message msg = {
0315 .mrq = MRQ_DEBUG,
0316 .tx = {
0317 .data = &req,
0318 .size = sizeof(req),
0319 },
0320 .rx = {
0321 .data = &resp,
0322 .size = sizeof(resp),
0323 },
0324 };
0325 uint32_t fd = 0, len = 0;
0326 int remaining, err;
0327
0328 filename = get_filename(bpmp, file, fnamebuf, sizeof(fnamebuf));
0329 if (!filename)
0330 return -ENOENT;
0331
0332 mutex_lock(&bpmp_debug_lock);
0333 err = mrq_debug_open(bpmp, filename, &fd, &len, 0);
0334 if (err)
0335 goto out;
0336
0337 req.frd.fd = fd;
0338 remaining = len;
0339
0340 while (remaining > 0) {
0341 err = tegra_bpmp_transfer(bpmp, &msg);
0342 if (err < 0) {
0343 goto close;
0344 } else if (msg.rx.ret < 0) {
0345 err = -EINVAL;
0346 goto close;
0347 }
0348
0349 if (resp.frd.readlen > remaining) {
0350 pr_err("%s: read data length invalid\n", __func__);
0351 err = -EINVAL;
0352 goto close;
0353 }
0354
0355 seq_write(m, resp.frd.data, resp.frd.readlen);
0356 remaining -= resp.frd.readlen;
0357 }
0358
0359 close:
0360 err = mrq_debug_close(bpmp, fd);
0361 out:
0362 mutex_unlock(&bpmp_debug_lock);
0363 return err;
0364 }
0365
0366 static ssize_t bpmp_debug_store(struct file *file, const char __user *buf,
0367 size_t count, loff_t *f_pos)
0368 {
0369 struct inode *inode = file_inode(file);
0370 struct tegra_bpmp *bpmp = inode->i_private;
0371 char *databuf = NULL;
0372 char fnamebuf[256];
0373 const char *filename;
0374 ssize_t err;
0375
0376 filename = get_filename(bpmp, file, fnamebuf, sizeof(fnamebuf));
0377 if (!filename)
0378 return -ENOENT;
0379
0380 databuf = kmalloc(count, GFP_KERNEL);
0381 if (!databuf)
0382 return -ENOMEM;
0383
0384 if (copy_from_user(databuf, buf, count)) {
0385 err = -EFAULT;
0386 goto free_ret;
0387 }
0388
0389 err = mrq_debug_write(bpmp, filename, databuf, count);
0390
0391 free_ret:
0392 kfree(databuf);
0393
0394 return err ?: count;
0395 }
0396
0397 static int bpmp_debug_open(struct inode *inode, struct file *file)
0398 {
0399 return single_open_size(file, bpmp_debug_show, file, SZ_256K);
0400 }
0401
0402 static const struct file_operations bpmp_debug_fops = {
0403 .open = bpmp_debug_open,
0404 .read = seq_read,
0405 .llseek = seq_lseek,
0406 .write = bpmp_debug_store,
0407 .release = single_release,
0408 };
0409
0410 static int bpmp_populate_debugfs_inband(struct tegra_bpmp *bpmp,
0411 struct dentry *parent,
0412 char *ppath)
0413 {
0414 const size_t pathlen = SZ_256;
0415 const size_t bufsize = SZ_16K;
0416 uint32_t dsize, attrs = 0;
0417 struct dentry *dentry;
0418 struct seqbuf seqbuf;
0419 char *buf, *pathbuf;
0420 const char *name;
0421 int err = 0;
0422
0423 if (!bpmp || !parent || !ppath)
0424 return -EINVAL;
0425
0426 buf = kmalloc(bufsize, GFP_KERNEL);
0427 if (!buf)
0428 return -ENOMEM;
0429
0430 pathbuf = kzalloc(pathlen, GFP_KERNEL);
0431 if (!pathbuf) {
0432 kfree(buf);
0433 return -ENOMEM;
0434 }
0435
0436 err = mrq_debug_read(bpmp, ppath, buf, bufsize, &dsize);
0437 if (err)
0438 goto out;
0439
0440 seqbuf_init(&seqbuf, buf, dsize);
0441
0442 while (!seqbuf_eof(&seqbuf)) {
0443 err = seqbuf_read_u32(&seqbuf, &attrs);
0444 if (err)
0445 goto out;
0446
0447 err = seqbuf_read_str(&seqbuf, &name);
0448 if (err < 0)
0449 goto out;
0450
0451 if (attrs & DEBUGFS_S_ISDIR) {
0452 size_t len;
0453
0454 dentry = debugfs_create_dir(name, parent);
0455 if (IS_ERR(dentry)) {
0456 err = PTR_ERR(dentry);
0457 goto out;
0458 }
0459
0460 len = snprintf(pathbuf, pathlen, "%s%s/", ppath, name);
0461 if (len >= pathlen) {
0462 err = -EINVAL;
0463 goto out;
0464 }
0465
0466 err = bpmp_populate_debugfs_inband(bpmp, dentry,
0467 pathbuf);
0468 if (err < 0)
0469 goto out;
0470 } else {
0471 umode_t mode;
0472
0473 mode = attrs & DEBUGFS_S_IRUSR ? 0400 : 0;
0474 mode |= attrs & DEBUGFS_S_IWUSR ? 0200 : 0;
0475 dentry = debugfs_create_file(name, mode, parent, bpmp,
0476 &bpmp_debug_fops);
0477 if (IS_ERR(dentry)) {
0478 err = -ENOMEM;
0479 goto out;
0480 }
0481 }
0482 }
0483
0484 out:
0485 kfree(pathbuf);
0486 kfree(buf);
0487
0488 return err;
0489 }
0490
0491 static int mrq_debugfs_read(struct tegra_bpmp *bpmp,
0492 dma_addr_t name, size_t sz_name,
0493 dma_addr_t data, size_t sz_data,
0494 size_t *nbytes)
0495 {
0496 struct mrq_debugfs_request req = {
0497 .cmd = cpu_to_le32(CMD_DEBUGFS_READ),
0498 .fop = {
0499 .fnameaddr = cpu_to_le32((uint32_t)name),
0500 .fnamelen = cpu_to_le32((uint32_t)sz_name),
0501 .dataaddr = cpu_to_le32((uint32_t)data),
0502 .datalen = cpu_to_le32((uint32_t)sz_data),
0503 },
0504 };
0505 struct mrq_debugfs_response resp;
0506 struct tegra_bpmp_message msg = {
0507 .mrq = MRQ_DEBUGFS,
0508 .tx = {
0509 .data = &req,
0510 .size = sizeof(req),
0511 },
0512 .rx = {
0513 .data = &resp,
0514 .size = sizeof(resp),
0515 },
0516 };
0517 int err;
0518
0519 err = tegra_bpmp_transfer(bpmp, &msg);
0520 if (err < 0)
0521 return err;
0522 else if (msg.rx.ret < 0)
0523 return -EINVAL;
0524
0525 *nbytes = (size_t)resp.fop.nbytes;
0526
0527 return 0;
0528 }
0529
0530 static int mrq_debugfs_write(struct tegra_bpmp *bpmp,
0531 dma_addr_t name, size_t sz_name,
0532 dma_addr_t data, size_t sz_data)
0533 {
0534 const struct mrq_debugfs_request req = {
0535 .cmd = cpu_to_le32(CMD_DEBUGFS_WRITE),
0536 .fop = {
0537 .fnameaddr = cpu_to_le32((uint32_t)name),
0538 .fnamelen = cpu_to_le32((uint32_t)sz_name),
0539 .dataaddr = cpu_to_le32((uint32_t)data),
0540 .datalen = cpu_to_le32((uint32_t)sz_data),
0541 },
0542 };
0543 struct tegra_bpmp_message msg = {
0544 .mrq = MRQ_DEBUGFS,
0545 .tx = {
0546 .data = &req,
0547 .size = sizeof(req),
0548 },
0549 };
0550
0551 return tegra_bpmp_transfer(bpmp, &msg);
0552 }
0553
0554 static int mrq_debugfs_dumpdir(struct tegra_bpmp *bpmp, dma_addr_t addr,
0555 size_t size, size_t *nbytes)
0556 {
0557 const struct mrq_debugfs_request req = {
0558 .cmd = cpu_to_le32(CMD_DEBUGFS_DUMPDIR),
0559 .dumpdir = {
0560 .dataaddr = cpu_to_le32((uint32_t)addr),
0561 .datalen = cpu_to_le32((uint32_t)size),
0562 },
0563 };
0564 struct mrq_debugfs_response resp;
0565 struct tegra_bpmp_message msg = {
0566 .mrq = MRQ_DEBUGFS,
0567 .tx = {
0568 .data = &req,
0569 .size = sizeof(req),
0570 },
0571 .rx = {
0572 .data = &resp,
0573 .size = sizeof(resp),
0574 },
0575 };
0576 int err;
0577
0578 err = tegra_bpmp_transfer(bpmp, &msg);
0579 if (err < 0)
0580 return err;
0581 else if (msg.rx.ret < 0)
0582 return -EINVAL;
0583
0584 *nbytes = (size_t)resp.dumpdir.nbytes;
0585
0586 return 0;
0587 }
0588
0589 static int debugfs_show(struct seq_file *m, void *p)
0590 {
0591 struct file *file = m->private;
0592 struct inode *inode = file_inode(file);
0593 struct tegra_bpmp *bpmp = inode->i_private;
0594 const size_t datasize = m->size;
0595 const size_t namesize = SZ_256;
0596 void *datavirt, *namevirt;
0597 dma_addr_t dataphys, namephys;
0598 char buf[256];
0599 const char *filename;
0600 size_t len, nbytes;
0601 int err;
0602
0603 filename = get_filename(bpmp, file, buf, sizeof(buf));
0604 if (!filename)
0605 return -ENOENT;
0606
0607 namevirt = dma_alloc_coherent(bpmp->dev, namesize, &namephys,
0608 GFP_KERNEL | GFP_DMA32);
0609 if (!namevirt)
0610 return -ENOMEM;
0611
0612 datavirt = dma_alloc_coherent(bpmp->dev, datasize, &dataphys,
0613 GFP_KERNEL | GFP_DMA32);
0614 if (!datavirt) {
0615 err = -ENOMEM;
0616 goto free_namebuf;
0617 }
0618
0619 len = strlen(filename);
0620 strncpy(namevirt, filename, namesize);
0621
0622 err = mrq_debugfs_read(bpmp, namephys, len, dataphys, datasize,
0623 &nbytes);
0624
0625 if (!err)
0626 seq_write(m, datavirt, nbytes);
0627
0628 dma_free_coherent(bpmp->dev, datasize, datavirt, dataphys);
0629 free_namebuf:
0630 dma_free_coherent(bpmp->dev, namesize, namevirt, namephys);
0631
0632 return err;
0633 }
0634
0635 static int debugfs_open(struct inode *inode, struct file *file)
0636 {
0637 return single_open_size(file, debugfs_show, file, SZ_128K);
0638 }
0639
0640 static ssize_t debugfs_store(struct file *file, const char __user *buf,
0641 size_t count, loff_t *f_pos)
0642 {
0643 struct inode *inode = file_inode(file);
0644 struct tegra_bpmp *bpmp = inode->i_private;
0645 const size_t datasize = count;
0646 const size_t namesize = SZ_256;
0647 void *datavirt, *namevirt;
0648 dma_addr_t dataphys, namephys;
0649 char fnamebuf[256];
0650 const char *filename;
0651 size_t len;
0652 int err;
0653
0654 filename = get_filename(bpmp, file, fnamebuf, sizeof(fnamebuf));
0655 if (!filename)
0656 return -ENOENT;
0657
0658 namevirt = dma_alloc_coherent(bpmp->dev, namesize, &namephys,
0659 GFP_KERNEL | GFP_DMA32);
0660 if (!namevirt)
0661 return -ENOMEM;
0662
0663 datavirt = dma_alloc_coherent(bpmp->dev, datasize, &dataphys,
0664 GFP_KERNEL | GFP_DMA32);
0665 if (!datavirt) {
0666 err = -ENOMEM;
0667 goto free_namebuf;
0668 }
0669
0670 len = strlen(filename);
0671 strncpy(namevirt, filename, namesize);
0672
0673 if (copy_from_user(datavirt, buf, count)) {
0674 err = -EFAULT;
0675 goto free_databuf;
0676 }
0677
0678 err = mrq_debugfs_write(bpmp, namephys, len, dataphys,
0679 count);
0680
0681 free_databuf:
0682 dma_free_coherent(bpmp->dev, datasize, datavirt, dataphys);
0683 free_namebuf:
0684 dma_free_coherent(bpmp->dev, namesize, namevirt, namephys);
0685
0686 return err ?: count;
0687 }
0688
0689 static const struct file_operations debugfs_fops = {
0690 .open = debugfs_open,
0691 .read = seq_read,
0692 .llseek = seq_lseek,
0693 .write = debugfs_store,
0694 .release = single_release,
0695 };
0696
0697 static int bpmp_populate_dir(struct tegra_bpmp *bpmp, struct seqbuf *seqbuf,
0698 struct dentry *parent, uint32_t depth)
0699 {
0700 int err;
0701 uint32_t d, t;
0702 const char *name;
0703 struct dentry *dentry;
0704
0705 while (!seqbuf_eof(seqbuf)) {
0706 err = seqbuf_read_u32(seqbuf, &d);
0707 if (err < 0)
0708 return err;
0709
0710 if (d < depth) {
0711 seqbuf_seek(seqbuf, -4);
0712
0713 return 0;
0714 } else if (d != depth) {
0715
0716 return -EIO;
0717 }
0718
0719 err = seqbuf_read_u32(seqbuf, &t);
0720 if (err < 0)
0721 return err;
0722 err = seqbuf_read_str(seqbuf, &name);
0723 if (err < 0)
0724 return err;
0725
0726 if (t & DEBUGFS_S_ISDIR) {
0727 dentry = debugfs_create_dir(name, parent);
0728 if (IS_ERR(dentry))
0729 return -ENOMEM;
0730 err = bpmp_populate_dir(bpmp, seqbuf, dentry, depth+1);
0731 if (err < 0)
0732 return err;
0733 } else {
0734 umode_t mode;
0735
0736 mode = t & DEBUGFS_S_IRUSR ? S_IRUSR : 0;
0737 mode |= t & DEBUGFS_S_IWUSR ? S_IWUSR : 0;
0738 dentry = debugfs_create_file(name, mode,
0739 parent, bpmp,
0740 &debugfs_fops);
0741 if (IS_ERR(dentry))
0742 return -ENOMEM;
0743 }
0744 }
0745
0746 return 0;
0747 }
0748
0749 static int bpmp_populate_debugfs_shmem(struct tegra_bpmp *bpmp)
0750 {
0751 struct seqbuf seqbuf;
0752 const size_t sz = SZ_512K;
0753 dma_addr_t phys;
0754 size_t nbytes;
0755 void *virt;
0756 int err;
0757
0758 virt = dma_alloc_coherent(bpmp->dev, sz, &phys,
0759 GFP_KERNEL | GFP_DMA32);
0760 if (!virt)
0761 return -ENOMEM;
0762
0763 err = mrq_debugfs_dumpdir(bpmp, phys, sz, &nbytes);
0764 if (err < 0) {
0765 goto free;
0766 } else if (nbytes > sz) {
0767 err = -EINVAL;
0768 goto free;
0769 }
0770
0771 seqbuf_init(&seqbuf, virt, nbytes);
0772 err = bpmp_populate_dir(bpmp, &seqbuf, bpmp->debugfs_mirror, 0);
0773 free:
0774 dma_free_coherent(bpmp->dev, sz, virt, phys);
0775
0776 return err;
0777 }
0778
0779 int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp)
0780 {
0781 struct dentry *root;
0782 bool inband;
0783 int err;
0784
0785 inband = tegra_bpmp_mrq_is_supported(bpmp, MRQ_DEBUG);
0786
0787 if (!inband && !tegra_bpmp_mrq_is_supported(bpmp, MRQ_DEBUGFS))
0788 return 0;
0789
0790 root = debugfs_create_dir("bpmp", NULL);
0791 if (IS_ERR(root))
0792 return -ENOMEM;
0793
0794 bpmp->debugfs_mirror = debugfs_create_dir("debug", root);
0795 if (IS_ERR(bpmp->debugfs_mirror)) {
0796 err = -ENOMEM;
0797 goto out;
0798 }
0799
0800 if (inband)
0801 err = bpmp_populate_debugfs_inband(bpmp, bpmp->debugfs_mirror,
0802 "/");
0803 else
0804 err = bpmp_populate_debugfs_shmem(bpmp);
0805
0806 out:
0807 if (err < 0)
0808 debugfs_remove_recursive(root);
0809
0810 return err;
0811 }