Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2017, NVIDIA CORPORATION.  All rights reserved.
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 /* map filename in Linux debugfs to corresponding entry in BPMP */
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             /* go up a level */
0713             return 0;
0714         } else if (d != depth) {
0715             /* malformed data received from BPMP */
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 }