mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
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> Signed-off-by: azrim <mirzaspc@gmail.com>
This commit is contained in:
parent
496ccac5eb
commit
969229a4cf
@ -3122,8 +3122,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");
|
||||
@ -3301,10 +3301,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);
|
||||
|
||||
@ -4007,60 +4007,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;
|
||||
}
|
||||
@ -4069,8 +4069,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[] = {
|
||||
|
@ -151,7 +151,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,
|
||||
@ -217,10 +217,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;
|
||||
|
||||
|
@ -49,6 +49,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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user