diff --git a/drivers/soc/qcom/icnss2/main.c b/drivers/soc/qcom/icnss2/main.c index eec972a1bb34..fc5728303f4c 100644 --- a/drivers/soc/qcom/icnss2/main.c +++ b/drivers/soc/qcom/icnss2/main.c @@ -1842,6 +1842,30 @@ enable_pdr: return 0; } +static int icnss_trigger_ssr_smp2p(struct icnss_priv *priv) +{ + unsigned int value = 0; + int ret; + + if (IS_ERR(priv->smp2p_info.smem_state)) + return -EINVAL; + + value |= priv->smp2p_info.seq++; + value <<= ICNSS_SMEM_SEQ_NO_POS; + value |= ICNSS_TRIGGER_SSR; + ret = qcom_smem_state_update_bits( + priv->smp2p_info.smem_state, + ICNSS_SMEM_VALUE_MASK, + value); + if (ret) + icnss_pr_dbg("Error in SMP2P sent ret: %d\n", ret); + + icnss_pr_dbg("Initiate Root PD restart. SMP2P sent value: 0x%X\n", + value); + set_bit(ICNSS_HOST_TRIGGERED_PDR, &priv->state); + return ret; +} + static int icnss_tcdev_get_max_state(struct thermal_cooling_device *tcdev, unsigned long *thermal_state) { @@ -2688,6 +2712,9 @@ int icnss_trigger_recovery(struct device *dev) goto out; } + if (priv->device_id == WCN6750_DEVICE_ID) + return icnss_trigger_ssr_smp2p(priv); + if (!test_bit(ICNSS_PDR_REGISTERED, &priv->state)) { icnss_pr_err("PD restart not enabled to trigger recovery: state: 0x%lx\n", priv->state); diff --git a/drivers/soc/qcom/icnss2/main.h b/drivers/soc/qcom/icnss2/main.h index 58a3b313b9b6..4a6854f4d834 100644 --- a/drivers/soc/qcom/icnss2/main.h +++ b/drivers/soc/qcom/icnss2/main.h @@ -171,10 +171,12 @@ struct icnss_fw_mem { unsigned long attrs; }; -enum icnss_power_save_mode { +enum icnss_smp2p_msg_id { ICNSS_POWER_SAVE_ENTER = 1, ICNSS_POWER_SAVE_EXIT, + ICNSS_TRIGGER_SSR, }; + struct icnss_stats { struct { uint32_t posted;