In drivers/net/wireless/realtek/rtlwifi, we had a similar problem. There it was handled by putting the lps_enter() and lps_leave() operations in a separate workqueue. In this case, the routines were rtl_lps_enter() and rtl_lps_leave(). Each of them sets a variable to indicate whether enter_ps is true or false, and schedules the workqueue. In the workqueue's callback routine, the routines to start/stop ps mode are called. The code is in drivers/net/wireless/realtek/rtlwifi/ps.c.
This solution is only one of many, and there may be a better one.
Larry