From dd2d22f7b7e7fb41428e17fba0f2e11a36f08288 Mon Sep 17 00:00:00 2001 From: Sathish Ambley Date: Thu, 19 Jan 2017 10:32:55 -0800 Subject: [PATCH 1/2] msm: ADSPRPC: Expose information about open devices Using Debugfs virtual file system to make debug information available to userspace. A directory called adsprpc is created in debugfs root directory and a debugfs file is created in this directory for every device open in the fastrpc driver. Change-Id: Ie944424e30ddc810ff29116481d63b266c47c037 Acked-by: Vishnu Karthik Signed-off-by: Sathish Ambley --- drivers/char/adsprpc.c | 130 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 03429b18825b..230856c90736 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -48,6 +48,7 @@ #include "adsprpc_compat.h" #include "adsprpc_shared.h" #include +#include #define TZ_PIL_PROTECT_MEM_SUBSYS_ID 0x0C #define TZ_PIL_CLEAR_PROTECT_MEM_SUBSYS_ID 0x0D @@ -55,6 +56,7 @@ #define ADSP_MMAP_HEAP_ADDR 4 #define FASTRPC_ENOSUCH 39 #define VMID_SSC_Q6 5 +#define DEBUGFS_SIZE 1024 #define RPC_TIMEOUT (5 * HZ) #define BALIGN 128 @@ -90,6 +92,8 @@ static int fastrpc_glink_open(int cid); static void fastrpc_glink_close(void *chan, int cid); +static struct dentry *debugfs_root; +static struct dentry *debugfs_global_file; static inline uint64_t buf_page_start(uint64_t buf) { @@ -283,6 +287,7 @@ struct fastrpc_file { int pd; struct fastrpc_apps *apps; struct fastrpc_perf perf; + struct dentry *debugfs_file; }; static struct fastrpc_apps gfa; @@ -2042,6 +2047,8 @@ static int fastrpc_device_release(struct inode *inode, struct file *file) struct fastrpc_file *fl = (struct fastrpc_file *)file->private_data; if (fl) { + if (fl->debugfs_file != NULL) + debugfs_remove(fl->debugfs_file); fastrpc_file_free(fl); file->private_data = 0; } @@ -2158,9 +2165,124 @@ bail: return err; } +static int fastrpc_debugfs_open(struct inode *inode, struct file *filp) +{ + filp->private_data = inode->i_private; + return 0; +} + +static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer, + size_t count, loff_t *position) +{ + struct fastrpc_file *fl = filp->private_data; + struct hlist_node *n; + struct fastrpc_buf *buf = 0; + struct fastrpc_mmap *map = 0; + struct smq_invoke_ctx *ictx = 0; + struct fastrpc_channel_ctx *chan; + struct fastrpc_session_ctx *sess; + unsigned int len = 0; + int i, j, ret = 0; + char *fileinfo = NULL; + + fileinfo = kzalloc(DEBUGFS_SIZE, GFP_KERNEL); + if (!fileinfo) + goto bail; + if (fl == NULL) { + for (i = 0; i < NUM_CHANNELS; i++) { + chan = &gcinfo[i]; + len += scnprintf(fileinfo + len, + DEBUGFS_SIZE - len, "%s\n\n", + chan->name); + len += scnprintf(fileinfo + len, + DEBUGFS_SIZE - len, "%s %d\n", + "sesscount:", chan->sesscount); + for (j = 0; j < chan->sesscount; j++) { + sess = &chan->session[j]; + len += scnprintf(fileinfo + len, + DEBUGFS_SIZE - len, + "%s%d\n\n", "SESSION", j); + len += scnprintf(fileinfo + len, + DEBUGFS_SIZE - len, + "%s %d\n", "sid:", + sess->smmu.cb); + len += scnprintf(fileinfo + len, + DEBUGFS_SIZE - len, + "%s %d\n", "SECURE:", + sess->smmu.secure); + } + } + } else { + len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len, + "%s %d\n\n", + "PROCESS_ID:", fl->tgid); + len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len, + "%s %d\n\n", + "CHANNEL_ID:", fl->cid); + len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len, + "%s %d\n\n", + "SSRCOUNT:", fl->ssrcount); + len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len, + "%s\n", + "LIST OF BUFS:"); + spin_lock(&fl->hlock); + hlist_for_each_entry_safe(buf, n, &fl->bufs, hn) { + len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len, + "%s %p %s %p %s %llx\n", "buf:", + buf, "buf->virt:", buf->virt, + "buf->phys:", buf->phys); + } + len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len, + "\n%s\n", + "LIST OF MAPS:"); + hlist_for_each_entry_safe(map, n, &fl->maps, hn) { + len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len, + "%s %p %s %lx %s %llx\n", + "map:", map, + "map->va:", map->va, + "map->phys:", map->phys); + } + len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len, + "\n%s\n", + "LIST OF PENDING SMQCONTEXTS:"); + hlist_for_each_entry_safe(ictx, n, &fl->clst.pending, hn) { + len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len, + "%s %p %s %u %s %u %s %u\n", + "smqcontext:", ictx, + "sc:", ictx->sc, + "tid:", ictx->pid, + "handle", ictx->rpra->h); + } + len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len, + "\n%s\n", + "LIST OF INTERRUPTED SMQCONTEXTS:"); + hlist_for_each_entry_safe(ictx, n, &fl->clst.interrupted, hn) { + len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len, + "%s %p %s %u %s %u %s %u\n", + "smqcontext:", ictx, + "sc:", ictx->sc, + "tid:", ictx->pid, + "handle", ictx->rpra->h); + } + spin_unlock(&fl->hlock); + } + if (len > DEBUGFS_SIZE) + len = DEBUGFS_SIZE; + ret = simple_read_from_buffer(buffer, count, position, fileinfo, len); + kfree(fileinfo); +bail: + return ret; +} + +static const struct file_operations debugfs_fops = { + .open = fastrpc_debugfs_open, + .read = fastrpc_debugfs_read, +}; + static int fastrpc_device_open(struct inode *inode, struct file *filp) { int cid = MINOR(inode->i_rdev); + struct dentry *debugfs_file; int err = 0; struct fastrpc_apps *me = &gfa; struct fastrpc_file *fl = 0; @@ -2173,6 +2295,8 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) mutex_lock(&me->smd_mutex); + debugfs_file = debugfs_create_file(current->comm, 0644, debugfs_root, + fl, &debugfs_fops); context_list_ctor(&fl->clst); spin_lock_init(&fl->hlock); INIT_HLIST_HEAD(&fl->maps); @@ -2181,6 +2305,8 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) fl->tgid = current->tgid; fl->apps = me; fl->cid = cid; + if (debugfs_file != NULL) + fl->debugfs_file = debugfs_file; memset(&fl->perf, 0, sizeof(fl->perf)); VERIFY(err, !fastrpc_session_alloc_locked(&me->channel[cid], 0, @@ -2496,6 +2622,8 @@ static int fastrpc_cb_probe(struct device *dev) sess->dev = dev; sess->smmu.enabled = 1; chan->sesscount++; + debugfs_global_file = debugfs_create_file("global", 0644, debugfs_root, + NULL, &debugfs_fops); bail: return err; } @@ -2706,6 +2834,7 @@ static int __init fastrpc_device_init(void) VERIFY(err, !IS_ERR_OR_NULL(me->client)); if (err) goto device_create_bail; + debugfs_root = debugfs_create_dir("adsprpc", NULL); return 0; device_create_bail: for (i = 0; i < NUM_CHANNELS; i++) { @@ -2744,6 +2873,7 @@ static void __exit fastrpc_device_exit(void) cdev_del(&me->cdev); unregister_chrdev_region(me->dev_no, NUM_CHANNELS); ion_client_destroy(me->client); + debugfs_remove_recursive(debugfs_root); } late_initcall(fastrpc_device_init); From 99f5e59bf550cd86efc87208c9833ad08987fc24 Mon Sep 17 00:00:00 2001 From: Sathish Ambley Date: Mon, 9 Jan 2017 22:33:59 -0800 Subject: [PATCH 2/2] msm: ADSPRPC: Remove references to SMD SMD is being removed from defconfig of SDM660. All the references to SMD like macros and header files are removed from fastrpc driver. Change-Id: Iaa961e7faee4b59562fc92133c5154027c325f53 Acked-by: Vishnu Karthik Signed-off-by: Sathish Ambley --- drivers/char/Kconfig | 2 +- drivers/char/adsprpc.c | 97 +++++++----------------------------------- 2 files changed, 16 insertions(+), 83 deletions(-) diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 8e3bff9c7fe9..ebbe31fee7ae 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -607,7 +607,7 @@ source "drivers/char/xillybus/Kconfig" config MSM_ADSPRPC tristate "QTI ADSP RPC driver" - depends on MSM_SMD + depends on MSM_GLINK help Provides a communication mechanism that allows for clients to make remote method invocations across processor boundary to diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 230856c90736..95dca75efde9 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -211,7 +210,6 @@ struct fastrpc_channel_ctx { struct completion work; struct notifier_block nb; struct kref kref; - int channel; int sesscount; int ssrcount; void *handle; @@ -235,7 +233,6 @@ struct fastrpc_apps { spinlock_t hlock; struct ion_client *client; struct device *dev; - bool glink; }; struct fastrpc_mmap { @@ -296,21 +293,18 @@ static struct fastrpc_channel_ctx gcinfo[NUM_CHANNELS] = { { .name = "adsprpc-smd", .subsys = "adsp", - .channel = SMD_APPS_QDSP, .link.link_info.edge = "lpass", .link.link_info.transport = "smem", }, { .name = "mdsprpc-smd", .subsys = "modem", - .channel = SMD_APPS_MODEM, .link.link_info.edge = "mpss", .link.link_info.transport = "smem", }, { .name = "sdsprpc-smd", .subsys = "slpi", - .channel = SMD_APPS_DSPS, .link.link_info.edge = "dsps", .link.link_info.transport = "smem", .vmid = VMID_SSC_Q6, @@ -1353,7 +1347,7 @@ static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx, struct smq_msg *msg = &ctx->msg; struct fastrpc_file *fl = ctx->fl; struct fastrpc_channel_ctx *channel_ctx = &fl->apps->channel[fl->cid]; - int err = 0, len; + int err = 0; VERIFY(err, 0 != channel_ctx->chan); if (err) @@ -1368,64 +1362,21 @@ static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx, msg->invoke.page.addr = ctx->buf ? ctx->buf->phys : 0; msg->invoke.page.size = buf_page_size(ctx->used); - if (fl->apps->glink) { - if (fl->ssrcount != channel_ctx->ssrcount) { - err = -ECONNRESET; - goto bail; - } - VERIFY(err, channel_ctx->link.port_state == - FASTRPC_LINK_CONNECTED); - if (err) - goto bail; - err = glink_tx(channel_ctx->chan, - (void *)&fl->apps->channel[fl->cid], msg, sizeof(*msg), - GLINK_TX_REQ_INTENT); - } else { - spin_lock(&fl->apps->hlock); - len = smd_write((smd_channel_t *) - channel_ctx->chan, - msg, sizeof(*msg)); - spin_unlock(&fl->apps->hlock); - VERIFY(err, len == sizeof(*msg)); + if (fl->ssrcount != channel_ctx->ssrcount) { + err = -ECONNRESET; + goto bail; } + VERIFY(err, channel_ctx->link.port_state == + FASTRPC_LINK_CONNECTED); + if (err) + goto bail; + err = glink_tx(channel_ctx->chan, + (void *)&fl->apps->channel[fl->cid], msg, sizeof(*msg), + GLINK_TX_REQ_INTENT); bail: return err; } -static void fastrpc_smd_read_handler(int cid) -{ - struct fastrpc_apps *me = &gfa; - struct smq_invoke_rsp rsp = {0}; - int ret = 0; - - do { - ret = smd_read_from_cb(me->channel[cid].chan, &rsp, - sizeof(rsp)); - if (ret != sizeof(rsp)) - break; - rsp.ctx = rsp.ctx & ~1; - context_notify_user(uint64_to_ptr(rsp.ctx), rsp.retval); - } while (ret == sizeof(rsp)); -} - -static void smd_event_handler(void *priv, unsigned event) -{ - struct fastrpc_apps *me = &gfa; - int cid = (int)(uintptr_t)priv; - - switch (event) { - case SMD_EVENT_OPEN: - complete(&me->channel[cid].work); - break; - case SMD_EVENT_CLOSE: - fastrpc_notify_drivers(me, cid); - break; - case SMD_EVENT_DATA: - fastrpc_smd_read_handler(cid); - break; - } -} - static void fastrpc_init(struct fastrpc_apps *me) { int i; @@ -1888,11 +1839,7 @@ static void fastrpc_channel_close(struct kref *kref) ctx = container_of(kref, struct fastrpc_channel_ctx, kref); cid = ctx - &gcinfo[0]; - if (!me->glink) { - smd_close(ctx->chan); - } else { - fastrpc_glink_close(ctx->chan, cid); - } + fastrpc_glink_close(ctx->chan, cid); ctx->chan = 0; mutex_unlock(&me->smd_mutex); pr_info("'closed /dev/%s c %d %d'\n", gcinfo[cid].name, @@ -2317,16 +2264,8 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) fl->ssrcount = me->channel[cid].ssrcount; if ((kref_get_unless_zero(&me->channel[cid].kref) == 0) || (me->channel[cid].chan == 0)) { - if (me->glink) { - fastrpc_glink_register(cid, me); - VERIFY(err, 0 == fastrpc_glink_open(cid)); - } else { - VERIFY(err, !smd_named_open_on_edge(FASTRPC_SMD_GUID, - gcinfo[cid].channel, - (smd_channel_t **)&me->channel[cid].chan, - (void *)(uintptr_t)cid, - smd_event_handler)); - } + fastrpc_glink_register(cid, me); + VERIFY(err, 0 == fastrpc_glink_open(cid)); if (err) goto bail; @@ -2513,11 +2452,7 @@ static int fastrpc_restart_notifier_cb(struct notifier_block *nb, mutex_lock(&me->smd_mutex); ctx->ssrcount++; if (ctx->chan) { - if (me->glink) { - fastrpc_glink_close(ctx->chan, cid); - } else { - smd_close(ctx->chan); - } + fastrpc_glink_close(ctx->chan, cid); ctx->chan = 0; pr_info("'restart notifier: closed /dev/%s c %d %d'\n", gcinfo[cid].name, MAJOR(me->dev_no), cid); @@ -2738,8 +2673,6 @@ static int fastrpc_probe(struct platform_device *pdev) return 0; } - me->glink = of_property_read_bool(dev->of_node, "qcom,fastrpc-glink"); - VERIFY(err, !of_platform_populate(pdev->dev.of_node, fastrpc_match_table, NULL, &pdev->dev));