summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorGhanim Fodi <gfodi@codeaurora.org>2016-04-06 16:22:56 +0300
committerJeevan Shriram <jshriram@codeaurora.org>2016-04-07 15:58:58 -0700
commite7969bfba68c1f073cd7993bacc44575d59ab4c9 (patch)
tree8c628b628c314f9ec0acf61718a17e7a4707f724 /drivers
parente558c118418412734272a6b5721c822b6e578692 (diff)
msm: ipa3: add ipc logging support for ipahal
Add ipc logging capability to ipahal sublayer. Messages will be directed to ipc logging buffers which can be read from debugfs or crash dump. CRs-Fixed: 999887 Change-Id: I4ef85fc64f465aa0d4901493b80dd676596affcb Signed-off-by: Ghanim Fodi <gfodi@codeaurora.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/platform/msm/ipa/ipa_clients/ipa_usb.c64
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c106
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h49
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c13
4 files changed, 180 insertions, 52 deletions
diff --git a/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c b/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c
index 9b9ec31f34fc..a0c94c8e37ec 100644
--- a/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c
+++ b/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c
@@ -1788,6 +1788,33 @@ connect_ul_fail:
return result;
}
+static int ipa_usb_ipc_logging_init(void)
+{
+ int result;
+
+ ipa3_usb_ctx->logbuf = ipc_log_context_create(IPA_USB_IPC_LOG_PAGES,
+ "ipa_usb", 0);
+ if (ipa3_usb_ctx->logbuf == NULL) {
+ /* we can't use ipa_usb print macros on failures */
+ pr_err("ipa_usb: failed to get logbuf\n");
+ return -ENOMEM;
+ }
+
+ ipa3_usb_ctx->logbuf_low = ipc_log_context_create(IPA_USB_IPC_LOG_PAGES,
+ "ipa_usb_low", 0);
+ if (ipa3_usb_ctx->logbuf_low == NULL) {
+ pr_err("ipa_usb: failed to get logbuf_low\n");
+ result = -ENOMEM;
+ goto fail_logbuf_low;
+ }
+
+ return 0;
+
+fail_logbuf_low:
+ ipc_log_context_destroy(ipa3_usb_ctx->logbuf);
+ return result;
+}
+
#ifdef CONFIG_DEBUG_FS
static char dbg_buff[IPA_USB_MAX_MSG_LEN];
@@ -1949,7 +1976,7 @@ const struct file_operations ipa3_ipa_usb_ops = {
.read = ipa3_read_usb_state_info,
};
-void ipa_usb_debugfs_init(void)
+static void ipa_usb_debugfs_init(void)
{
const mode_t read_only_mode = S_IRUSR | S_IRGRP | S_IROTH;
const mode_t read_write_mode = S_IRUSR | S_IRGRP | S_IROTH |
@@ -1987,45 +2014,18 @@ fail:
ipa3_usb_ctx->dent = NULL;
}
-static int ipa_usb_ipc_logging_init(void)
-{
- int result;
-
- ipa3_usb_ctx->logbuf = ipc_log_context_create(IPA_USB_IPC_LOG_PAGES,
- "ipa_usb", 0);
- if (ipa3_usb_ctx->logbuf == NULL) {
- /* we can't use ipa_usb print macros on failures */
- pr_err("ipa_usb: failed to get logbuf\n");
- return -ENOMEM;
- }
-
- ipa3_usb_ctx->logbuf_low = ipc_log_context_create(IPA_USB_IPC_LOG_PAGES,
- "ipa_usb_low", 0);
- if (ipa3_usb_ctx->logbuf_low == NULL) {
- pr_err("ipa_usb: failed to get logbuf_low\n");
- result = -ENOMEM;
- goto fail_logbuf_low;
- }
-
- return 0;
-
-fail_logbuf_low:
- ipc_log_context_destroy(ipa3_usb_ctx->logbuf);
- return result;
-}
-
-void ipa_usb_debugfs_remove(void)
+static void ipa_usb_debugfs_remove(void)
{
if (IS_ERR(ipa3_usb_ctx->dent)) {
- IPA_USB_ERR("ipa_debugfs_remove: folder was not created.\n");
+ IPA_USB_ERR("ipa_usb debugfs folder was not created.\n");
return;
}
debugfs_remove_recursive(ipa3_usb_ctx->dent);
}
#else /* CONFIG_DEBUG_FS */
-void ipa_usb_debugfs_init(void){}
-void ipa_usb_debugfs_remove(void){}
+static void ipa_usb_debugfs_init(void){}
+static void ipa_usb_debugfs_remove(void){}
#endif /* CONFIG_DEBUG_FS */
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c
index 2677c9e0c83c..f7a74283056c 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c
@@ -10,6 +10,8 @@
* GNU General Public License for more details.
*/
+#include <linux/ipc_logging.h>
+#include <linux/debugfs.h>
#include "ipahal.h"
#include "ipahal_i.h"
#include "ipahal_reg_i.h"
@@ -531,7 +533,7 @@ static int ipahal_imm_cmd_init(enum ipa_hw_type ipa_hw_type)
int j;
struct ipahal_imm_cmd_obj zero_obj;
- IPAHAL_DBG("Entry - HW_TYPE=%d\n", ipa_hw_type);
+ IPAHAL_DBG_LOW("Entry - HW_TYPE=%d\n", ipa_hw_type);
memset(&zero_obj, 0, sizeof(zero_obj));
for (i = IPA_HW_v3_0 ; i < ipa_hw_type ; i++) {
@@ -592,7 +594,8 @@ u16 ipahal_imm_cmd_get_opcode(enum ipahal_imm_cmd_name cmd)
return -EFAULT;
}
- IPAHAL_DBG("Get opcode of IMM_CMD=%s\n", ipahal_imm_cmd_name_str(cmd));
+ IPAHAL_DBG_LOW("Get opcode of IMM_CMD=%s\n",
+ ipahal_imm_cmd_name_str(cmd));
opcode = ipahal_imm_cmd_objs[ipahal_ctx->hw_type][cmd].opcode;
if (opcode == -1) {
IPAHAL_ERR("Try to get opcode of obsolete IMM_CMD=%s\n",
@@ -624,7 +627,8 @@ u16 ipahal_imm_cmd_get_opcode_param(enum ipahal_imm_cmd_name cmd, int param)
return -EFAULT;
}
- IPAHAL_DBG("Get opcode of IMM_CMD=%s\n", ipahal_imm_cmd_name_str(cmd));
+ IPAHAL_DBG_LOW("Get opcode of IMM_CMD=%s\n",
+ ipahal_imm_cmd_name_str(cmd));
if (!ipahal_imm_cmd_objs[ipahal_ctx->hw_type][cmd].dyn_op) {
IPAHAL_ERR("IMM_CMD=%s does not support dynamic opcode\n",
@@ -681,7 +685,7 @@ struct ipahal_imm_cmd_pyld *ipahal_construct_imm_cmd(
return NULL;
}
- IPAHAL_DBG("construct IMM_CMD:%s\n", ipahal_imm_cmd_name_str(cmd));
+ IPAHAL_DBG_LOW("construct IMM_CMD:%s\n", ipahal_imm_cmd_name_str(cmd));
return ipahal_imm_cmd_objs[ipahal_ctx->hw_type][cmd].construct(
cmd, params, is_atomic_ctx);
}
@@ -895,7 +899,7 @@ static int ipahal_pkt_status_init(enum ipa_hw_type ipa_hw_type)
int i;
struct ipahal_pkt_status_obj zero_obj;
- IPAHAL_DBG("Entry - HW_TYPE=%d\n", ipa_hw_type);
+ IPAHAL_DBG_LOW("Entry - HW_TYPE=%d\n", ipa_hw_type);
/*
* Since structure alignment is implementation dependent,
@@ -960,7 +964,7 @@ void ipahal_pkt_status_parse(const void *unparsed_status,
return;
}
- IPAHAL_DBG("Parse Status Packet\n");
+ IPAHAL_DBG_LOW("Parse Status Packet\n");
memset(status, 0, sizeof(*status));
ipahal_pkt_status_objs[ipahal_ctx->hw_type].parse(unparsed_status,
status);
@@ -983,6 +987,72 @@ const char *ipahal_pkt_status_exception_str(
return ipahal_pkt_status_exception_to_str[exception];
}
+static int ipahal_ipc_logging_init(void)
+{
+ ipahal_ctx->ipc_logbuf =
+ ipc_log_context_create(IPAHAL_IPC_LOG_PAGES, "ipahal", 0);
+ if (!ipahal_ctx->ipc_logbuf) {
+ /* Cannot use the logging macros as no log buffers yet */
+ pr_err("ipaghal: failed to create ipc_logbuf\n");
+ return -ENOMEM;
+ }
+
+ ipahal_ctx->ipc_logbuf_low =
+ ipc_log_context_create(IPAHAL_IPC_LOG_PAGES, "ipahal_low", 0);
+ if (!ipahal_ctx->ipc_logbuf_low) {
+ /* Cannot use the logging macros as no log buffers yet */
+ pr_err("ipaghal: failed to create ipc_logbuf_low\n");
+ ipc_log_context_destroy(ipahal_ctx->ipc_logbuf);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+static void ipahal_debugfs_init(void)
+{
+ const mode_t read_write_mode = S_IRUSR | S_IRGRP | S_IROTH |
+ S_IWUSR | S_IWGRP;
+
+ ipahal_ctx->dent = debugfs_create_dir("ipahal", 0);
+ if (!ipahal_ctx->dent || IS_ERR(ipahal_ctx->dent)) {
+ IPAHAL_ERR("fail to create ipahal debugfs folder\n");
+ return;
+ }
+
+ ipahal_ctx->dfile_enable_low_prio_ipc =
+ debugfs_create_u32("enable_low_prio_log", read_write_mode,
+ ipahal_ctx->dent, &ipahal_ctx->enable_low_prio_ipc);
+ if (!ipahal_ctx->dfile_enable_low_prio_ipc ||
+ IS_ERR(ipahal_ctx->dfile_enable_low_prio_ipc)) {
+ IPAHAL_ERR("fail create enable_low_prio_log debugfs file\n");
+ goto fail;
+ }
+
+ return;
+fail:
+ debugfs_remove_recursive(ipahal_ctx->dent);
+ ipahal_ctx->dent = NULL;
+}
+
+static void ipahal_debugfs_remove(void)
+{
+ if (!ipahal_ctx)
+ return;
+
+ if (IS_ERR(ipahal_ctx->dent)) {
+ IPAHAL_ERR("ipahal debugfs folder was not created\n");
+ return;
+ }
+
+ debugfs_remove_recursive(ipahal_ctx->dent);
+}
+#else /* CONFIG_DEBUG_FS */
+static void ipahal_debugfs_init(void) {}
+static void ipahal_debugfs_remove(void) {}
+#endif /* CONFIG_DEBUG_FS */
+
int ipahal_init(enum ipa_hw_type ipa_hw_type, void __iomem *base)
{
int result;
@@ -997,16 +1067,23 @@ int ipahal_init(enum ipa_hw_type ipa_hw_type, void __iomem *base)
goto bail_err_exit;
}
+ if (ipahal_ipc_logging_init()) {
+ /* Cannot use the logging macros as no log buffers yet */
+ pr_err("ipahal: failed to initialize ipc logging\n");
+ result = -ENOMEM;
+ goto bail_free_ctx;
+ }
+
if (ipa_hw_type < IPA_HW_v3_0) {
IPAHAL_ERR("ipahal supported on IPAv3 and later only\n");
result = -EINVAL;
- goto bail_free_ctx;
+ goto bail_destroy_ipc;
}
if (!base) {
IPAHAL_ERR("invalid memory io mapping addr\n");
result = -EINVAL;
- goto bail_free_ctx;
+ goto bail_destroy_ipc;
}
ipahal_ctx->hw_type = ipa_hw_type;
@@ -1015,23 +1092,28 @@ int ipahal_init(enum ipa_hw_type ipa_hw_type, void __iomem *base)
if (ipahal_reg_init(ipa_hw_type)) {
IPAHAL_ERR("failed to init ipahal reg\n");
result = -EFAULT;
- goto bail_free_ctx;
+ goto bail_destroy_ipc;
}
if (ipahal_imm_cmd_init(ipa_hw_type)) {
IPAHAL_ERR("failed to init ipahal imm cmd\n");
result = -EFAULT;
- goto bail_free_ctx;
+ goto bail_destroy_ipc;
}
if (ipahal_pkt_status_init(ipa_hw_type)) {
IPAHAL_ERR("failed to init ipahal pkt status\n");
result = -EFAULT;
- goto bail_free_ctx;
+ goto bail_destroy_ipc;
}
+ ipahal_debugfs_init();
+
return 0;
+bail_destroy_ipc:
+ ipc_log_context_destroy(ipahal_ctx->ipc_logbuf_low);
+ ipc_log_context_destroy(ipahal_ctx->ipc_logbuf);
bail_free_ctx:
kfree(ipahal_ctx);
ipahal_ctx = NULL;
@@ -1042,7 +1124,7 @@ bail_err_exit:
void ipahal_destroy(void)
{
IPAHAL_DBG("Entry\n");
-
+ ipahal_debugfs_remove();
kfree(ipahal_ctx);
ipahal_ctx = NULL;
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h
index c5dbf0185267..3c513a7d4dc1 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h
@@ -14,20 +14,65 @@
#define _IPAHAL_I_H_
#define IPAHAL_DRV_NAME "ipahal"
+
+#define IPAHAL_IPC_LOG_PAGES 10
+#define IPAHAL_IPC_LOG(buf, fmt, args...) \
+ ipc_log_string((buf), \
+ IPAHAL_DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
+
#define IPAHAL_DBG(fmt, args...) \
- pr_debug(IPAHAL_DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
+ do { \
+ pr_debug(IPAHAL_DRV_NAME " %s:%d " fmt, \
+ __func__, __LINE__, ## args); \
+ if (likely(ipahal_ctx)) { \
+ IPAHAL_IPC_LOG(ipahal_ctx->ipc_logbuf, fmt, ## args); \
+ IPAHAL_IPC_LOG(ipahal_ctx->ipc_logbuf_low, \
+ fmt, ## args); \
+ } \
+ } while (0)
+
+#define IPAHAL_DBG_LOW(fmt, args...) \
+ do { \
+ pr_debug(IPAHAL_DRV_NAME " %s:%d " fmt, \
+ __func__, __LINE__, ## args); \
+ if (likely(ipahal_ctx) && \
+ ipahal_ctx->enable_low_prio_ipc) { \
+ IPAHAL_IPC_LOG(ipahal_ctx->ipc_logbuf_low, \
+ fmt, ## args); \
+ } \
+ } while (0)
+
#define IPAHAL_ERR(fmt, args...) \
- pr_err(IPAHAL_DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
+ do { \
+ pr_err(IPAHAL_DRV_NAME " %s:%d " fmt, \
+ __func__, __LINE__, ## args); \
+ if (likely(ipahal_ctx)) { \
+ IPAHAL_IPC_LOG(ipahal_ctx->ipc_logbuf, fmt, ## args); \
+ IPAHAL_IPC_LOG(ipahal_ctx->ipc_logbuf_low, \
+ fmt, ## args); \
+ } \
+ } while (0)
/*
* struct ipahal_context - HAL global context data
* @hw_type: IPA H/W type/version.
* @base: Base address to be used for accessing IPA memory. This is
* I/O memory mapped address.
+ * @ipc_logbuf: IPC debug logs buffer
+ * @ipc_logbuf_low: IPC Low priority debug logs buffer
+ * @enable_low_prio_ipc: Flag telling to enable low priority logging
+ * Controlled by debugfs. default is off
+ * @dent: Debugfs folder dir entry
+ * @dfile_enable_low_prio_ipc: Debugfs file for enable_low_prio_ipc
*/
struct ipahal_context {
enum ipa_hw_type hw_type;
void __iomem *base;
+ void *ipc_logbuf;
+ void *ipc_logbuf_low;
+ u32 enable_low_prio_ipc;
+ struct dentry *dent;
+ struct dentry *dfile_enable_low_prio_ipc;
};
extern struct ipahal_context *ipahal_ctx;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
index 1e5733d3101c..cf0fa16b2bbc 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
@@ -10,6 +10,7 @@
* GNU General Public License for more details.
*/
+#include <linux/ipc_logging.h>
#include <linux/init.h>
#include <linux/ipa.h>
#include <linux/kernel.h>
@@ -1064,7 +1065,7 @@ int ipahal_reg_init(enum ipa_hw_type ipa_hw_type)
int j;
struct ipahal_reg_obj zero_obj;
- IPAHAL_DBG("Entry - HW_TYPE=%d\n", ipa_hw_type);
+ IPAHAL_DBG_LOW("Entry - HW_TYPE=%d\n", ipa_hw_type);
memset(&zero_obj, 0, sizeof(zero_obj));
for (i = IPA_HW_v3_0 ; i < ipa_hw_type ; i++) {
@@ -1131,7 +1132,7 @@ u32 ipahal_read_reg_n(enum ipahal_reg_name reg, u32 n)
return -EFAULT;
}
- IPAHAL_DBG("read from %s n=%u\n",
+ IPAHAL_DBG_LOW("read from %s n=%u\n",
ipahal_reg_name_str(reg), n);
offset = ipahal_reg_objs[ipahal_ctx->hw_type][reg].offset;
@@ -1157,7 +1158,7 @@ void ipahal_write_reg_mn(enum ipahal_reg_name reg, u32 m, u32 n, u32 val)
return;
}
- IPAHAL_DBG("write to %s m=%u n=%u val=%u\n",
+ IPAHAL_DBG_LOW("write to %s m=%u n=%u val=%u\n",
ipahal_reg_name_str(reg), m, n, val);
offset = ipahal_reg_objs[ipahal_ctx->hw_type][reg].offset;
if (offset == -1) {
@@ -1197,7 +1198,7 @@ u32 ipahal_read_reg_n_fields(enum ipahal_reg_name reg, u32 n, void *fields)
return -EFAULT;
}
- IPAHAL_DBG("read from %s n=%u and parse it\n",
+ IPAHAL_DBG_LOW("read from %s n=%u and parse it\n",
ipahal_reg_name_str(reg), n);
offset = ipahal_reg_objs[ipahal_ctx->hw_type][reg].offset;
if (offset == -1) {
@@ -1232,7 +1233,7 @@ void ipahal_write_reg_n_fields(enum ipahal_reg_name reg, u32 n,
return;
}
- IPAHAL_DBG("write to %s n=%u after constructing it\n",
+ IPAHAL_DBG_LOW("write to %s n=%u after constructing it\n",
ipahal_reg_name_str(reg), n);
offset = ipahal_reg_objs[ipahal_ctx->hw_type][reg].offset;
if (offset == -1) {
@@ -1260,7 +1261,7 @@ u32 ipahal_get_reg_mn_ofst(enum ipahal_reg_name reg, u32 m, u32 n)
return -EFAULT;
}
- IPAHAL_DBG("get offset of %s m=%u n=%u\n",
+ IPAHAL_DBG_LOW("get offset of %s m=%u n=%u\n",
ipahal_reg_name_str(reg), m, n);
offset = ipahal_reg_objs[ipahal_ctx->hw_type][reg].offset;
if (offset == -1) {