Browse Source

Merge "msm: ipa3: Initial version of minidump support in IPA"

qctecmdr 2 years ago
parent
commit
e7b629ee85

+ 29 - 0
drivers/platform/msm/gsi/gsi.c

@@ -25,6 +25,7 @@
 #include <linux/wait.h>
 #include <linux/delay.h>
 #include <linux/version.h>
+#include <soc/qcom/minidump.h>
 
 #define CREATE_TRACE_POINTS
 #include "gsi_trace.h"
@@ -5829,6 +5830,25 @@ int gsi_get_fw_version(struct gsi_fw_version *ver)
 	return 0;
 }
 
+#if IS_ENABLED(CONFIG_QCOM_VA_MINIDUMP)
+static int qcom_va_md_gsi_notif_handler(struct notifier_block *this,
+				unsigned long event, void *ptr)
+{
+	struct va_md_entry entry;
+
+	strlcpy(entry.owner, "gsi_mini", sizeof(entry.owner));
+	entry.vaddr = (unsigned long)gsi_ctx;
+	entry.size = sizeof(struct gsi_ctx);
+	qcom_va_md_add_region(&entry);
+	return NOTIFY_OK;
+}
+
+static struct notifier_block qcom_va_md_gsi_notif_blk = {
+        .notifier_call = qcom_va_md_gsi_notif_handler,
+        .priority = INT_MAX,
+};
+#endif
+
 static int msm_gsi_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -5861,6 +5881,15 @@ static int msm_gsi_probe(struct platform_device *pdev)
 	init_completion(&gsi_ctx->gen_ee_cmd_compl);
 	gsi_debugfs_init();
 
+#if IS_ENABLED(CONFIG_QCOM_VA_MINIDUMP)
+	result = qcom_va_md_register("gsi_mini", &qcom_va_md_gsi_notif_blk);
+
+	if(result)
+		GSIERR("gsi mini qcom_va_md_register failed = %d\n", result);
+	else
+		GSIDBG("gsi mini qcom_va_md_register success\n");
+#endif
+
 	return 0;
 }
 

+ 13 - 2
drivers/platform/msm/ipa/ipa_v3/dump/ipa4.5/ipa_reg_dump.c

@@ -1839,7 +1839,9 @@ static void ipa_hal_save_regs_save_ipa_testbus(void)
 int ipa_reg_save_init(u32 value)
 {
 	u32 i, num_regs = ARRAY_SIZE(ipa_regs_to_save_array);
-
+#if IS_ENABLED(CONFIG_QCOM_VA_MINIDUMP)
+	struct ipa_minidump_data *mini_dump;
+#endif
 	if (!ipa3_ctx->do_register_collection_on_crash)
 		return 0;
 
@@ -1927,7 +1929,16 @@ int ipa_reg_save_init(u32 value)
 			goto alloc_fail2;
 		}
 	}
-
+#if IS_ENABLED(CONFIG_QCOM_VA_MINIDUMP)
+	/*Adding ipa_reg_save pointer to minidump list*/
+	mini_dump = (struct ipa_minidump_data *)kzalloc(sizeof(struct ipa_minidump_data), GFP_KERNEL);
+	if (mini_dump != NULL) {
+		strlcpy(mini_dump->data.owner, "ipa_reg_save", sizeof(mini_dump->data.owner));
+		mini_dump->data.vaddr = (unsigned long)&ipa_reg_save;
+		mini_dump->data.size = sizeof(ipa_reg_save);
+		list_add(&mini_dump->entry, &ipa3_ctx->minidump_list_head);
+	}
+#endif
 	return 0;
 
 alloc_fail2:

+ 43 - 1
drivers/platform/msm/ipa/ipa_v3/ipa.c

