Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8bca26f8 authored by Jilai Wang's avatar Jilai Wang Committed by Gerrit - the friendly Code Review server
Browse files

msm: npu: Use different functions for register node



Register node in debugfs needs to free buffer in release function
which is allocated while reading registers.

Change-Id: I39a3bd94e6659ba5201c0984248558bd2a3e887c
Signed-off-by: default avatarJilai Wang <jilaiw@codeaurora.org>
parent a835d13f
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -102,8 +102,6 @@ struct npu_debugfs_ctx {
	struct dentry *root;
	uint32_t reg_off;
	uint32_t reg_cnt;
	char *buf;
	size_t buf_len;
	uint8_t *log_buf;
	struct mutex log_lock;
	uint32_t log_num_bytes_buffered;
@@ -112,6 +110,12 @@ struct npu_debugfs_ctx {
	uint32_t log_buf_size;
};

struct npu_debugfs_reg_ctx {
	char *buf;
	size_t buf_len;
	struct npu_device *npu_dev;
};

struct npu_mbox {
	struct mbox_client client;
	struct mbox_chan *chan;
+42 −22
Original line number Diff line number Diff line
/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -34,6 +34,8 @@
 */
static int npu_debug_open(struct inode *inode, struct file *file);
static int npu_debug_release(struct inode *inode, struct file *file);
static int npu_debug_reg_open(struct inode *inode, struct file *file);
static int npu_debug_reg_release(struct inode *inode, struct file *file);
static ssize_t npu_debug_reg_write(struct file *file,
		const char __user *user_buf, size_t count, loff_t *ppos);
static ssize_t npu_debug_reg_read(struct file *file,
@@ -54,8 +56,8 @@ static ssize_t npu_debug_ctrl_write(struct file *file,
struct npu_device *g_npu_dev;

static const struct file_operations npu_reg_fops = {
	.open = npu_debug_open,
	.release = npu_debug_release,
	.open = npu_debug_reg_open,
	.release = npu_debug_reg_release,
	.read = npu_debug_reg_read,
	.write = npu_debug_reg_write,
};
@@ -95,14 +97,31 @@ static int npu_debug_open(struct inode *inode, struct file *file)

static int npu_debug_release(struct inode *inode, struct file *file)
{
	struct npu_device *npu_dev = file->private_data;
	struct npu_debugfs_ctx *debugfs;
	return 0;
}

	debugfs = &npu_dev->debugfs_ctx;
static int npu_debug_reg_open(struct inode *inode, struct file *file)
{
	struct npu_debugfs_reg_ctx *reg_ctx;

	reg_ctx = kzalloc(sizeof(*reg_ctx), GFP_KERNEL);
	if (!reg_ctx)
		return -ENOMEM;

	kfree(debugfs->buf);
	debugfs->buf_len = 0;
	debugfs->buf = NULL;
	/* non-seekable */
	file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
	reg_ctx->npu_dev = inode->i_private;
	file->private_data = reg_ctx;
	return 0;
}

static int npu_debug_reg_release(struct inode *inode, struct file *file)
{
	struct npu_debugfs_reg_ctx *reg_ctx = file->private_data;

	kfree(reg_ctx->buf);
	kfree(reg_ctx);
	file->private_data = NULL;
	return 0;
}

@@ -148,7 +167,8 @@ static ssize_t npu_debug_reg_write(struct file *file,
static ssize_t npu_debug_reg_read(struct file *file,
			char __user *user_buf, size_t count, loff_t *ppos)
{
	struct npu_device *npu_dev = file->private_data;
	struct npu_debugfs_reg_ctx *reg_ctx = file->private_data;
	struct npu_device *npu_dev = reg_ctx->npu_dev;
	struct npu_debugfs_ctx *debugfs;
	size_t len;

@@ -157,16 +177,16 @@ static ssize_t npu_debug_reg_read(struct file *file,
	if (debugfs->reg_cnt == 0)
		return 0;

	if (!debugfs->buf) {
	if (!reg_ctx->buf) {
		char dump_buf[64];
		char *ptr;
		int cnt, tot, off;

		debugfs->buf_len = sizeof(dump_buf) *
		reg_ctx->buf_len = sizeof(dump_buf) *
			DIV_ROUND_UP(debugfs->reg_cnt, ROW_BYTES);
		debugfs->buf = kzalloc(debugfs->buf_len, GFP_KERNEL);
		reg_ctx->buf = kzalloc(reg_ctx->buf_len, GFP_KERNEL);

		if (!debugfs->buf)
		if (!reg_ctx->buf)
			return -ENOMEM;

		ptr = npu_dev->core_io.base + debugfs->reg_off;
@@ -180,28 +200,28 @@ static ssize_t npu_debug_reg_read(struct file *file,
			hex_dump_to_buffer(ptr, min(cnt, ROW_BYTES),
					   ROW_BYTES, GROUP_BYTES, dump_buf,
					   sizeof(dump_buf), false);
			len = scnprintf(debugfs->buf + tot,
				debugfs->buf_len - tot, "0x%08x: %s\n",
			len = scnprintf(reg_ctx->buf + tot,
				reg_ctx->buf_len - tot, "0x%08x: %s\n",
				((int) (unsigned long) ptr) -
				((int) (unsigned long) npu_dev->core_io.base),
				dump_buf);

			ptr += ROW_BYTES;
			tot += len;
			if (tot >= debugfs->buf_len)
			if (tot >= reg_ctx->buf_len)
				break;
		}
		npu_disable_core_power(npu_dev);

		debugfs->buf_len = tot;
		reg_ctx->buf_len = tot;
	}

	if (*ppos >= debugfs->buf_len)
	if (*ppos >= reg_ctx->buf_len)
		return 0; /* done reading */

	len = min(count, debugfs->buf_len - (size_t) *ppos);
	pr_debug("read %zi %zi\n", count, debugfs->buf_len - (size_t) *ppos);
	if (copy_to_user(user_buf, debugfs->buf + *ppos, len)) {
	len = min(count, reg_ctx->buf_len - (size_t) *ppos);
	pr_debug("read %zi %zi\n", count, reg_ctx->buf_len - (size_t) *ppos);
	if (copy_to_user(user_buf, reg_ctx->buf + *ppos, len)) {
		pr_err("failed to copy to user\n");
		return -EFAULT;
	}