icnss: Fix suspend errors caused by wrong paired PM operation

Becauase of using wrong pair of PM operation device
was not resuming if suspend fails. Also device gives
errors in dmesg like below:

[ 2420.308491] dpm_run_callback(): icnss_pm_suspend_noirq+0x0/0xc0 returns -11
[ 2420.308510] PM: Device 18800000.qcom,icnss failed to suspend async: error -11
[ 2420.312069] PM: noirq suspend of devices failed
[ 2423.384002] dpm_run_callback(): icnss_pm_suspend_noirq+0x0/0xc0 returns -11
[ 2423.384020] PM: Device 18800000.qcom,icnss failed to suspend async: error -11
[ 2423.317523] PM: noirq suspend of devices failed
[ 2426.444164] dpm_run_callback(): icnss_pm_suspend_noirq+0x0/0xc0 returns -11
[ 2426.444181] PM: Device 18800000.qcom,icnss failed to suspend async: error -11
[ 2426.447813] PM: noirq suspend of devices failed
[ 2428.915643] dpm_run_callback(): icnss_pm_suspend_noirq+0x0/0xc0 returns -11
[ 2428.915659] PM: Device 18800000.qcom,icnss failed to suspend async: error -11
[ 2428.919208] PM: noirq suspend of devices failed
[ 2429.529067] dpm_run_callback(): icnss_pm_suspend_noirq+0x0/0xc0 returns -11
[ 2429.529086] PM: Device 18800000.qcom,icnss failed to suspend async: error -11
[ 2423.532786] PM: noirq suspend of devices failed

Adding changes to use correct set of PM operations and
fix log spam.

Signed-off-by: atndko <z1281552865@gmail.com>
This commit is contained in:
atndko 2020-12-20 14:58:19 +08:00 committed by spakkkk
parent 6de1bb84f5
commit c713ef892b
3 changed files with 31 additions and 29 deletions

View File

