summaryrefslogtreecommitdiff
path: root/drivers/soc
diff options
context:
space:
mode:
authorPatrick Daly <pdaly@codeaurora.org>2016-02-25 16:10:06 -0800
committerJeevan Shriram <jshriram@codeaurora.org>2016-04-13 11:08:14 -0700
commitf0d99999f889747aeacea5a25fe07f6869c9f3e6 (patch)
treee3bea746dcd601758117647397b9553263b5b3ac /drivers/soc
parentc41f0385ee8d28857dc9bfea86f75380c0178bdc (diff)
soc: qcom: remoteqdss: Implement the new communication protocol
Replace the previous format of a unique scm call id per function to a buffer-based protocol. CRs-Fixed: 997749 Change-Id: I7738b6369e095868fa6087aac94116f4767dc168 Signed-off-by: Patrick Daly <pdaly@codeaurora.org>
Diffstat (limited to 'drivers/soc')
-rw-r--r--drivers/soc/qcom/remoteqdss.c111
1 files changed, 93 insertions, 18 deletions
diff --git a/drivers/soc/qcom/remoteqdss.c b/drivers/soc/qcom/remoteqdss.c
index bb10099db83f..e578fb1b8b47 100644
--- a/drivers/soc/qcom/remoteqdss.c
+++ b/drivers/soc/qcom/remoteqdss.c
@@ -16,6 +16,7 @@
#include <soc/qcom/scm.h>
#include <linux/debugfs.h>
#include <linux/ratelimit.h>
+#include <linux/dma-mapping.h>
#define REMOTEQDSS_FLAG_QUIET (BIT(0))
@@ -42,12 +43,58 @@ struct qdss_msg_translation {
* dir Parent debugfs directory
*/
struct remoteqdss_data {
- u8 id;
- u64 sw_entity_group;
- u64 sw_event_group;
+ uint32_t id;
+ uint32_t sw_entity_group;
+ uint32_t sw_event_group;
struct dentry *dir;
};
+static struct device dma_dev;
+
+/* Allowed message formats */
+
+enum remoteqdss_cmd_id {
+ CMD_ID_QUERY_SWEVENT_TAG,
+ CMD_ID_FILTER_SWTRACE_STATE,
+ CMD_ID_QUERY_SWTRACE_STATE,
+ CMD_ID_FILTER_SWEVENT,
+ CMD_ID_QUERY_SWEVENT,
+ CMD_ID_FILTER_SWENTITY,
+ CMD_ID_QUERY_SWENTITY,
+};
+
+struct remoteqdss_header_fmt {
+ uint32_t subsys_id;
+ uint32_t cmd_id;
+};
+
+struct remoteqdss_filter_swtrace_state_fmt {
+ struct remoteqdss_header_fmt h;
+ uint32_t state;
+};
+
+struct remoteqdss_filter_swevent_fmt {
+ struct remoteqdss_header_fmt h;
+ uint32_t event_group;
+ uint32_t event_mask;
+};
+
+struct remoteqdss_query_swevent_fmt {
+ struct remoteqdss_header_fmt h;
+ uint32_t event_group;
+};
+
+struct remoteqdss_filter_swentity_fmt {
+ struct remoteqdss_header_fmt h;
+ uint32_t entity_group;
+ uint32_t entity_mask;
+};
+
+struct remoteqdss_query_swentity_fmt {
+ struct remoteqdss_header_fmt h;
+ uint32_t entity_group;
+};
+
/* msgs is a null terminated array */
static void remoteqdss_err_translation(struct qdss_msg_translation *msgs,
u64 err)
@@ -71,9 +118,8 @@ static void remoteqdss_err_translation(struct qdss_msg_translation *msgs,
REMOTEQDSS_ERR_CALLER("Error 0x%llx\n", err);
}
-/* SCM based devices */
-#define SCM_FILTER_SWTRACE_ID (0x1)
-#define SCM_QUERY_SWTRACE_ID (0x2)
+/* Shared across all remoteqdss scm functions */
+#define SCM_CMD_ID (0x1)
/* Response Values */
#define SCM_CMD_FAIL (0x80)
@@ -118,20 +164,31 @@ static int remoteqdss_scm_query_swtrace(void *priv, u64 *val)
struct remoteqdss_data *data = priv;
int ret;
struct scm_desc desc;
+ struct remoteqdss_header_fmt *fmt;
+ dma_addr_t addr;
+
+ fmt = dma_alloc_coherent(&dma_dev, sizeof(*fmt), &addr, GFP_KERNEL);
+ if (!fmt)
+ return -ENOMEM;
+ fmt->subsys_id = data->id;
+ fmt->cmd_id = CMD_ID_QUERY_SWTRACE_STATE;
memset(&desc, 0, sizeof(desc));
- desc.args[0] = data->id;
- desc.arginfo = SCM_ARGS(1, SCM_VAL);
+ desc.args[0] = dma_to_phys(NULL, addr);
+ desc.args[1] = sizeof(*fmt);
+ desc.arginfo = SCM_ARGS(2, SCM_RO, SCM_VAL);
ret = scm_call2(
- SCM_SIP_FNID(SCM_SVC_QDSS, SCM_QUERY_SWTRACE_ID),
+ SCM_SIP_FNID(SCM_SVC_QDSS, SCM_CMD_ID),
&desc);
if (ret)
- return ret;
+ goto out;
remoteqdss_err_translation(remoteqdss_scm_msgs, desc.ret[0]);
ret = desc.ret[0] ? -EINVAL : 0;
*val = desc.ret[1];
+out:
+ dma_free_coherent(&dma_dev, sizeof(*fmt), fmt, addr);
return ret;
}
@@ -140,26 +197,37 @@ static int remoteqdss_scm_filter_swtrace(void *priv, u64 val)
struct remoteqdss_data *data = priv;
int ret;
struct scm_desc desc;
+ struct remoteqdss_filter_swtrace_state_fmt *fmt;
+ dma_addr_t addr;
+
+ fmt = dma_alloc_coherent(&dma_dev, sizeof(*fmt), &addr, GFP_KERNEL);
+ if (!fmt)
+ return -ENOMEM;
+ fmt->h.subsys_id = data->id;
+ fmt->h.cmd_id = CMD_ID_FILTER_SWTRACE_STATE;
+ fmt->state = (uint32_t)val;
memset(&desc, 0, sizeof(desc));
- desc.args[0] = data->id;
- desc.args[1] = val;
+ desc.args[0] = dma_to_phys(NULL, addr);
+ desc.args[1] = sizeof(*fmt);
desc.arginfo = SCM_ARGS(2, SCM_VAL, SCM_VAL);
ret = scm_call2(
- SCM_SIP_FNID(SCM_SVC_QDSS, SCM_FILTER_SWTRACE_ID),
+ SCM_SIP_FNID(SCM_SVC_QDSS, SCM_CMD_ID),
&desc);
if (ret)
- return ret;
+ goto out;
remoteqdss_err_translation(remoteqdss_scm_msgs, desc.ret[0]);
ret = desc.ret[0] ? -EINVAL : 0;
+out:
+ dma_free_coherent(&dma_dev, sizeof(*fmt), fmt, addr);
return ret;
}
DEFINE_SIMPLE_ATTRIBUTE(fops_sw_trace_output,
remoteqdss_scm_query_swtrace,
remoteqdss_scm_filter_swtrace,
- "%llu\n");
+ "0x%llx\n");
static void __init enumerate_scm_devices(struct dentry *parent)
{
@@ -189,12 +257,12 @@ static void __init enumerate_scm_devices(struct dentry *parent)
if (IS_ERR_OR_NULL(dentry))
goto out;
- dentry = debugfs_create_u64("sw_entity_group", S_IRUGO | S_IWUSR,
+ dentry = debugfs_create_u32("sw_entity_group", S_IRUGO | S_IWUSR,
data->dir, &data->sw_entity_group);
if (IS_ERR_OR_NULL(dentry))
goto out;
- dentry = debugfs_create_u64("sw_event_group", S_IRUGO | S_IWUSR,
+ dentry = debugfs_create_u32("sw_event_group", S_IRUGO | S_IWUSR,
data->dir, &data->sw_event_group);
if (IS_ERR_OR_NULL(dentry))
goto out;
@@ -209,6 +277,13 @@ out:
static int __init remoteqdss_init(void)
{
unsigned long old_flags = remoteqdss_dbg_flags;
+ int ret;
+
+ /* Set up DMA */
+ arch_setup_dma_ops(&dma_dev, 0, U64_MAX, NULL, false);
+ ret = dma_coerce_mask_and_coherent(&dma_dev, DMA_BIT_MASK(64));
+ if (ret)
+ return ret;
/*
* disable normal error messages while checking
@@ -225,4 +300,4 @@ static int __init remoteqdss_init(void)
remoteqdss_dbg_flags = old_flags;
return 0;
}
-module_init(remoteqdss_init);
+late_initcall(remoteqdss_init);