mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 13:49:24 -04:00
Merge "icnss2: Send power save enter/exit via SMP2P"
This commit is contained in:
commit
1e8e6c8d2b
2 changed files with 81 additions and 13 deletions
|
|
@ -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"
|
||||
|
|
@ -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");
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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) {
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
@ -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);
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
@ -3467,6 +3511,7 @@ out:
|
|||
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) {
|
||||
|
|
@ -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;
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
@ -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 {
|
||||
|
|
@ -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;
|
||||
|
|
@ -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…
Reference in a new issue