}
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;
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");
{
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);
#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"
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);
}
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,
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";
}
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)
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",
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);
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);
}
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",
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,