qcacmn: add sync between suspend and wow resume in runtime pm
In moselle, once wow enabled there is a possibility that wow wake interrupt can be fired from FW during runtime suspend in-progress in host, this will introduce a race between runtime suspend and resume, so adding a synchronization between runtime suspend and wow triggered runtime resume. Change-Id: I38d6a24e4421697cc2d0090ba8d19884885596cb CRs-Fixed: 2845672
This commit is contained in:

committed by
snandini

parent
82acedd149
commit
86f4aa6017
@@ -1027,6 +1027,8 @@ int hif_pm_runtime_prevent_suspend(struct hif_opaque_softc *ol_sc,
|
||||
int hif_pm_runtime_allow_suspend(struct hif_opaque_softc *ol_sc,
|
||||
struct hif_pm_runtime_lock *lock);
|
||||
bool hif_pm_runtime_is_suspended(struct hif_opaque_softc *hif_ctx);
|
||||
void hif_pm_runtime_suspend_lock(struct hif_opaque_softc *hif_ctx);
|
||||
void hif_pm_runtime_suspend_unlock(struct hif_opaque_softc *hif_ctx);
|
||||
int hif_pm_runtime_get_monitor_wake_intr(struct hif_opaque_softc *hif_ctx);
|
||||
void hif_pm_runtime_set_monitor_wake_intr(struct hif_opaque_softc *hif_ctx,
|
||||
int val);
|
||||
@@ -1083,6 +1085,12 @@ static inline int hif_pm_runtime_allow_suspend(struct hif_opaque_softc *ol_sc,
|
||||
{ return 0; }
|
||||
static inline bool hif_pm_runtime_is_suspended(struct hif_opaque_softc *hif_ctx)
|
||||
{ return false; }
|
||||
static inline void
|
||||
hif_pm_runtime_suspend_lock(struct hif_opaque_softc *hif_ctx)
|
||||
{ return; }
|
||||
static inline void
|
||||
hif_pm_runtime_suspend_unlock(struct hif_opaque_softc *hif_ctx)
|
||||
{ return; }
|
||||
static inline int
|
||||
hif_pm_runtime_get_monitor_wake_intr(struct hif_opaque_softc *hif_ctx)
|
||||
{ return 0; }
|
||||
|
@@ -438,6 +438,7 @@ void hif_pm_runtime_open(struct hif_softc *scn)
|
||||
struct hif_runtime_pm_ctx *rpm_ctx = hif_bus_get_rpm_ctx(scn);
|
||||
|
||||
spin_lock_init(&rpm_ctx->runtime_lock);
|
||||
qdf_spinlock_create(&rpm_ctx->runtime_suspend_lock);
|
||||
qdf_atomic_init(&rpm_ctx->pm_state);
|
||||
hif_runtime_lock_init(&rpm_ctx->prevent_linkdown_lock,
|
||||
"prevent_linkdown_lock");
|
||||
@@ -554,6 +555,8 @@ void hif_pm_runtime_close(struct hif_softc *scn)
|
||||
hif_is_recovery_in_progress(scn) ?
|
||||
hif_pm_runtime_sanitize_on_ssr_exit(scn) :
|
||||
hif_pm_runtime_sanitize_on_exit(scn);
|
||||
|
||||
qdf_spinlock_destroy(&rpm_ctx->runtime_suspend_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1592,6 +1595,34 @@ bool hif_pm_runtime_is_suspended(struct hif_opaque_softc *hif_ctx)
|
||||
HIF_PM_RUNTIME_STATE_SUSPENDED;
|
||||
}
|
||||
|
||||
/*
|
||||
* hif_pm_runtime_suspend_lock() - spin_lock on marking runtime suspend
|
||||
* @hif_ctx: HIF context
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
void hif_pm_runtime_suspend_lock(struct hif_opaque_softc *hif_ctx)
|
||||
{
|
||||
struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
|
||||
struct hif_runtime_pm_ctx *rpm_ctx = hif_bus_get_rpm_ctx(scn);
|
||||
|
||||
qdf_spin_lock_irqsave(&rpm_ctx->runtime_suspend_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* hif_pm_runtime_suspend_unlock() - spin_unlock on marking runtime suspend
|
||||
* @hif_ctx: HIF context
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
void hif_pm_runtime_suspend_unlock(struct hif_opaque_softc *hif_ctx)
|
||||
{
|
||||
struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
|
||||
struct hif_runtime_pm_ctx *rpm_ctx = hif_bus_get_rpm_ctx(scn);
|
||||
|
||||
qdf_spin_unlock_irqrestore(&rpm_ctx->runtime_suspend_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* hif_pm_runtime_get_monitor_wake_intr() - API to get monitor_wake_intr
|
||||
* @hif_ctx: HIF context
|
||||
@@ -1640,9 +1671,12 @@ void hif_pm_runtime_set_monitor_wake_intr(struct hif_opaque_softc *hif_ctx,
|
||||
*/
|
||||
void hif_pm_runtime_check_and_request_resume(struct hif_opaque_softc *hif_ctx)
|
||||
{
|
||||
if (hif_pm_runtime_get_monitor_wake_intr(hif_ctx)) {
|
||||
hif_pm_runtime_set_monitor_wake_intr(hif_ctx, 0);
|
||||
hif_pm_runtime_suspend_lock(hif_ctx);
|
||||
if (hif_pm_runtime_is_suspended(hif_ctx)) {
|
||||
hif_pm_runtime_suspend_unlock(hif_ctx);
|
||||
hif_pm_runtime_request_resume(hif_ctx);
|
||||
} else {
|
||||
hif_pm_runtime_suspend_unlock(hif_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -78,6 +78,7 @@ struct hif_runtime_pm_ctx {
|
||||
struct hif_pci_pm_stats pm_stats;
|
||||
struct work_struct pm_work;
|
||||
spinlock_t runtime_lock; /* Generic spinlock for Runtime PM */
|
||||
qdf_spinlock_t runtime_suspend_lock;
|
||||
qdf_timer_t runtime_timer;
|
||||
struct list_head prevent_suspend_list;
|
||||
unsigned long runtime_timer_expires;
|
||||
|
Reference in New Issue
Block a user