Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9ec08ea5 authored by Guisen Yang's avatar Guisen Yang Committed by Gerrit - the friendly Code Review server
Browse files

cnss2: Export a platform API to force collect ramdump



Add an API to force collect ramdump in platform driver. This API will be
called from WLAN driver to collect  ramdump before calling kernel panic.

CRs-Fixed: 2351811
Change-Id: Ic88769beec4f7f8303fc2c0803012789e02c9f4f
Signed-off-by: default avatarGuisen Yang <guiseny@codeaurora.org>
parent f5387f19
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -1179,6 +1179,41 @@ int cnss_force_fw_assert(struct device *dev)
}
EXPORT_SYMBOL(cnss_force_fw_assert);

int cnss_force_collect_rddm(struct device *dev)
{
	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
	int ret = 0;

	if (!plat_priv) {
		cnss_pr_err("plat_priv is NULL\n");
		return -ENODEV;
	}

	if (plat_priv->device_id == QCA6174_DEVICE_ID) {
		cnss_pr_info("Force collect rddm is not supported\n");
		return -EOPNOTSUPP;
	}

	if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) {
		cnss_pr_info("Recovery is already in progress, ignore forced collect rddm\n");
		return 0;
	}

	cnss_driver_event_post(plat_priv,
			       CNSS_DRIVER_EVENT_FORCE_FW_ASSERT,
			       0, NULL);

	reinit_completion(&plat_priv->rddm_complete);
	ret = wait_for_completion_timeout
		(&plat_priv->rddm_complete,
		 msecs_to_jiffies(CNSS_RDDM_TIMEOUT_MS));
	if (!ret)
		ret = -ETIMEDOUT;

	return ret;
}
EXPORT_SYMBOL(cnss_force_collect_rddm);

static int cnss_wlfw_server_arrive_hdlr(struct cnss_plat_data *plat_priv)
{
	int ret;
@@ -1928,6 +1963,7 @@ static int cnss_probe(struct platform_device *plat_dev)
			    ret);

	init_completion(&plat_priv->power_up_complete);
	init_completion(&plat_priv->rddm_complete);
	mutex_init(&plat_priv->dev_lock);

	cnss_pr_info("Platform driver probed successfully.\n");
@@ -1967,6 +2003,7 @@ static int cnss_remove(struct platform_device *plat_dev)
{
	struct cnss_plat_data *plat_priv = platform_get_drvdata(plat_dev);

	complete_all(&plat_priv->rddm_complete);
	complete_all(&plat_priv->power_up_complete);
	device_init_wakeup(&plat_dev->dev, false);
	unregister_pm_notifier(&cnss_pm_notifier);
+2 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include "qmi.h"

#define MAX_NO_OF_MAC_ADDR		4
#define CNSS_RDDM_TIMEOUT_MS		20000

#define CNSS_EVENT_SYNC   BIT(0)
#define CNSS_EVENT_UNINTERRUPTIBLE BIT(1)
@@ -225,6 +226,7 @@ struct cnss_plat_data {
	u8 *diag_reg_read_buf;
	void *caldb_mem;
	bool cal_done;
	struct completion rddm_complete;
};

struct cnss_plat_data *cnss_get_plat_priv(struct platform_device *plat_dev);
+24 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/of.h>
#include <linux/pm_runtime.h>
#include <linux/memblock.h>
#include <linux/completion.h>
#include <soc/qcom/ramdump.h>

#include "main.h"
@@ -573,6 +574,11 @@ static void cnss_qca6290_crash_shutdown(struct cnss_pci_data *pci_priv)
		return;
	}

	if (test_bit(CNSS_MHI_RDDM_DONE, &plat_priv->driver_state)) {
		cnss_pr_dbg("RDDM already collected, return\n");
		return;
	}

	cnss_pci_collect_dump_info(pci_priv);
}

