diff options
Diffstat (limited to 'drivers/media/test-drivers/visl/visl-debugfs.c')
| -rw-r--r-- | drivers/media/test-drivers/visl/visl-debugfs.c | 112 | 
1 files changed, 112 insertions, 0 deletions
diff --git a/drivers/media/test-drivers/visl/visl-debugfs.c b/drivers/media/test-drivers/visl/visl-debugfs.c new file mode 100644 index 000000000000..45f2a8268014 --- /dev/null +++ b/drivers/media/test-drivers/visl/visl-debugfs.c @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Debugfs tracing for bitstream buffers. This is similar to VA-API's + * LIBVA_TRACE_BUFDATA in that the raw bitstream can be dumped as a debugging + * aid. + * + * Produces one file per OUTPUT buffer. Files are automatically cleared on + * STREAMOFF unless the module parameter "keep_bitstream_buffers" is set. + */ + +#include <linux/debugfs.h> +#include <linux/list.h> +#include <linux/mutex.h> +#include <media/v4l2-mem2mem.h> + +#include "visl-debugfs.h" + +int visl_debugfs_init(struct visl_dev *dev) +{ +	dev->debugfs_root = debugfs_create_dir("visl", NULL); +	INIT_LIST_HEAD(&dev->bitstream_blobs); +	mutex_init(&dev->bitstream_lock); + +	if (IS_ERR(dev->debugfs_root)) +		return PTR_ERR(dev->debugfs_root); + +	return visl_debugfs_bitstream_init(dev); +} + +int visl_debugfs_bitstream_init(struct visl_dev *dev) +{ +	dev->bitstream_debugfs = debugfs_create_dir("bitstream", +						    dev->debugfs_root); +	if (IS_ERR(dev->bitstream_debugfs)) +		return PTR_ERR(dev->bitstream_debugfs); + +	return 0; +} + +void visl_trace_bitstream(struct visl_ctx *ctx, struct visl_run *run) +{ +	u8 *vaddr = vb2_plane_vaddr(&run->src->vb2_buf, 0); +	struct visl_blob *blob; +	size_t data_sz = vb2_get_plane_payload(&run->src->vb2_buf, 0); +	struct dentry *dentry; +	char name[32]; + +	blob  = kzalloc(sizeof(*blob), GFP_KERNEL); +	if (!blob) +		return; + +	blob->blob.data = vzalloc(data_sz); +	if (!blob->blob.data) +		goto err_vmalloc; + +	blob->blob.size = data_sz; +	snprintf(name, 32, "bitstream%d", run->src->sequence); + +	memcpy(blob->blob.data, vaddr, data_sz); + +	dentry = debugfs_create_blob(name, 0444, ctx->dev->bitstream_debugfs, +				     &blob->blob); +	if (IS_ERR(dentry)) +		goto err_debugfs; + +	blob->dentry = dentry; + +	mutex_lock(&ctx->dev->bitstream_lock); +	list_add_tail(&blob->list, &ctx->dev->bitstream_blobs); +	mutex_unlock(&ctx->dev->bitstream_lock); + +	return; + +err_debugfs: +	vfree(blob->blob.data); +err_vmalloc: +	kfree(blob); +} + +void visl_debugfs_clear_bitstream(struct visl_dev *dev) +{ +	struct visl_blob *blob; +	struct visl_blob *tmp; + +	mutex_lock(&dev->bitstream_lock); +	if (list_empty(&dev->bitstream_blobs)) +		goto unlock; + +	list_for_each_entry_safe(blob, tmp, &dev->bitstream_blobs, list) { +		list_del(&blob->list); +		debugfs_remove(blob->dentry); +		vfree(blob->blob.data); +		kfree(blob); +	} + +unlock: +	mutex_unlock(&dev->bitstream_lock); +} + +void visl_debugfs_bitstream_deinit(struct visl_dev *dev) +{ +	visl_debugfs_clear_bitstream(dev); +	debugfs_remove_recursive(dev->bitstream_debugfs); +	dev->bitstream_debugfs = NULL; +} + +void visl_debugfs_deinit(struct visl_dev *dev) +{ +	visl_debugfs_bitstream_deinit(dev); +	debugfs_remove_recursive(dev->debugfs_root); +	dev->debugfs_root = NULL; +}  |