@ -3042,8 +3042,8 @@ static int icnss_stats_show_state(struct seq_file *s, struct icnss_priv *priv)
case ICNSS_PM_SUSPEND:
seq_puts(s, "PM SUSPEND");
continue;
case ICNSS_PM_SUSPEND_NOIRQ:
seq_puts(s, "PM SUSPEND NOIRQ");
case ICNSS_PM_SUSPEND_LATE:
seq_puts(s, "PM SUSPEND LATE");
continue;
case ICNSS_SSR_REGISTERED:
seq_puts(s, "SSR REGISTERED");
@ -3212,10 +3212,10 @@ static int icnss_stats_show(struct seq_file *s, void *data)
ICNSS_STATS_DUMP(s, priv, pm_suspend_err);
ICNSS_STATS_DUMP(s, priv, pm_resume);
ICNSS_STATS_DUMP(s, priv, pm_resume_err);
ICNSS_STATS_DUMP(s, priv, pm_suspend_noirq);
ICNSS_STATS_DUMP(s, priv, pm_suspend_noirq_err);
ICNSS_STATS_DUMP(s, priv, pm_resume_noirq);
ICNSS_STATS_DUMP(s, priv, pm_resume_noirq_err);
ICNSS_STATS_DUMP(s, priv, pm_suspend_late);
ICNSS_STATS_DUMP(s, priv, pm_suspend_late_err);
ICNSS_STATS_DUMP(s, priv, pm_resume_early);
ICNSS_STATS_DUMP(s, priv, pm_resume_early_err);
ICNSS_STATS_DUMP(s, priv, pm_stay_awake);
ICNSS_STATS_DUMP(s, priv, pm_relax);
@ -4006,60 +4006,60 @@ out:
return ret;
}
static int icnss_pm_suspend_noirq(struct device *dev)
static int icnss_pm_suspend_late(struct device *dev)
{
struct icnss_priv *priv = dev_get_drvdata(dev);
int ret = 0;
if (priv->magic != ICNSS_MAGIC) {
icnss_pr_err("Invalid drvdata for pm suspend_noirq: dev %pK, data %pK, magic 0x%x\n",
icnss_pr_err("Invalid drvdata for pm suspend_late: dev %pK, data %pK, magic 0x%x\n",
dev, priv, priv->magic);
return -EINVAL;
}
icnss_pr_vdbg("PM suspend_noirq, state: 0x%lx\n", priv->state);
icnss_pr_vdbg("PM suspend_late, state: 0x%lx\n", priv->state);
if (!priv->ops || !priv->ops->suspend_noirq ||
if (!priv->ops || !priv->ops->suspend_late ||
!test_bit(ICNSS_DRIVER_PROBED, &priv->state))
goto out;
ret = priv->ops->suspend_noirq(dev);
ret = priv->ops->suspend_late(dev);
out:
if (ret == 0) {
priv->stats.pm_suspend_noirq++;
set_bit(ICNSS_PM_SUSPEND_NOIRQ, &priv->state);
priv->stats.pm_suspend_late++;
set_bit(ICNSS_PM_SUSPEND_LATE, &priv->state);
} else {
priv->stats.pm_suspend_noirq_err++;
priv->stats.pm_suspend_late_err++;
}
return ret;
}
static int icnss_pm_resume_noirq(struct device *dev)
static int icnss_pm_resume_early(struct device *dev)
{
struct icnss_priv *priv = dev_get_drvdata(dev);
int ret = 0;
if (priv->magic != ICNSS_MAGIC) {
icnss_pr_err("Invalid drvdata for pm resume_noirq: dev %pK, data %pK, magic 0x%x\n",
icnss_pr_err("Invalid drvdata for pm resume_early: dev %pK, data %pK, magic 0x%x\n",
dev, priv, priv->magic);
return -EINVAL;
}
icnss_pr_vdbg("PM resume_noirq, state: 0x%lx\n", priv->state);
icnss_pr_vdbg("PM resume_early, state: 0x%lx\n", priv->state);
if (!priv->ops || !priv->ops->resume_noirq ||
if (!priv->ops || !priv->ops->resume_early ||
!test_bit(ICNSS_DRIVER_PROBED, &priv->state))
goto out;
ret = priv->ops->resume_noirq(dev);
ret = priv->ops->resume_early(dev);
out:
if (ret == 0) {
priv->stats.pm_resume_noirq++;
clear_bit(ICNSS_PM_SUSPEND_NOIRQ, &priv->state);
priv->stats.pm_resume_early++;
clear_bit(ICNSS_PM_SUSPEND_LATE, &priv->state);
} else {
priv->stats.pm_resume_noirq_err++;
priv->stats.pm_resume_early_err++;
}
return ret;
}
@ -4068,8 +4068,8 @@ out:
static const struct dev_pm_ops icnss_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(icnss_pm_suspend,
icnss_pm_resume)
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(icnss_pm_suspend_noirq,
icnss_pm_resume_noirq)
SET_LATE_SYSTEM_SLEEP_PM_OPS(icnss_pm_suspend_late,
icnss_pm_resume_early)
};
static const struct of_device_id icnss_dt_match[] = {

View File

@ -145,7 +145,7 @@ enum icnss_driver_state {
ICNSS_DRIVER_PROBED,
ICNSS_FW_TEST_MODE,
ICNSS_PM_SUSPEND,
ICNSS_PM_SUSPEND_NOIRQ,
ICNSS_PM_SUSPEND_LATE,
ICNSS_SSR_REGISTERED,
ICNSS_PDR_REGISTERED,
ICNSS_PD_RESTART,
@ -214,10 +214,10 @@ struct icnss_stats {
uint32_t pm_suspend_err;
uint32_t pm_resume;
uint32_t pm_resume_err;
uint32_t pm_suspend_noirq;
uint32_t pm_suspend_noirq_err;
uint32_t pm_resume_noirq;
uint32_t pm_resume_noirq_err;
uint32_t pm_suspend_late;
uint32_t pm_suspend_late_err;
uint32_t pm_resume_early;
uint32_t pm_resume_early_err;
uint32_t pm_stay_awake;
uint32_t pm_relax;

View File

@ -52,6 +52,8 @@ struct icnss_driver_ops {
int (*pm_resume)(struct device *dev);
int (*suspend_noirq)(struct device *dev);
int (*resume_noirq)(struct device *dev);
int (*suspend_late)(struct device *dev);
int (*resume_early)(struct device *dev);
int (*uevent)(struct device *dev, struct icnss_uevent_data *uevent);
int (*idle_shutdown)(struct device *dev);
int (*idle_restart)(struct device *dev);