qcacmn: Fix long ping delay after enable RTPM
Issue1: Driver RTPM state is ON/NONE, Kernel state is RESUMING. cdp_runtime_resume is already complete, hif_pm_runtime_get return -E_INPROGRESS, dp_tx_hw_enqueue will set the flush event, but cdp_runtime_resume is already done, this flush event will be handled only on next pkt tx. Issue2: Driver RTPM state: Resuming hif_pm_runtime_get returns -EBUSY, dp_tx_hw_enqueue is interrupted by any IRQ, cdp_runtime_resume is completed, dp_tx_hw_enqueue will set the flush event, This flush event will be handled only on next pkt tx. Fix: Introduce a link_state_up atomic variable in hif to track the link state change by pld_cb. Set atomic variable link_state_up=1 in pmo_core_psoc_bus_runtime_resume just after pld_cb. pld_cb brings the PCIe bus out of suspend state. Set atomic variable link_state_up=0 in pmo_core_psoc_bus_runtime_suspend just before pld_cb. pld_cb puts the PCIe bus into suspend state. Introduce dp_runtime_get and dp_runtime_put. dp_runtime_get get refcount with increment of an atomic variable. dp_runtime_put return refcount with decrement of this atomic variable. If hif_pm_runtime_get returns -EBUSY or -EINPROGRESS, take the dp runtime refcount using dp_runtime_get, check if the link state is up, write TX ring HP, return the dp runtime refcount using dp_runtime_put. cdp_runtime_suspend should reject the suspend, if dp_runtime_get is non zero. cdp_runtime_resume should wait until dp_runtime_get becomes zero or time out, then flush pending tx for runtime suspend. Change-Id: I5b97d50cba710082f117f3845f7830712b86cda7 CRs-Fixed: 2844888
This commit is contained in:
@@ -2633,4 +2633,73 @@ void dp_desc_multi_pages_mem_free(struct dp_soc *soc,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FEATURE_RUNTIME_PM
|
||||
/**
|
||||
* dp_runtime_get() - Get dp runtime refcount
|
||||
* @soc: Datapath soc handle
|
||||
*
|
||||
* Get dp runtime refcount by increment of an atomic variable, which can block
|
||||
* dp runtime resume to wait to flush pending tx by runtime suspend.
|
||||
*
|
||||
* Return: Current refcount
|
||||
*/
|
||||
static inline int32_t dp_runtime_get(struct dp_soc *soc)
|
||||
{
|
||||
return qdf_atomic_inc_return(&soc->dp_runtime_refcount);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_runtime_put() - Return dp runtime refcount
|
||||
* @soc: Datapath soc handle
|
||||
*
|
||||
* Return dp runtime refcount by decrement of an atomic variable, allow dp
|
||||
* runtime resume finish.
|
||||
*
|
||||
* Return: Current refcount
|
||||
*/
|
||||
static inline int32_t dp_runtime_put(struct dp_soc *soc)
|
||||
{
|
||||
return qdf_atomic_dec_return(&soc->dp_runtime_refcount);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_runtime_get_refcount() - Get dp runtime refcount
|
||||
* @soc: Datapath soc handle
|
||||
*
|
||||
* Get dp runtime refcount by returning an atomic variable
|
||||
*
|
||||
* Return: Current refcount
|
||||
*/
|
||||
static inline int32_t dp_runtime_get_refcount(struct dp_soc *soc)
|
||||
{
|
||||
return qdf_atomic_read(&soc->dp_runtime_refcount);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_runtime_init() - Init dp runtime refcount when dp soc init
|
||||
* @soc: Datapath soc handle
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static inline QDF_STATUS dp_runtime_init(struct dp_soc *soc)
|
||||
{
|
||||
return qdf_atomic_init(&soc->dp_runtime_refcount);
|
||||
}
|
||||
#else
|
||||
static inline int32_t dp_runtime_get(struct dp_soc *soc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int32_t dp_runtime_put(struct dp_soc *soc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline QDF_STATUS dp_runtime_init(struct dp_soc *soc)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* #ifndef _DP_INTERNAL_H_ */
|
||||
|
مرجع در شماره جدید
Block a user