Loading drivers/soc/qcom/icnss2/main.c +70 −12 Original line number Diff line number Diff line Loading @@ -41,6 +41,8 @@ #include <soc/qcom/subsystem_restart.h> #include <soc/qcom/socinfo.h> #include <soc/qcom/ramdump.h> #include <linux/soc/qcom/smem.h> #include <linux/soc/qcom/smem_state.h> #include "main.h" #include "qmi.h" #include "debug.h" Loading Loading @@ -2761,6 +2763,8 @@ EXPORT_SYMBOL(icnss_idle_restart); int icnss_exit_power_save(struct device *dev) { struct icnss_priv *priv = dev_get_drvdata(dev); unsigned int value = 0; int ret; icnss_pr_dbg("Calling Exit Power Save\n"); Loading @@ -2768,8 +2772,18 @@ int icnss_exit_power_save(struct device *dev) !test_bit(ICNSS_MODE_ON, &priv->state)) return 0; return wlfw_power_save_send_msg(priv, (enum wlfw_power_save_mode_v01)ICNSS_POWER_SAVE_EXIT); value |= priv->smp2p_info.seq++; value <<= ICNSS_SMEM_SEQ_NO_POS; value |= ICNSS_POWER_SAVE_EXIT; 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("SMP2P sent value: 0x%X\n", value); return ret; } EXPORT_SYMBOL(icnss_exit_power_save); Loading Loading @@ -3154,6 +3168,20 @@ static void icnss_init_control_params(struct icnss_priv *priv) } } static inline void icnss_get_smp2p_info(struct icnss_priv *priv) { priv->smp2p_info.smem_state = qcom_smem_state_get(&priv->pdev->dev, "wlan-smp2p-out", &priv->smp2p_info.smem_bit); if (IS_ERR(priv->smp2p_info.smem_state)) { icnss_pr_dbg("Failed to get smem state %d", PTR_ERR(priv->smp2p_info.smem_state)); } } static inline void icnss_runtime_pm_init(struct icnss_priv *priv) { pm_runtime_get_sync(&priv->pdev->dev); Loading Loading @@ -3275,6 +3303,7 @@ static int icnss_probe(struct platform_device *pdev) icnss_runtime_pm_init(priv); icnss_get_cpr_info(priv); icnss_get_smp2p_info(priv); set_bit(ICNSS_COLD_BOOT_CAL, &priv->state); } Loading Loading @@ -3344,6 +3373,7 @@ static int icnss_remove(struct platform_device *pdev) static int icnss_pm_suspend(struct device *dev) { struct icnss_priv *priv = dev_get_drvdata(dev); unsigned int value = 0; int ret = 0; if (priv->magic != ICNSS_MAGIC) { Loading @@ -3355,6 +3385,7 @@ static int icnss_pm_suspend(struct device *dev) icnss_pr_vdbg("PM Suspend, state: 0x%lx\n", priv->state); if (!priv->ops || !priv->ops->pm_suspend || IS_ERR(priv->smp2p_info.smem_state) || !test_bit(ICNSS_DRIVER_PROBED, &priv->state)) return 0; Loading @@ -3362,11 +3393,23 @@ static int icnss_pm_suspend(struct device *dev) if (ret == 0) { if (priv->device_id == WCN6750_DEVICE_ID) { ret = wlfw_power_save_send_msg(priv, (enum wlfw_power_save_mode_v01) ICNSS_POWER_SAVE_ENTER); if (test_bit(ICNSS_PD_RESTART, &priv->state) || !test_bit(ICNSS_MODE_ON, &priv->state)) return 0; value |= priv->smp2p_info.seq++; value <<= ICNSS_SMEM_SEQ_NO_POS; value |= ICNSS_POWER_SAVE_ENTER; ret = qcom_smem_state_update_bits( priv->smp2p_info.smem_state, ICNSS_SMEM_VALUE_MASK, value); if (ret) return priv->ops->pm_resume(dev); icnss_pr_dbg("Error in SMP2P sent ret: %d\n", ret); icnss_pr_dbg("SMP2P sent value: 0x%X\n", value); } priv->stats.pm_suspend++; set_bit(ICNSS_PM_SUSPEND, &priv->state); Loading @@ -3390,6 +3433,7 @@ static int icnss_pm_resume(struct device *dev) icnss_pr_vdbg("PM resume, state: 0x%lx\n", priv->state); if (!priv->ops || !priv->ops->pm_resume || IS_ERR(priv->smp2p_info.smem_state) || !test_bit(ICNSS_DRIVER_PROBED, &priv->state)) goto out; Loading Loading @@ -3467,6 +3511,7 @@ static int icnss_pm_resume_noirq(struct device *dev) static int icnss_pm_runtime_suspend(struct device *dev) { struct icnss_priv *priv = dev_get_drvdata(dev); unsigned int value = 0; int ret = 0; if (priv->magic != ICNSS_MAGIC) { Loading @@ -3475,17 +3520,29 @@ static int icnss_pm_runtime_suspend(struct device *dev) return -EINVAL; } if (!priv->ops || !priv->ops->runtime_suspend) if (!priv->ops || !priv->ops->runtime_suspend || IS_ERR(priv->smp2p_info.smem_state)) goto out; icnss_pr_vdbg("Runtime suspend\n"); ret = priv->ops->runtime_suspend(dev); if (!ret) { ret = wlfw_power_save_send_msg(priv, (enum wlfw_power_save_mode_v01) ICNSS_POWER_SAVE_ENTER); if (test_bit(ICNSS_PD_RESTART, &priv->state) || !test_bit(ICNSS_MODE_ON, &priv->state)) return 0; value |= priv->smp2p_info.seq++; value <<= ICNSS_SMEM_SEQ_NO_POS; value |= ICNSS_POWER_SAVE_ENTER; ret = qcom_smem_state_update_bits( priv->smp2p_info.smem_state, ICNSS_SMEM_VALUE_MASK, value); if (ret) return priv->ops->runtime_resume(dev); icnss_pr_dbg("Error in SMP2P sent ret: %d\n", ret); icnss_pr_dbg("SMP2P sent value: 0x%X\n", value); } out: return ret; Loading @@ -3502,7 +3559,8 @@ static int icnss_pm_runtime_resume(struct device *dev) return -EINVAL; } if (!priv->ops || !priv->ops->runtime_resume) if (!priv->ops || !priv->ops->runtime_resume || IS_ERR(priv->smp2p_info.smem_state)) goto out; icnss_pr_vdbg("Runtime resume, state: 0x%lx\n", priv->state); Loading drivers/soc/qcom/icnss2/main.h +11 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,9 @@ #define ADRASTEA_DEVICE_ID 0xabcd #define QMI_WLFW_MAX_NUM_MEM_SEG 32 #define THERMAL_NAME_LENGTH 20 #define ICNSS_SMEM_VALUE_MASK 0xFFFFFFFF #define ICNSS_SMEM_SEQ_NO_POS 16 extern uint64_t dynamic_feature_mask; enum icnss_bdf_type { Loading Loading @@ -169,7 +172,7 @@ struct icnss_fw_mem { }; enum icnss_power_save_mode { ICNSS_POWER_SAVE_ENTER, ICNSS_POWER_SAVE_ENTER = 1, ICNSS_POWER_SAVE_EXIT, }; struct icnss_stats { Loading Loading @@ -310,6 +313,12 @@ struct icnss_thermal_cdev { struct thermal_cooling_device *tcdev; }; struct smp2p_out_info { unsigned short seq; unsigned int smem_bit; struct qcom_smem_state *smem_state; }; struct icnss_priv { uint32_t magic; struct platform_device *pdev; Loading Loading @@ -386,6 +395,7 @@ struct icnss_priv { struct mutex dev_lock; uint32_t fw_error_fatal_irq; uint32_t fw_early_crash_irq; struct smp2p_out_info smp2p_info; struct completion unblock_shutdown; struct adc_tm_param vph_monitor_params; struct adc_tm_chip *adc_tm_dev; Loading Loading
drivers/soc/qcom/icnss2/main.c +70 −12 Original line number Diff line number Diff line Loading @@ -41,6 +41,8 @@ #include <soc/qcom/subsystem_restart.h> #include <soc/qcom/socinfo.h> #include <soc/qcom/ramdump.h> #include <linux/soc/qcom/smem.h> #include <linux/soc/qcom/smem_state.h> #include "main.h" #include "qmi.h" #include "debug.h" Loading Loading @@ -2761,6 +2763,8 @@ EXPORT_SYMBOL(icnss_idle_restart); int icnss_exit_power_save(struct device *dev) { struct icnss_priv *priv = dev_get_drvdata(dev); unsigned int value = 0; int ret; icnss_pr_dbg("Calling Exit Power Save\n"); Loading @@ -2768,8 +2772,18 @@ int icnss_exit_power_save(struct device *dev) !test_bit(ICNSS_MODE_ON, &priv->state)) return 0; return wlfw_power_save_send_msg(priv, (enum wlfw_power_save_mode_v01)ICNSS_POWER_SAVE_EXIT); value |= priv->smp2p_info.seq++; value <<= ICNSS_SMEM_SEQ_NO_POS; value |= ICNSS_POWER_SAVE_EXIT; 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("SMP2P sent value: 0x%X\n", value); return ret; } EXPORT_SYMBOL(icnss_exit_power_save); Loading Loading @@ -3154,6 +3168,20 @@ static void icnss_init_control_params(struct icnss_priv *priv) } } static inline void icnss_get_smp2p_info(struct icnss_priv *priv) { priv->smp2p_info.smem_state = qcom_smem_state_get(&priv->pdev->dev, "wlan-smp2p-out", &priv->smp2p_info.smem_bit); if (IS_ERR(priv->smp2p_info.smem_state)) { icnss_pr_dbg("Failed to get smem state %d", PTR_ERR(priv->smp2p_info.smem_state)); } } static inline void icnss_runtime_pm_init(struct icnss_priv *priv) { pm_runtime_get_sync(&priv->pdev->dev); Loading Loading @@ -3275,6 +3303,7 @@ static int icnss_probe(struct platform_device *pdev) icnss_runtime_pm_init(priv); icnss_get_cpr_info(priv); icnss_get_smp2p_info(priv); set_bit(ICNSS_COLD_BOOT_CAL, &priv->state); } Loading Loading @@ -3344,6 +3373,7 @@ static int icnss_remove(struct platform_device *pdev) static int icnss_pm_suspend(struct device *dev) { struct icnss_priv *priv = dev_get_drvdata(dev); unsigned int value = 0; int ret = 0; if (priv->magic != ICNSS_MAGIC) { Loading @@ -3355,6 +3385,7 @@ static int icnss_pm_suspend(struct device *dev) icnss_pr_vdbg("PM Suspend, state: 0x%lx\n", priv->state); if (!priv->ops || !priv->ops->pm_suspend || IS_ERR(priv->smp2p_info.smem_state) || !test_bit(ICNSS_DRIVER_PROBED, &priv->state)) return 0; Loading @@ -3362,11 +3393,23 @@ static int icnss_pm_suspend(struct device *dev) if (ret == 0) { if (priv->device_id == WCN6750_DEVICE_ID) { ret = wlfw_power_save_send_msg(priv, (enum wlfw_power_save_mode_v01) ICNSS_POWER_SAVE_ENTER); if (test_bit(ICNSS_PD_RESTART, &priv->state) || !test_bit(ICNSS_MODE_ON, &priv->state)) return 0; value |= priv->smp2p_info.seq++; value <<= ICNSS_SMEM_SEQ_NO_POS; value |= ICNSS_POWER_SAVE_ENTER; ret = qcom_smem_state_update_bits( priv->smp2p_info.smem_state, ICNSS_SMEM_VALUE_MASK, value); if (ret) return priv->ops->pm_resume(dev); icnss_pr_dbg("Error in SMP2P sent ret: %d\n", ret); icnss_pr_dbg("SMP2P sent value: 0x%X\n", value); } priv->stats.pm_suspend++; set_bit(ICNSS_PM_SUSPEND, &priv->state); Loading @@ -3390,6 +3433,7 @@ static int icnss_pm_resume(struct device *dev) icnss_pr_vdbg("PM resume, state: 0x%lx\n", priv->state); if (!priv->ops || !priv->ops->pm_resume || IS_ERR(priv->smp2p_info.smem_state) || !test_bit(ICNSS_DRIVER_PROBED, &priv->state)) goto out; Loading Loading @@ -3467,6 +3511,7 @@ static int icnss_pm_resume_noirq(struct device *dev) static int icnss_pm_runtime_suspend(struct device *dev) { struct icnss_priv *priv = dev_get_drvdata(dev); unsigned int value = 0; int ret = 0; if (priv->magic != ICNSS_MAGIC) { Loading @@ -3475,17 +3520,29 @@ static int icnss_pm_runtime_suspend(struct device *dev) return -EINVAL; } if (!priv->ops || !priv->ops->runtime_suspend) if (!priv->ops || !priv->ops->runtime_suspend || IS_ERR(priv->smp2p_info.smem_state)) goto out; icnss_pr_vdbg("Runtime suspend\n"); ret = priv->ops->runtime_suspend(dev); if (!ret) { ret = wlfw_power_save_send_msg(priv, (enum wlfw_power_save_mode_v01) ICNSS_POWER_SAVE_ENTER); if (test_bit(ICNSS_PD_RESTART, &priv->state) || !test_bit(ICNSS_MODE_ON, &priv->state)) return 0; value |= priv->smp2p_info.seq++; value <<= ICNSS_SMEM_SEQ_NO_POS; value |= ICNSS_POWER_SAVE_ENTER; ret = qcom_smem_state_update_bits( priv->smp2p_info.smem_state, ICNSS_SMEM_VALUE_MASK, value); if (ret) return priv->ops->runtime_resume(dev); icnss_pr_dbg("Error in SMP2P sent ret: %d\n", ret); icnss_pr_dbg("SMP2P sent value: 0x%X\n", value); } out: return ret; Loading @@ -3502,7 +3559,8 @@ static int icnss_pm_runtime_resume(struct device *dev) return -EINVAL; } if (!priv->ops || !priv->ops->runtime_resume) if (!priv->ops || !priv->ops->runtime_resume || IS_ERR(priv->smp2p_info.smem_state)) goto out; icnss_pr_vdbg("Runtime resume, state: 0x%lx\n", priv->state); Loading
drivers/soc/qcom/icnss2/main.h +11 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,9 @@ #define ADRASTEA_DEVICE_ID 0xabcd #define QMI_WLFW_MAX_NUM_MEM_SEG 32 #define THERMAL_NAME_LENGTH 20 #define ICNSS_SMEM_VALUE_MASK 0xFFFFFFFF #define ICNSS_SMEM_SEQ_NO_POS 16 extern uint64_t dynamic_feature_mask; enum icnss_bdf_type { Loading Loading @@ -169,7 +172,7 @@ struct icnss_fw_mem { }; enum icnss_power_save_mode { ICNSS_POWER_SAVE_ENTER, ICNSS_POWER_SAVE_ENTER = 1, ICNSS_POWER_SAVE_EXIT, }; struct icnss_stats { Loading Loading @@ -310,6 +313,12 @@ struct icnss_thermal_cdev { struct thermal_cooling_device *tcdev; }; struct smp2p_out_info { unsigned short seq; unsigned int smem_bit; struct qcom_smem_state *smem_state; }; struct icnss_priv { uint32_t magic; struct platform_device *pdev; Loading Loading @@ -386,6 +395,7 @@ struct icnss_priv { struct mutex dev_lock; uint32_t fw_error_fatal_irq; uint32_t fw_early_crash_irq; struct smp2p_out_info smp2p_info; struct completion unblock_shutdown; struct adc_tm_param vph_monitor_params; struct adc_tm_chip *adc_tm_dev; Loading