@@ -1511,8 +1517,15 @@ int cnss_pci_force_fw_assert_hdlr(struct cnss_pci_data *pci_priv)
	if (!plat_priv)
		return -ENODEV;

	if (test_bit(CNSS_MHI_RDDM_DONE, &pci_priv->mhi_state)) {
		cnss_pr_err("RDDM already collected 0x%lx, return\n",
			    pci_priv->mhi_state);
		return 0;
	}

	ret = cnss_pci_set_mhi_state(pci_priv,
				     CNSS_MHI_TRIGGER_RDDM);

	if (ret) {
		cnss_pr_err("Failed to trigger RDDM, err = %d\n", ret);
		cnss_schedule_recovery(&pci_priv->pci_dev->dev,
@@ -1912,6 +1925,8 @@ static char *cnss_mhi_state_to_str(enum cnss_mhi_state mhi_state)
		return "RDDM_KERNEL_PANIC";
	case CNSS_MHI_NOTIFY_LINK_ERROR:
		return "NOTIFY_LINK_ERROR";
	case CNSS_MHI_RDDM_DONE:
		return "RDDM_DONE";
	default:
		return "UNKNOWN";
	}
@@ -1974,6 +1989,9 @@ void cnss_pci_collect_dump_info(struct cnss_pci_data *pci_priv)

	if (dump_data->nentries > 0)
		plat_priv->ramdump_info_v2.dump_data_valid = true;

	cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_RDDM_DONE);
	complete(&plat_priv->rddm_complete);
}

void cnss_pci_clear_dump_info(struct cnss_pci_data *pci_priv)
@@ -2118,6 +2136,7 @@ static int cnss_pci_check_mhi_state_bit(struct cnss_pci_data *pci_priv,
	case CNSS_MHI_RDDM:
	case CNSS_MHI_RDDM_KERNEL_PANIC:
	case CNSS_MHI_NOTIFY_LINK_ERROR:
	case CNSS_MHI_RDDM_DONE:
		return 0;
	default:
		cnss_pr_err("Unhandled MHI state: %s(%d)\n",
@@ -2146,6 +2165,7 @@ static void cnss_pci_set_mhi_state_bit(struct cnss_pci_data *pci_priv,
		break;
	case CNSS_MHI_POWER_OFF:
		clear_bit(CNSS_MHI_POWER_ON, &pci_priv->mhi_state);
		clear_bit(CNSS_MHI_RDDM_DONE, &pci_priv->mhi_state);
		break;
	case CNSS_MHI_SUSPEND:
		set_bit(CNSS_MHI_SUSPEND, &pci_priv->mhi_state);
@@ -2158,6 +2178,9 @@ static void cnss_pci_set_mhi_state_bit(struct cnss_pci_data *pci_priv,
	case CNSS_MHI_RDDM_KERNEL_PANIC:
	case CNSS_MHI_NOTIFY_LINK_ERROR:
		break;
	case CNSS_MHI_RDDM_DONE:
		set_bit(CNSS_MHI_RDDM_DONE, &pci_priv->mhi_state);
		break;
	default:
		cnss_pr_err("Unhandled MHI state (%d)\n", mhi_state);
	}
@@ -2188,6 +2211,7 @@ int cnss_pci_set_mhi_state(struct cnss_pci_data *pci_priv,

	cnss_pr_dbg("Setting MHI state: %s(%d)\n",
		    cnss_mhi_state_to_str(mhi_state), mhi_state);

	ret = mhi_pm_control_device(&pci_priv->mhi_dev, mhi_dev_state);
	if (ret) {
		cnss_pr_err("Failed to set MHI state: %s(%d)\n",
+1 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ enum cnss_mhi_state {
	CNSS_MHI_RDDM,
	CNSS_MHI_RDDM_KERNEL_PANIC,
	CNSS_MHI_NOTIFY_LINK_ERROR,
	CNSS_MHI_RDDM_DONE,
};

struct cnss_msi_user {
+1 −0
Original line number Diff line number Diff line
@@ -189,6 +189,7 @@ extern void cnss_schedule_recovery(struct device *dev,
extern int cnss_self_recovery(struct device *dev,
			      enum cnss_recovery_reason reason);
extern int cnss_force_fw_assert(struct device *dev);
extern int cnss_force_collect_rddm(struct device *dev);
extern void *cnss_get_virt_ramdump_mem(struct device *dev, unsigned long *size);
extern int cnss_get_fw_files_for_target(struct device *dev,
					struct cnss_fw_files *pfw_files,