1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Debugfs tracing for bitstream buffers. This is similar to VA-API's 4 * LIBVA_TRACE_BUFDATA in that the raw bitstream can be dumped as a debugging 5 * aid. 6 * 7 * Produces one file per OUTPUT buffer. Files are automatically cleared on 8 * STREAMOFF unless the module parameter "keep_bitstream_buffers" is set. 9 */ 10 11 #include <linux/debugfs.h> 12 #include <linux/list.h> 13 #include <linux/mutex.h> 14 #include <media/v4l2-mem2mem.h> 15 16 #include "visl-debugfs.h" 17 18 int visl_debugfs_init(struct visl_dev *dev) 19 { 20 dev->debugfs_root = debugfs_create_dir("visl", NULL); 21 INIT_LIST_HEAD(&dev->bitstream_blobs); 22 mutex_init(&dev->bitstream_lock); 23 24 if (IS_ERR(dev->debugfs_root)) 25 return PTR_ERR(dev->debugfs_root); 26 27 return visl_debugfs_bitstream_init(dev); 28 } 29 30 int visl_debugfs_bitstream_init(struct visl_dev *dev) 31 { 32 dev->bitstream_debugfs = debugfs_create_dir("bitstream", 33 dev->debugfs_root); 34 if (IS_ERR(dev->bitstream_debugfs)) 35 return PTR_ERR(dev->bitstream_debugfs); 36 37 return 0; 38 } 39 40 void visl_trace_bitstream(struct visl_ctx *ctx, struct visl_run *run) 41 { 42 u8 *vaddr = vb2_plane_vaddr(&run->src->vb2_buf, 0); 43 struct visl_blob *blob; 44 size_t data_sz = vb2_get_plane_payload(&run->src->vb2_buf, 0); 45 struct dentry *dentry; 46 char name[32]; 47 48 blob = kzalloc(sizeof(*blob), GFP_KERNEL); 49 if (!blob) 50 return; 51 52 blob->blob.data = vzalloc(data_sz); 53 if (!blob->blob.data) 54 goto err_vmalloc; 55 56 blob->blob.size = data_sz; 57 snprintf(name, 32, "bitstream%d", run->src->sequence); 58 59 memcpy(blob->blob.data, vaddr, data_sz); 60 61 dentry = debugfs_create_blob(name, 0444, ctx->dev->bitstream_debugfs, 62 &blob->blob); 63 if (IS_ERR(dentry)) 64 goto err_debugfs; 65 66 blob->dentry = dentry; 67 68 mutex_lock(&ctx->dev->bitstream_lock); 69 list_add_tail(&blob->list, &ctx->dev->bitstream_blobs); 70 mutex_unlock(&ctx->dev->bitstream_lock); 71 72 return; 73 74 err_debugfs: 75 vfree(blob->blob.data); 76 err_vmalloc: 77 kfree(blob); 78 } 79 80 void visl_debugfs_clear_bitstream(struct visl_dev *dev) 81 { 82 struct visl_blob *blob; 83 struct visl_blob *tmp; 84 85 mutex_lock(&dev->bitstream_lock); 86 if (list_empty(&dev->bitstream_blobs)) 87 goto unlock; 88 89 list_for_each_entry_safe(blob, tmp, &dev->bitstream_blobs, list) { 90 list_del(&blob->list); 91 debugfs_remove(blob->dentry); 92 vfree(blob->blob.data); 93 kfree(blob); 94 } 95 96 unlock: 97 mutex_unlock(&dev->bitstream_lock); 98 } 99 100 void visl_debugfs_bitstream_deinit(struct visl_dev *dev) 101 { 102 visl_debugfs_clear_bitstream(dev); 103 debugfs_remove_recursive(dev->bitstream_debugfs); 104 dev->bitstream_debugfs = NULL; 105 } 106 107 void visl_debugfs_deinit(struct visl_dev *dev) 108 { 109 visl_debugfs_bitstream_deinit(dev); 110 debugfs_remove_recursive(dev->debugfs_root); 111 dev->debugfs_root = NULL; 112 } 113