diff options
| author | Bhalchandra Gajare <gajare@codeaurora.org> | 2016-09-08 16:56:01 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-10-18 16:03:13 -0700 |
| commit | 4f284f6dbbbfb2501d8bc4deba1a19bc16922ad2 (patch) | |
| tree | 52c80708e219b0d285dcb30206af0f2446392e11 | |
| parent | c6b7d9674c413431a6622844bdcbfc8a7f2942df (diff) | |
ASoC: wcd-spi: Add memory read debug support
To help debugging, change adds support to read address and size from
the debugfs nodes and provide the memory content through the
mem_read debugfs node.
CRs-Fixed: 1064870
Change-Id: I151bc5d373129e3599baf6d3217b65843c0f16d0
Signed-off-by: Bhalchandra Gajare <gajare@codeaurora.org>
| -rw-r--r-- | sound/soc/codecs/wcd-spi.c | 80 |
1 files changed, 75 insertions, 5 deletions
diff --git a/sound/soc/codecs/wcd-spi.c b/sound/soc/codecs/wcd-spi.c index 0a9c283c250c..77504a5cd885 100644 --- a/sound/soc/codecs/wcd-spi.c +++ b/sound/soc/codecs/wcd-spi.c @@ -104,6 +104,12 @@ mutex_unlock(&lock); \ } +struct wcd_spi_debug_data { + struct dentry *dir; + u32 addr; + u32 size; +}; + struct wcd_spi_priv { struct spi_device *spi; u32 mem_base_addr; @@ -133,6 +139,9 @@ struct wcd_spi_priv { struct device *m_dev; struct wdsp_mgr_ops *m_ops; + + /* Debugfs related information */ + struct wcd_spi_debug_data debug_data; }; enum xfer_request { @@ -1012,20 +1021,81 @@ static const struct file_operations state_fops = { .release = single_release, }; +static ssize_t wcd_spi_debugfs_mem_read(struct file *file, char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct spi_device *spi = file->private_data; + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + struct wcd_spi_debug_data *dbg_data = &wcd_spi->debug_data; + struct wcd_spi_msg msg; + ssize_t buf_size, read_count = 0; + char *buf; + int ret; + + if (*ppos < 0 || !count) + return -EINVAL; + + if (dbg_data->size == 0 || dbg_data->addr == 0) { + dev_err(&spi->dev, + "%s: Invalid request, size = %u, addr = 0x%x\n", + __func__, dbg_data->size, dbg_data->addr); + return 0; + } + + buf_size = count < dbg_data->size ? count : dbg_data->size; + buf = kzalloc(buf_size, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + msg.data = buf; + msg.remote_addr = dbg_data->addr; + msg.len = buf_size; + msg.flags = 0; + + ret = wcd_spi_data_read(spi, &msg); + if (IS_ERR_VALUE(ret)) { + dev_err(&spi->dev, + "%s: Failed to read %zu bytes from addr 0x%x\n", + __func__, buf_size, msg.remote_addr); + goto done; + } + + read_count = simple_read_from_buffer(ubuf, count, ppos, buf, buf_size); + +done: + kfree(buf); + if (ret < 0) + return ret; + else + return read_count; +} + +static const struct file_operations mem_read_fops = { + .open = simple_open, + .read = wcd_spi_debugfs_mem_read, +}; + static int wcd_spi_debugfs_init(struct spi_device *spi) { + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + struct wcd_spi_debug_data *dbg_data = &wcd_spi->debug_data; int rc = 0; - struct dentry *dir; - dir = debugfs_create_dir("wcd_spi", NULL); - if (IS_ERR_OR_NULL(dir)) { - dir = NULL; + dbg_data->dir = debugfs_create_dir("wcd_spi", NULL); + if (IS_ERR_OR_NULL(dbg_data->dir)) { + dbg_data->dir = NULL; rc = -ENODEV; goto done; } - debugfs_create_file("state", 0444, dir, spi, &state_fops); + debugfs_create_file("state", 0444, dbg_data->dir, spi, &state_fops); + debugfs_create_u32("addr", S_IRUGO | S_IWUSR, dbg_data->dir, + &dbg_data->addr); + debugfs_create_u32("size", S_IRUGO | S_IWUSR, dbg_data->dir, + &dbg_data->size); + debugfs_create_file("mem_read", S_IRUGO, dbg_data->dir, + spi, &mem_read_fops); done: return rc; } |