@@ -7881,6 +7881,9 @@ static int ipa3_post_init(const struct ipa3_plat_drv_res *resource_p,
 	struct idr *idr;
 	bool reg = false;
 	enum ipa_ip_type ip;
+#if IS_ENABLED(CONFIG_QCOM_VA_MINIDUMP)
+	struct ipa_minidump_data *mini_dump;
+#endif
 
 	if (ipa3_ctx == NULL) {
 		IPADBG("IPA driver haven't initialized\n");
@@ -8252,7 +8255,16 @@ static int ipa3_post_init(const struct ipa3_plat_drv_res *resource_p,
 		IPADBG("Fail to init spearhead ipa lnx module");
 
 	pr_info("IPA driver initialization was successful.\n");
-
+#if IS_ENABLED(CONFIG_QCOM_VA_MINIDUMP)
+	/*Adding ipa3_ctx pointer to minidump list*/
+	mini_dump = (struct ipa_minidump_data *)kzalloc(sizeof(struct ipa_minidump_data), GFP_KERNEL);
+	if (mini_dump != NULL) {
+		strlcpy(mini_dump->data.owner, "ipa3_ctx", sizeof(mini_dump->data.owner));
+		mini_dump->data.vaddr = (unsigned long)(ipa3_ctx);
+		mini_dump->data.size = sizeof(struct ipa3_context);
+		list_add(&mini_dump->entry, &ipa3_ctx->minidump_list_head);
+	}
+#endif
 	return 0;
 
 fail_teth_bridge_driver_init:
@@ -9041,6 +9053,26 @@ static u32 get_tx_wrapper_cache_size(u32 cache_size)
 	return IPA_TX_WRAPPER_CACHE_MAX_THRESHOLD;
 }
 
+#if IS_ENABLED(CONFIG_QCOM_VA_MINIDUMP)
+static int qcom_va_md_ipa_notif_handler(struct notifier_block *this,
+					unsigned long event, void *ptr)
+{
+	struct ipa_minidump_data *testptr;
+	struct ipa_minidump_data *ptr_next;
+
+	list_for_each_entry_safe(testptr, ptr_next, &ipa3_ctx->minidump_list_head, entry) {
+		qcom_va_md_add_region(&testptr->data);
+	}
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block qcom_va_md_ipa_notif_blk = {
+	.notifier_call = qcom_va_md_ipa_notif_handler,
+	.priority = INT_MAX,
+};
+#endif
+
 /**
  * ipa3_pre_init() - Initialize the IPA Driver.
  * This part contains all initialization which doesn't require IPA HW, such
@@ -9425,6 +9457,8 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p,
 		}
 	}
 
+	INIT_LIST_HEAD(&ipa3_ctx->minidump_list_head);
+
 	/*
 	 * Setup access for register collection/dump on crash
 	 */
@@ -9732,6 +9766,14 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p,
 	ipa3_ctx->is_modem_up = false;
 	ipa3_ctx->mhi_ctrl_state = IPA_MHI_CTRL_NOT_SETUP;
 
+#if IS_ENABLED(CONFIG_QCOM_VA_MINIDUMP)
+	result = qcom_va_md_register("ipa_mini", &qcom_va_md_ipa_notif_blk);
+
+	if(result)
+		IPAERR("ipa mini qcom_va_md_register failed = %d\n", result);
+	else
+		IPADBG("ipa mini qcom_va_md_register success\n");
+#endif
 	return 0;
 
 fail_rmnet_ll_init:

+ 9 - 0
drivers/platform/msm/ipa/ipa_v3/ipa_i.h

@@ -42,6 +42,7 @@
 #include <linux/rmnet_ipa_fd_ioctl.h>
 #include <linux/ipa_fmwk.h>
 #include "ipa_uc_holb_monitor.h"
+#include <soc/qcom/minidump.h>
 
 #define IPA_DEV_NAME_MAX_LEN 15
 #define DRV_NAME "ipa"
@@ -2100,6 +2101,13 @@ struct ipa3_tsp_ctx {
 };
 #endif
 
+#if IS_ENABLED(CONFIG_QCOM_VA_MINIDUMP)
+struct ipa_minidump_data {
+	struct list_head entry;
+	struct va_md_entry data;
+};
+#endif
+
 /**
  * struct ipa3_context - IPA context
  * @cdev: cdev context
@@ -2476,6 +2484,7 @@ struct ipa3_context {
 	u32 ipa_max_napi_sort_page_thrshld;
 	u32 page_wq_reschd_time;
 	bool coal_ipv4_id_ignore;
+	struct list_head minidump_list_head;
 };
 
 struct ipa3_plat_drv_res {

+ 14 - 0
drivers/platform/msm/ipa/ipa_v3/ipa_pm.c

@@ -612,6 +612,9 @@ int ipa_pm_init(struct ipa_pm_init_params *params)
 {
 	int i, j;
 	struct clk_scaling_db *clk_scaling;
+#if IS_ENABLED(CONFIG_QCOM_VA_MINIDUMP)
+	struct ipa_minidump_data *mini_dump;
+#endif
 
 	if (params == NULL) {
 		IPA_PM_ERR("Invalid Params\n");
@@ -692,6 +695,17 @@ int ipa_pm_init(struct ipa_pm_init_params *params)
 	}
 	IPA_PM_DBG("initialization success");
 
+#if IS_ENABLED(CONFIG_QCOM_VA_MINIDUMP)
+	/*Adding ipa3_ctx pointer to minidump list*/
+	mini_dump = (struct ipa_minidump_data *)kzalloc(sizeof(struct ipa_minidump_data), GFP_KERNEL);
+	if (mini_dump != NULL) {
+		strlcpy(mini_dump->data.owner, "ipa_pm_ctx", sizeof(mini_dump->data.owner));
+		mini_dump->data.vaddr = (unsigned long)(ipa_pm_ctx);
+		mini_dump->data.size = sizeof(*ipa_pm_ctx);
+		list_add(&mini_dump->entry, &ipa3_ctx->minidump_list_head);
+	}
+#endif
+
 	return 0;
 }