bpmp-debugfs.c 16 KB

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