Re: [PATCH 2/2] wlcore: Add support runtime PM

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi

On Tue, May 15, 2018 at 6:13 PM, Tony Lindgren <tony@xxxxxxxxxxx> wrote:
> We can update wlcore to use PM runtime by adding functions for
> wlcore_runtime_suspend() and wlcore_runtime_resume() and replacing
> calls to wl1271_ps_elp_wakeup() and wl1271_ps_elp_sleep() with calls
> to pm_runtime_get_sync() and pm_runtime_put().
>
> Note that the new wlcore_runtime_suspend() and wlcore_runtime_resume()
> functions are based on simplified versions of wl1271_ps_elp_sleep() and
> wl1271_ps_elp_wakeup(). We don't want to use the old functions as we
> can now take advantage of the runtime PM usage count. And we don't need
> the old elp_work at all. And we can also remove WL1271_FLAG_ELP_REQUESTED
> that is no longer needed.
>
> Then eventually should allow us to use pm_runtime_autosuspend in
> further patches instead of the custom handling. And we should be able
> to start using Linux generic wakeirqs for the padconf interrupt.
>
> Signed-off-by: Tony Lindgren <tony@xxxxxxxxxxx>
> ---
>  drivers/net/wireless/ti/wl18xx/debugfs.c    |  26 +-
>  drivers/net/wireless/ti/wlcore/debugfs.c    |  79 ++--
>  drivers/net/wireless/ti/wlcore/main.c       | 403 ++++++++++++++------
>  drivers/net/wireless/ti/wlcore/ps.c         | 146 -------
>  drivers/net/wireless/ti/wlcore/ps.h         |   3 -
>  drivers/net/wireless/ti/wlcore/scan.c       |   9 +-
>  drivers/net/wireless/ti/wlcore/sysfs.c      |  10 +-
>  drivers/net/wireless/ti/wlcore/testmode.c   |  17 +-
>  drivers/net/wireless/ti/wlcore/tx.c         |   9 +-
>  drivers/net/wireless/ti/wlcore/vendor_cmd.c |  26 +-
>  drivers/net/wireless/ti/wlcore/wlcore.h     |   1 -
>  drivers/net/wireless/ti/wlcore/wlcore_i.h   |   1 -
>  12 files changed, 401 insertions(+), 329 deletions(-)
>
> diff --git a/drivers/net/wireless/ti/wl18xx/debugfs.c b/drivers/net/wireless/ti/wl18xx/debugfs.c
> --- a/drivers/net/wireless/ti/wl18xx/debugfs.c
> +++ b/drivers/net/wireless/ti/wl18xx/debugfs.c
> @@ -20,6 +20,8 @@
>   *
>   */
>
> +#include <linux/pm_runtime.h>
> +
>  #include "../wlcore/debugfs.h"
>  #include "../wlcore/wlcore.h"
>  #include "../wlcore/debug.h"
> @@ -276,15 +278,17 @@ static ssize_t radar_detection_write(struct file *file,
>         if (unlikely(wl->state != WLCORE_STATE_ON))
>                 goto out;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         ret = wl18xx_cmd_radar_detection_debug(wl, channel);
>         if (ret < 0)
>                 count = ret;
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>         return count;
> @@ -315,15 +319,17 @@ static ssize_t dynamic_fw_traces_write(struct file *file,
>         if (unlikely(wl->state != WLCORE_STATE_ON))
>                 goto out;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>

Can you just change ps_elp_wakeup with
       ret = pm_runtime_get_sync(wl->dev);
       if (ret < 0) {
               pm_runtime_put_noidle(wl->dev);
                 goto out;
       }

>         ret = wl18xx_acx_dynamic_fw_traces(wl);
>         if (ret < 0)
>                 count = ret;
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);

and elp_sleep with this one

>  out:
>         mutex_unlock(&wl->mutex);
>         return count;
> @@ -374,9 +380,11 @@ static ssize_t radar_debug_mode_write(struct file *file,
>         if (unlikely(wl->state != WLCORE_STATE_ON))
>                 goto out;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         wl12xx_for_each_wlvif_ap(wl, wlvif) {
>                 wlcore_cmd_generic_cfg(wl, wlvif,
> @@ -384,7 +392,7 @@ static ssize_t radar_debug_mode_write(struct file *file,
>                                        wl->radar_debug_mode, 0);
>         }
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);

Michael

>  out:
>         mutex_unlock(&wl->mutex);
>         return count;
> diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c
> --- a/drivers/net/wireless/ti/wlcore/debugfs.c
> +++ b/drivers/net/wireless/ti/wlcore/debugfs.c
> @@ -26,6 +26,7 @@
>  #include <linux/skbuff.h>
>  #include <linux/slab.h>
>  #include <linux/module.h>
> +#include <linux/pm_runtime.h>
>
>  #include "wlcore.h"
>  #include "debug.h"
> @@ -65,9 +66,11 @@ void wl1271_debugfs_update_stats(struct wl1271 *wl)
>         if (unlikely(wl->state != WLCORE_STATE_ON))
>                 goto out;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         if (!wl->plt &&
>             time_after(jiffies, wl->stats.fw_stats_update +
> @@ -76,7 +79,7 @@ void wl1271_debugfs_update_stats(struct wl1271 *wl)
>                 wl->stats.fw_stats_update = jiffies;
>         }
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>
>  out:
>         mutex_unlock(&wl->mutex);
> @@ -118,14 +121,17 @@ static void chip_op_handler(struct wl1271 *wl, unsigned long value,
>                 return;
>         }
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
> +
>                 return;
> +       }
>
>         chip_op = arg;
>         chip_op(wl);
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  }
>
>
> @@ -292,9 +298,11 @@ static ssize_t dynamic_ps_timeout_write(struct file *file,
>         if (unlikely(wl->state != WLCORE_STATE_ON))
>                 goto out;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         /* In case we're already in PSM, trigger it again to set new timeout
>          * immediately without waiting for re-association
> @@ -305,7 +313,7 @@ static ssize_t dynamic_ps_timeout_write(struct file *file,
>                         wl1271_ps_set_mode(wl, wlvif, STATION_AUTO_PS_MODE);
>         }
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>
>  out:
>         mutex_unlock(&wl->mutex);
> @@ -359,9 +367,11 @@ static ssize_t forced_ps_write(struct file *file,
>         if (unlikely(wl->state != WLCORE_STATE_ON))
>                 goto out;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         /* In case we're already in PSM, trigger it again to switch mode
>          * immediately without waiting for re-association
> @@ -374,7 +384,7 @@ static ssize_t forced_ps_write(struct file *file,
>                         wl1271_ps_set_mode(wl, wlvif, ps_mode);
>         }
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>
>  out:
>         mutex_unlock(&wl->mutex);
> @@ -838,15 +848,17 @@ static ssize_t rx_streaming_interval_write(struct file *file,
>
>         wl->conf.rx_streaming.interval = value;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         wl12xx_for_each_wlvif_sta(wl, wlvif) {
>                 wl1271_recalc_rx_streaming(wl, wlvif);
>         }
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>         return count;
> @@ -893,15 +905,17 @@ static ssize_t rx_streaming_always_write(struct file *file,
>
>         wl->conf.rx_streaming.always = value;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         wl12xx_for_each_wlvif_sta(wl, wlvif) {
>                 wl1271_recalc_rx_streaming(wl, wlvif);
>         }
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>         return count;
> @@ -940,15 +954,17 @@ static ssize_t beacon_filtering_write(struct file *file,
>
>         mutex_lock(&wl->mutex);
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         wl12xx_for_each_wlvif(wl, wlvif) {
>                 ret = wl1271_acx_beacon_filter_opt(wl, wlvif, !!value);
>         }
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>         return count;
> @@ -1019,16 +1035,18 @@ static ssize_t sleep_auth_write(struct file *file,
>                 goto out;
>         }
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         ret = wl1271_acx_sleep_auth(wl, value);
>         if (ret < 0)
>                 goto out_sleep;
>
>  out_sleep:
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>         return count;
> @@ -1083,7 +1101,7 @@ static ssize_t dev_mem_read(struct file *file,
>          * Don't fail if elp_wakeup returns an error, so the device's memory
>          * could be read even if the FW crashed
>          */
> -       wl1271_ps_elp_wakeup(wl);
> +       pm_runtime_get_sync(wl->dev);
>
>         /* store current partition and switch partition */
>         memcpy(&old_part, &wl->curr_part, sizeof(old_part));
> @@ -1102,7 +1120,7 @@ static ssize_t dev_mem_read(struct file *file,
>                 goto part_err;
>
>  part_err:
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>
>  skip_read:
>         mutex_unlock(&wl->mutex);
> @@ -1164,7 +1182,7 @@ static ssize_t dev_mem_write(struct file *file, const char __user *user_buf,
>          * Don't fail if elp_wakeup returns an error, so the device's memory
>          * could be read even if the FW crashed
>          */
> -       wl1271_ps_elp_wakeup(wl);
> +       pm_runtime_get_sync(wl->dev);
>
>         /* store current partition and switch partition */
>         memcpy(&old_part, &wl->curr_part, sizeof(old_part));
> @@ -1183,7 +1201,7 @@ static ssize_t dev_mem_write(struct file *file, const char __user *user_buf,
>                 goto part_err;
>
>  part_err:
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>
>  skip_write:
>         mutex_unlock(&wl->mutex);
> @@ -1247,8 +1265,9 @@ static ssize_t fw_logger_write(struct file *file,
>         }
>
>         mutex_lock(&wl->mutex);
> -       ret = wl1271_ps_elp_wakeup(wl);
> +       ret = pm_runtime_get_sync(wl->dev);
>         if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 count = ret;
>                 goto out;
>         }
> @@ -1257,7 +1276,7 @@ static ssize_t fw_logger_write(struct file *file,
>
>         ret = wl12xx_cmd_config_fwlog(wl);
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>
>  out:
>         mutex_unlock(&wl->mutex);
> diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
> --- a/drivers/net/wireless/ti/wlcore/main.c
> +++ b/drivers/net/wireless/ti/wlcore/main.c
> @@ -26,6 +26,7 @@
>  #include <linux/vmalloc.h>
>  #include <linux/interrupt.h>
>  #include <linux/irq.h>
> +#include <linux/pm_runtime.h>
>
>  #include "wlcore.h"
>  #include "debug.h"
> @@ -43,6 +44,7 @@
>
>  #define WL1271_BOOT_RETRIES 3
>  #define WL1271_SUSPEND_SLEEP 100
> +#define WL1271_WAKEUP_TIMEOUT 500
>
>  static char *fwlog_param;
>  static int fwlog_mem_blocks = -1;
> @@ -153,9 +155,11 @@ static void wl1271_rx_streaming_enable_work(struct work_struct *work)
>         if (!wl->conf.rx_streaming.interval)
>                 goto out;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         ret = wl1271_set_rx_streaming(wl, wlvif, true);
>         if (ret < 0)
> @@ -166,7 +170,7 @@ static void wl1271_rx_streaming_enable_work(struct work_struct *work)
>                   jiffies + msecs_to_jiffies(wl->conf.rx_streaming.duration));
>
>  out_sleep:
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>  }
> @@ -183,16 +187,18 @@ static void wl1271_rx_streaming_disable_work(struct work_struct *work)
>         if (!test_bit(WLVIF_FLAG_RX_STREAMING_STARTED, &wlvif->flags))
>                 goto out;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         ret = wl1271_set_rx_streaming(wl, wlvif, false);
>         if (ret)
>                 goto out_sleep;
>
>  out_sleep:
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>  }
> @@ -229,9 +235,11 @@ static void wlcore_rc_update_work(struct work_struct *work)
>         if (unlikely(wl->state != WLCORE_STATE_ON))
>                 goto out;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         if (ieee80211_vif_is_mesh(vif)) {
>                 ret = wl1271_acx_set_ht_capabilities(wl, &wlvif->rc_ht_cap,
> @@ -243,7 +251,7 @@ static void wlcore_rc_update_work(struct work_struct *work)
>         }
>
>  out_sleep:
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>  }
> @@ -539,15 +547,16 @@ static int wlcore_irq_locked(struct wl1271 *wl)
>         if (unlikely(wl->state != WLCORE_STATE_ON))
>                 goto out;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         while (!done && loopcount--) {
>                 /*
>                  * In order to avoid a race with the hardirq, clear the flag
> -                * before acknowledging the chip. Since the mutex is held,
> -                * wl1271_ps_elp_wakeup cannot be called concurrently.
> +                * before acknowledging the chip.
>                  */
>                 clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
>                 smp_mb__after_atomic();
> @@ -641,7 +650,7 @@ static int wlcore_irq_locked(struct wl1271 *wl)
>                         wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE");
>         }
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>
>  out:
>         return ret;
> @@ -818,6 +827,7 @@ size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen)
>  static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
>  {
>         u32 end_of_log = 0;
> +       int error;
>
>         if (wl->quirks & WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED)
>                 return;
> @@ -829,8 +839,11 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
>          * Do not send a stop fwlog command if the fw is hanged or if
>          * dbgpins are used (due to some fw bug).
>          */
> -       if (wl1271_ps_elp_wakeup(wl))
> +       error = pm_runtime_get_sync(wl->dev);
> +       if (error < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 return;
> +       }
>         if (!wl->watchdog_recovery &&
>             wl->conf.fwlog.output != WL12XX_FWLOG_OUTPUT_DBG_PINS)
>                 wl12xx_cmd_stop_fwlog(wl);
> @@ -925,9 +938,11 @@ static void wl1271_recovery_work(struct work_struct *work)
>         if (wl->state == WLCORE_STATE_OFF || wl->plt)
>                 goto out_unlock;
>
> -       error = wl1271_ps_elp_wakeup(wl);
> -       if (error < 0)
> +       error = pm_runtime_get_sync(wl->dev);
> +       if (error < 0) {
>                 wl1271_warning("Enable for recovery failed");
> +               pm_runtime_put_noidle(wl->dev);
> +       }
>
>         if (!test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)) {
>                 if (wl->conf.fwlog.output == WL12XX_FWLOG_OUTPUT_HOST)
> @@ -971,7 +986,7 @@ static void wl1271_recovery_work(struct work_struct *work)
>          */
>         wlcore_wake_queues(wl, WLCORE_QUEUE_STOP_REASON_FW_RESTART);
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>
>  out_unlock:
>         wl->watchdog_recovery = false;
> @@ -1190,7 +1205,6 @@ int wl1271_plt_stop(struct wl1271 *wl)
>         wl1271_flush_deferred_work(wl);
>         cancel_work_sync(&wl->netstack_work);
>         cancel_work_sync(&wl->recovery_work);
> -       cancel_delayed_work_sync(&wl->elp_work);
>         cancel_delayed_work_sync(&wl->tx_watchdog_work);
>
>         mutex_lock(&wl->mutex);
> @@ -1740,8 +1754,9 @@ static int __maybe_unused wl1271_op_suspend(struct ieee80211_hw *hw,
>
>         mutex_lock(&wl->mutex);
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> +       ret = pm_runtime_get_sync(wl->dev);
>         if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 mutex_unlock(&wl->mutex);
>                 return ret;
>         }
> @@ -1771,6 +1786,7 @@ static int __maybe_unused wl1271_op_suspend(struct ieee80211_hw *hw,
>                 goto out_sleep;
>
>  out_sleep:
> +       pm_runtime_put_noidle(wl->dev);
>         mutex_unlock(&wl->mutex);
>
>         if (ret < 0) {
> @@ -1795,7 +1811,6 @@ static int __maybe_unused wl1271_op_suspend(struct ieee80211_hw *hw,
>
>         wlcore_enable_interrupts(wl);
>         flush_work(&wl->tx_work);
> -       flush_delayed_work(&wl->elp_work);
>
>         /*
>          * Cancel the watchdog even if above tx_flush failed. We will detect
> @@ -1863,9 +1878,11 @@ static int __maybe_unused wl1271_op_resume(struct ieee80211_hw *hw)
>                 goto out_sleep;
>         }
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         wl12xx_for_each_wlvif(wl, wlvif) {
>                 if (wlcore_is_p2p_mgmt(wlvif))
> @@ -1884,7 +1901,7 @@ static int __maybe_unused wl1271_op_resume(struct ieee80211_hw *hw)
>                 goto out_sleep;
>
>  out_sleep:
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>
>  out:
>         wl->wow_enabled = false;
> @@ -1951,7 +1968,6 @@ static void wlcore_op_stop_locked(struct wl1271 *wl)
>         cancel_delayed_work_sync(&wl->scan_complete_work);
>         cancel_work_sync(&wl->netstack_work);
>         cancel_work_sync(&wl->tx_work);
> -       cancel_delayed_work_sync(&wl->elp_work);
>         cancel_delayed_work_sync(&wl->tx_watchdog_work);
>
>         /* let's notify MAC80211 about the remaining pending TX frames */
> @@ -2066,13 +2082,15 @@ static void wlcore_channel_switch_work(struct work_struct *work)
>         vif = wl12xx_wlvif_to_vif(wlvif);
>         ieee80211_chswitch_done(vif, false);
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         wl12xx_cmd_stop_channel_switch(wl, wlvif);
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>  }
> @@ -2134,14 +2152,16 @@ static void wlcore_pending_auth_complete_work(struct work_struct *work)
>         if (!time_after(time_spare, wlvif->pending_auth_reply_time))
>                 goto out;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         /* cancel the ROC if active */
>         wlcore_update_inconn_sta(wl, wlvif, NULL, false);
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>  }
> @@ -2543,9 +2563,11 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
>         wl12xx_get_vif_count(hw, vif, &vif_count);
>
>         mutex_lock(&wl->mutex);
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out_unlock;
> +       }
>
>         /*
>          * in some very corner case HW recovery scenarios its possible to
> @@ -2628,7 +2650,7 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
>         else
>                 wl->sta_count++;
>  out:
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out_unlock:
>         mutex_unlock(&wl->mutex);
>
> @@ -2683,9 +2705,11 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
>
>         if (!test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags)) {
>                 /* disable active roles */
> -               ret = wl1271_ps_elp_wakeup(wl);
> -               if (ret < 0)
> +               ret = pm_runtime_get_sync(wl->dev);
> +               if (ret < 0) {
> +                       pm_runtime_put_noidle(wl->dev);
>                         goto deinit;
> +               }
>
>                 if (wlvif->bss_type == BSS_TYPE_STA_BSS ||
>                     wlvif->bss_type == BSS_TYPE_IBSS) {
> @@ -2703,7 +2727,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
>                                 goto deinit;
>                 }
>
> -               wl1271_ps_elp_sleep(wl);
> +               pm_runtime_put(wl->dev);
>         }
>  deinit:
>         wl12xx_tx_reset_wlvif(wl, wlvif);
> @@ -3127,9 +3151,11 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
>         if (unlikely(wl->state != WLCORE_STATE_ON))
>                 goto out;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         /* configure each interface */
>         wl12xx_for_each_wlvif(wl, wlvif) {
> @@ -3139,7 +3165,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
>         }
>
>  out_sleep:
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>
>  out:
>         mutex_unlock(&wl->mutex);
> @@ -3208,9 +3234,11 @@ static void wl1271_op_configure_filter(struct ieee80211_hw *hw,
>         if (unlikely(wl->state != WLCORE_STATE_ON))
>                 goto out;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         wl12xx_for_each_wlvif(wl, wlvif) {
>                 if (wlcore_is_p2p_mgmt(wlvif))
> @@ -3253,7 +3281,7 @@ static void wl1271_op_configure_filter(struct ieee80211_hw *hw,
>          */
>
>  out_sleep:
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>
>  out:
>         mutex_unlock(&wl->mutex);
> @@ -3460,13 +3488,15 @@ static int wlcore_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
>                 goto out_wake_queues;
>         }
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out_wake_queues;
> +       }
>
>         ret = wlcore_hw_set_key(wl, cmd, vif, sta, key_conf);
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>
>  out_wake_queues:
>         if (might_change_spare)
> @@ -3606,9 +3636,11 @@ static void wl1271_op_set_default_key_idx(struct ieee80211_hw *hw,
>                 goto out_unlock;
>         }
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out_unlock;
> +       }
>
>         wlvif->default_key = key_idx;
>
> @@ -3622,7 +3654,7 @@ static void wl1271_op_set_default_key_idx(struct ieee80211_hw *hw,
>         }
>
>  out_sleep:
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>
>  out_unlock:
>         mutex_unlock(&wl->mutex);
> @@ -3640,7 +3672,7 @@ void wlcore_regdomain_config(struct wl1271 *wl)
>         if (unlikely(wl->state != WLCORE_STATE_ON))
>                 goto out;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> +       ret = pm_runtime_get_sync(wl->dev);
>         if (ret < 0)
>                 goto out;
>
> @@ -3650,7 +3682,7 @@ void wlcore_regdomain_config(struct wl1271 *wl)
>                 goto out;
>         }
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>  }
> @@ -3684,9 +3716,11 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
>                 goto out;
>         }
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         /* fail if there is any role in ROC */
>         if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES) {
> @@ -3697,7 +3731,7 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
>
>         ret = wlcore_scan(hw->priv, vif, ssid, len, req);
>  out_sleep:
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>
> @@ -3724,9 +3758,11 @@ static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw,
>         if (wl->scan.state == WL1271_SCAN_STATE_IDLE)
>                 goto out;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         if (wl->scan.state != WL1271_SCAN_STATE_DONE) {
>                 ret = wl->ops->scan_stop(wl, wlvif);
> @@ -3747,7 +3783,7 @@ static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw,
>         ieee80211_scan_completed(wl->hw, &info);
>
>  out_sleep:
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>
> @@ -3772,9 +3808,11 @@ static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw,
>                 goto out;
>         }
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         ret = wl->ops->sched_scan_start(wl, wlvif, req, ies);
>         if (ret < 0)
> @@ -3783,7 +3821,7 @@ static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw,
>         wl->sched_vif = wlvif;
>
>  out_sleep:
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>         return ret;
> @@ -3803,13 +3841,15 @@ static int wl1271_op_sched_scan_stop(struct ieee80211_hw *hw,
>         if (unlikely(wl->state != WLCORE_STATE_ON))
>                 goto out;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         wl->ops->sched_scan_stop(wl, wlvif);
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>
> @@ -3828,15 +3868,17 @@ static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
>                 goto out;
>         }
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         ret = wl1271_acx_frag_threshold(wl, value);
>         if (ret < 0)
>                 wl1271_warning("wl1271_op_set_frag_threshold failed: %d", ret);
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>
>  out:
>         mutex_unlock(&wl->mutex);
> @@ -3857,16 +3899,18 @@ static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
>                 goto out;
>         }
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         wl12xx_for_each_wlvif(wl, wlvif) {
>                 ret = wl1271_acx_rts_threshold(wl, wlvif, value);
>                 if (ret < 0)
>                         wl1271_warning("set rts threshold failed: %d", ret);
>         }
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>
>  out:
>         mutex_unlock(&wl->mutex);
> @@ -4613,9 +4657,11 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
>         if (unlikely(!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)))
>                 goto out;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         if ((changed & BSS_CHANGED_TXPOWER) &&
>             bss_conf->txpower != wlvif->power_level) {
> @@ -4632,7 +4678,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
>         else
>                 wl1271_bss_info_changed_sta(wl, vif, bss_conf, changed);
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>
>  out:
>         mutex_unlock(&wl->mutex);
> @@ -4671,9 +4717,11 @@ static void wlcore_op_change_chanctx(struct ieee80211_hw *hw,
>
>         mutex_lock(&wl->mutex);
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         wl12xx_for_each_wlvif(wl, wlvif) {
>                 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
> @@ -4696,7 +4744,7 @@ static void wlcore_op_change_chanctx(struct ieee80211_hw *hw,
>                 }
>         }
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>  }
> @@ -4725,9 +4773,11 @@ static int wlcore_op_assign_vif_chanctx(struct ieee80211_hw *hw,
>         if (unlikely(!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)))
>                 goto out;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         wlvif->band = ctx->def.chan->band;
>         wlvif->channel = channel;
> @@ -4743,7 +4793,7 @@ static int wlcore_op_assign_vif_chanctx(struct ieee80211_hw *hw,
>                 wlvif->radar_enabled = true;
>         }
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>
> @@ -4774,9 +4824,11 @@ static void wlcore_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
>         if (unlikely(!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)))
>                 goto out;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         if (wlvif->radar_enabled) {
>                 wl1271_debug(DEBUG_MAC80211, "Stop radar detection");
> @@ -4784,7 +4836,7 @@ static void wlcore_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
>                 wlvif->radar_enabled = false;
>         }
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>  }
> @@ -4841,9 +4893,11 @@ wlcore_op_switch_vif_chanctx(struct ieee80211_hw *hw,
>
>         mutex_lock(&wl->mutex);
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         for (i = 0; i < n_vifs; i++) {
>                 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vifs[i].vif);
> @@ -4853,7 +4907,7 @@ wlcore_op_switch_vif_chanctx(struct ieee80211_hw *hw,
>                         goto out_sleep;
>         }
>  out_sleep:
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>
> @@ -4884,9 +4938,11 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw,
>         if (!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))
>                 goto out;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         /*
>          * the txop is confed in units of 32us by the mac80211,
> @@ -4905,7 +4961,7 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw,
>                                  0, 0);
>
>  out_sleep:
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>
>  out:
>         mutex_unlock(&wl->mutex);
> @@ -4929,16 +4985,18 @@ static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw,
>         if (unlikely(wl->state != WLCORE_STATE_ON))
>                 goto out;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         ret = wl12xx_acx_tsf_info(wl, wlvif, &mactime);
>         if (ret < 0)
>                 goto out_sleep;
>
>  out_sleep:
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>
>  out:
>         mutex_unlock(&wl->mutex);
> @@ -5244,13 +5302,15 @@ static int wl12xx_op_sta_state(struct ieee80211_hw *hw,
>                 goto out;
>         }
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         ret = wl12xx_update_sta_state(wl, wlvif, sta, old_state, new_state);
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>         if (new_state < old_state)
> @@ -5299,9 +5359,11 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
>
>         ba_bitmap = &wl->links[hlid].ba_bitmap;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         wl1271_debug(DEBUG_MAC80211, "mac80211 ampdu: Rx tid %d action %d",
>                      tid, action);
> @@ -5374,7 +5436,7 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
>                 ret = -EINVAL;
>         }
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>
>  out:
>         mutex_unlock(&wl->mutex);
> @@ -5408,16 +5470,18 @@ static int wl12xx_set_bitrate_mask(struct ieee80211_hw *hw,
>         if (wlvif->bss_type == BSS_TYPE_STA_BSS &&
>             !test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) {
>
> -               ret = wl1271_ps_elp_wakeup(wl);
> -               if (ret < 0)
> +               ret = pm_runtime_get_sync(wl->dev);
> +               if (ret < 0) {
> +                       pm_runtime_put_noidle(wl->dev);
>                         goto out;
> +               }
>
>                 wl1271_set_band_rate(wl, wlvif);
>                 wlvif->basic_rate =
>                         wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
>                 ret = wl1271_acx_sta_rate_policies(wl, wlvif);
>
> -               wl1271_ps_elp_sleep(wl);
> +               pm_runtime_put(wl->dev);
>         }
>  out:
>         mutex_unlock(&wl->mutex);
> @@ -5447,9 +5511,11 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw,
>                 goto out;
>         }
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         /* TODO: change mac80211 to pass vif as param */
>
> @@ -5471,7 +5537,7 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw,
>         }
>
>  out_sleep:
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>
>  out:
>         mutex_unlock(&wl->mutex);
> @@ -5538,9 +5604,11 @@ static void wlcore_op_channel_switch_beacon(struct ieee80211_hw *hw,
>                 goto out;
>         }
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         ret = wl->ops->channel_switch(wl, wlvif, &ch_switch);
>         if (ret)
> @@ -5549,7 +5617,7 @@ static void wlcore_op_channel_switch_beacon(struct ieee80211_hw *hw,
>         set_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags);
>
>  out_sleep:
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>  }
> @@ -5590,9 +5658,11 @@ static int wlcore_op_remain_on_channel(struct ieee80211_hw *hw,
>                 goto out;
>         }
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         ret = wl12xx_start_dev(wl, wlvif, chan->band, channel);
>         if (ret < 0)
> @@ -5602,7 +5672,7 @@ static int wlcore_op_remain_on_channel(struct ieee80211_hw *hw,
>         ieee80211_queue_delayed_work(hw, &wl->roc_complete_work,
>                                      msecs_to_jiffies(duration));
>  out_sleep:
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>         return ret;
> @@ -5644,13 +5714,15 @@ static int wlcore_roc_completed(struct wl1271 *wl)
>                 goto out;
>         }
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         ret = __wlcore_roc_completed(wl);
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>
> @@ -5725,9 +5797,11 @@ static void wlcore_op_sta_statistics(struct ieee80211_hw *hw,
>         if (unlikely(wl->state != WLCORE_STATE_ON))
>                 goto out;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out_sleep;
> +       }
>
>         ret = wlcore_acx_average_rssi(wl, wlvif, &rssi_dbm);
>         if (ret < 0)
> @@ -5737,7 +5811,7 @@ static void wlcore_op_sta_statistics(struct ieee80211_hw *hw,
>         sinfo->signal = rssi_dbm;
>
>  out_sleep:
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>
>  out:
>         mutex_unlock(&wl->mutex);
> @@ -6306,7 +6380,6 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size,
>         skb_queue_head_init(&wl->deferred_rx_queue);
>         skb_queue_head_init(&wl->deferred_tx_queue);
>
> -       INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work);
>         INIT_WORK(&wl->netstack_work, wl1271_netstack_work);
>         INIT_WORK(&wl->tx_work, wl1271_tx_work);
>         INIT_WORK(&wl->recovery_work, wl1271_recovery_work);
> @@ -6581,6 +6654,100 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
>         complete_all(&wl->nvs_loading_complete);
>  }
>
> +static int __maybe_unused wlcore_runtime_suspend(struct device *dev)
> +{
> +       struct wl1271 *wl = dev_get_drvdata(dev);
> +       struct wl12xx_vif *wlvif;
> +       int error;
> +
> +       /* We do not enter elp sleep in PLT mode */
> +       if (wl->plt)
> +               return -EINVAL;
> +
> +       /* Nothing to do if no ELP mode requested */
> +       if (wl->sleep_auth != WL1271_PSM_ELP)
> +               return 0;
> +
> +       wl12xx_for_each_wlvif(wl, wlvif) {
> +               if (!test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags) &&
> +                   test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags))
> +                       return -EBUSY;
> +       }
> +
> +       wl1271_debug(DEBUG_PSM, "chip to elp");
> +       error = wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_SLEEP);
> +       if (error < 0) {
> +               wl12xx_queue_recovery_work(wl);
> +
> +               return error;
> +       }
> +
> +       set_bit(WL1271_FLAG_IN_ELP, &wl->flags);
> +
> +       return 0;
> +}
> +
> +static int __maybe_unused wlcore_runtime_resume(struct device *dev)
> +{
> +       struct wl1271 *wl = dev_get_drvdata(dev);
> +       DECLARE_COMPLETION_ONSTACK(compl);
> +       unsigned long flags;
> +       int ret;
> +       unsigned long start_time = jiffies;
> +       bool pending = false;
> +
> +       /* Nothing to do if no ELP mode requested */
> +       if (!test_bit(WL1271_FLAG_IN_ELP, &wl->flags))
> +               return 0;
> +
> +       wl1271_debug(DEBUG_PSM, "waking up chip from elp");
> +
> +       spin_lock_irqsave(&wl->wl_lock, flags);
> +       if (test_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags))
> +               pending = true;
> +       else
> +               wl->elp_compl = &compl;
> +       spin_unlock_irqrestore(&wl->wl_lock, flags);
> +
> +       ret = wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP);
> +       if (ret < 0) {
> +               wl12xx_queue_recovery_work(wl);
> +               goto err;
> +       }
> +
> +       if (!pending) {
> +               ret = wait_for_completion_timeout(&compl,
> +                       msecs_to_jiffies(WL1271_WAKEUP_TIMEOUT));
> +               if (ret == 0) {
> +                       wl1271_error("ELP wakeup timeout!");
> +                       wl12xx_queue_recovery_work(wl);
> +                       ret = -ETIMEDOUT;
> +                       goto err;
> +               }
> +       }
> +
> +       clear_bit(WL1271_FLAG_IN_ELP, &wl->flags);
> +
> +       wl1271_debug(DEBUG_PSM, "wakeup time: %u ms",
> +                    jiffies_to_msecs(jiffies - start_time));
> +       goto out;
> +
> +err:
> +       spin_lock_irqsave(&wl->wl_lock, flags);
> +       wl->elp_compl = NULL;
> +       spin_unlock_irqrestore(&wl->wl_lock, flags);
> +       return ret;
> +
> +out:
> +       return 0;
> +}
> +
> +static const struct dev_pm_ops wlcore_pm_ops = {
> +       SET_RUNTIME_PM_OPS(wlcore_runtime_suspend,
> +                          wlcore_runtime_resume,
> +                          NULL)
> +};
> +
>  int wlcore_probe(struct wl1271 *wl, struct platform_device *pdev)
>  {
>         struct wlcore_platdev_data *pdev_data = dev_get_platdata(&pdev->dev);
> @@ -6608,6 +6775,9 @@ int wlcore_probe(struct wl1271 *wl, struct platform_device *pdev)
>                 wlcore_nvs_cb(NULL, wl);
>         }
>
> +       wl->dev->driver->pm = &wlcore_pm_ops;
> +       pm_runtime_enable(wl->dev);
> +
>         return ret;
>  }
>  EXPORT_SYMBOL_GPL(wlcore_probe);
> @@ -6617,6 +6787,9 @@ int wlcore_remove(struct platform_device *pdev)
>         struct wlcore_platdev_data *pdev_data = dev_get_platdata(&pdev->dev);
>         struct wl1271 *wl = platform_get_drvdata(pdev);
>
> +       pm_runtime_disable(wl->dev);
> +       wl->dev->driver->pm = NULL;
> +
>         if (pdev_data->family && pdev_data->family->nvs_name)
>                 wait_for_completion(&wl->nvs_loading_complete);
>         if (!wl->initialized)
> diff --git a/drivers/net/wireless/ti/wlcore/ps.c b/drivers/net/wireless/ti/wlcore/ps.c
> --- a/drivers/net/wireless/ti/wlcore/ps.c
> +++ b/drivers/net/wireless/ti/wlcore/ps.c
> @@ -26,152 +26,6 @@
>  #include "tx.h"
>  #include "debug.h"
>
> -#define WL1271_WAKEUP_TIMEOUT 500
> -
> -#define ELP_ENTRY_DELAY  30
> -#define ELP_ENTRY_DELAY_FORCE_PS  5
> -
> -void wl1271_elp_work(struct work_struct *work)
> -{
> -       struct delayed_work *dwork;
> -       struct wl1271 *wl;
> -       struct wl12xx_vif *wlvif;
> -       int ret;
> -
> -       dwork = to_delayed_work(work);
> -       wl = container_of(dwork, struct wl1271, elp_work);
> -
> -       wl1271_debug(DEBUG_PSM, "elp work");
> -
> -       mutex_lock(&wl->mutex);
> -
> -       if (unlikely(wl->state != WLCORE_STATE_ON))
> -               goto out;
> -
> -       /* our work might have been already cancelled */
> -       if (unlikely(!test_bit(WL1271_FLAG_ELP_REQUESTED, &wl->flags)))
> -               goto out;
> -
> -       if (test_bit(WL1271_FLAG_IN_ELP, &wl->flags))
> -               goto out;
> -
> -       wl12xx_for_each_wlvif(wl, wlvif) {
> -               if (!test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags) &&
> -                   test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags))
> -                       goto out;
> -       }
> -
> -       wl1271_debug(DEBUG_PSM, "chip to elp");
> -       ret = wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_SLEEP);
> -       if (ret < 0) {
> -               wl12xx_queue_recovery_work(wl);
> -               goto out;
> -       }
> -
> -       set_bit(WL1271_FLAG_IN_ELP, &wl->flags);
> -
> -out:
> -       mutex_unlock(&wl->mutex);
> -}
> -
> -/* Routines to toggle sleep mode while in ELP */
> -void wl1271_ps_elp_sleep(struct wl1271 *wl)
> -{
> -       struct wl12xx_vif *wlvif;
> -       u32 timeout;
> -
> -       /* We do not enter elp sleep in PLT mode */
> -       if (wl->plt)
> -               return;
> -
> -       if (wl->sleep_auth != WL1271_PSM_ELP)
> -               return;
> -
> -       /* we shouldn't get consecutive sleep requests */
> -       if (WARN_ON(test_and_set_bit(WL1271_FLAG_ELP_REQUESTED, &wl->flags)))
> -               return;
> -
> -       wl12xx_for_each_wlvif(wl, wlvif) {
> -               if (!test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags) &&
> -                   test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags))
> -                       return;
> -       }
> -
> -       timeout = wl->conf.conn.forced_ps ?
> -                       ELP_ENTRY_DELAY_FORCE_PS : ELP_ENTRY_DELAY;
> -       ieee80211_queue_delayed_work(wl->hw, &wl->elp_work,
> -                                    msecs_to_jiffies(timeout));
> -}
> -EXPORT_SYMBOL_GPL(wl1271_ps_elp_sleep);
> -
> -int wl1271_ps_elp_wakeup(struct wl1271 *wl)
> -{
> -       DECLARE_COMPLETION_ONSTACK(compl);
> -       unsigned long flags;
> -       int ret;
> -       unsigned long start_time = jiffies;
> -       bool pending = false;
> -
> -       /*
> -        * we might try to wake up even if we didn't go to sleep
> -        * before (e.g. on boot)
> -        */
> -       if (!test_and_clear_bit(WL1271_FLAG_ELP_REQUESTED, &wl->flags))
> -               return 0;
> -
> -       /* don't cancel_sync as it might contend for a mutex and deadlock */
> -       cancel_delayed_work(&wl->elp_work);
> -
> -       if (!test_bit(WL1271_FLAG_IN_ELP, &wl->flags))
> -               return 0;
> -
> -       wl1271_debug(DEBUG_PSM, "waking up chip from elp");
> -
> -       /*
> -        * The spinlock is required here to synchronize both the work and
> -        * the completion variable in one entity.
> -        */
> -       spin_lock_irqsave(&wl->wl_lock, flags);
> -       if (test_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags))
> -               pending = true;
> -       else
> -               wl->elp_compl = &compl;
> -       spin_unlock_irqrestore(&wl->wl_lock, flags);
> -
> -       ret = wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP);
> -       if (ret < 0) {
> -               wl12xx_queue_recovery_work(wl);
> -               goto err;
> -       }
> -
> -       if (!pending) {
> -               ret = wait_for_completion_timeout(
> -                       &compl, msecs_to_jiffies(WL1271_WAKEUP_TIMEOUT));
> -               if (ret == 0) {
> -                       wl1271_error("ELP wakeup timeout!");
> -                       wl12xx_queue_recovery_work(wl);
> -                       ret = -ETIMEDOUT;
> -                       goto err;
> -               }
> -       }
> -
> -       clear_bit(WL1271_FLAG_IN_ELP, &wl->flags);
> -
> -       wl1271_debug(DEBUG_PSM, "wakeup time: %u ms",
> -                    jiffies_to_msecs(jiffies - start_time));
> -       goto out;
> -
> -err:
> -       spin_lock_irqsave(&wl->wl_lock, flags);
> -       wl->elp_compl = NULL;
> -       spin_unlock_irqrestore(&wl->wl_lock, flags);
> -       return ret;
> -
> -out:
> -       return 0;
> -}
> -EXPORT_SYMBOL_GPL(wl1271_ps_elp_wakeup);
> -
>  int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
>                        enum wl1271_cmd_ps_mode mode)
>  {
> diff --git a/drivers/net/wireless/ti/wlcore/ps.h b/drivers/net/wireless/ti/wlcore/ps.h
> --- a/drivers/net/wireless/ti/wlcore/ps.h
> +++ b/drivers/net/wireless/ti/wlcore/ps.h
> @@ -29,9 +29,6 @@
>
>  int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
>                        enum wl1271_cmd_ps_mode mode);
> -void wl1271_ps_elp_sleep(struct wl1271 *wl);
> -int wl1271_ps_elp_wakeup(struct wl1271 *wl);
> -void wl1271_elp_work(struct work_struct *work);
>  void wl12xx_ps_link_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
>                           u8 hlid, bool clean_queues);
>  void wl12xx_ps_link_end(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid);
> diff --git a/drivers/net/wireless/ti/wlcore/scan.c b/drivers/net/wireless/ti/wlcore/scan.c
> --- a/drivers/net/wireless/ti/wlcore/scan.c
> +++ b/drivers/net/wireless/ti/wlcore/scan.c
> @@ -22,6 +22,7 @@
>   */
>
>  #include <linux/ieee80211.h>
> +#include <linux/pm_runtime.h>
>
>  #include "wlcore.h"
>  #include "debug.h"
> @@ -67,16 +68,18 @@ void wl1271_scan_complete_work(struct work_struct *work)
>         wl->scan.req = NULL;
>         wl->scan_wlvif = NULL;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) {
>                 /* restore hardware connection monitoring template */
>                 wl1271_cmd_build_ap_probe_req(wl, wlvif, wlvif->probereq);
>         }
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>
>         if (wl->scan.failed) {
>                 wl1271_info("Scan completed due to error.");
> diff --git a/drivers/net/wireless/ti/wlcore/sysfs.c b/drivers/net/wireless/ti/wlcore/sysfs.c
> --- a/drivers/net/wireless/ti/wlcore/sysfs.c
> +++ b/drivers/net/wireless/ti/wlcore/sysfs.c
> @@ -19,6 +19,8 @@
>   *
>   */
>
> +#include <linux/pm_runtime.h>
> +
>  #include "wlcore.h"
>  #include "debug.h"
>  #include "ps.h"
> @@ -68,12 +70,14 @@ static ssize_t wl1271_sysfs_store_bt_coex_state(struct device *dev,
>         if (unlikely(wl->state != WLCORE_STATE_ON))
>                 goto out;
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         wl1271_acx_sg_enable(wl, wl->sg_enabled);
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>
>   out:
>         mutex_unlock(&wl->mutex);
> diff --git a/drivers/net/wireless/ti/wlcore/testmode.c b/drivers/net/wireless/ti/wlcore/testmode.c
> --- a/drivers/net/wireless/ti/wlcore/testmode.c
> +++ b/drivers/net/wireless/ti/wlcore/testmode.c
> @@ -22,6 +22,7 @@
>   */
>  #include "testmode.h"
>
> +#include <linux/pm_runtime.h>
>  #include <linux/slab.h>
>  #include <net/genetlink.h>
>
> @@ -97,9 +98,11 @@ static int wl1271_tm_cmd_test(struct wl1271 *wl, struct nlattr *tb[])
>                 goto out;
>         }
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         ret = wl1271_cmd_test(wl, buf, buf_len, answer);
>         if (ret < 0) {
> @@ -141,7 +144,7 @@ static int wl1271_tm_cmd_test(struct wl1271 *wl, struct nlattr *tb[])
>         }
>
>  out_sleep:
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>
> @@ -169,9 +172,11 @@ static int wl1271_tm_cmd_interrogate(struct wl1271 *wl, struct nlattr *tb[])
>                 goto out;
>         }
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
>         if (!cmd) {
> @@ -205,7 +210,7 @@ static int wl1271_tm_cmd_interrogate(struct wl1271 *wl, struct nlattr *tb[])
>  out_free:
>         kfree(cmd);
>  out_sleep:
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>
> diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c
> --- a/drivers/net/wireless/ti/wlcore/tx.c
> +++ b/drivers/net/wireless/ti/wlcore/tx.c
> @@ -24,6 +24,7 @@
>  #include <linux/kernel.h>
>  #include <linux/module.h>
>  #include <linux/etherdevice.h>
> +#include <linux/pm_runtime.h>
>  #include <linux/spinlock.h>
>
>  #include "wlcore.h"
> @@ -868,9 +869,11 @@ void wl1271_tx_work(struct work_struct *work)
>         int ret;
>
>         mutex_lock(&wl->mutex);
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         ret = wlcore_tx_work_locked(wl);
>         if (ret < 0) {
> @@ -878,7 +881,7 @@ void wl1271_tx_work(struct work_struct *work)
>                 goto out;
>         }
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>  }
> diff --git a/drivers/net/wireless/ti/wlcore/vendor_cmd.c b/drivers/net/wireless/ti/wlcore/vendor_cmd.c
> --- a/drivers/net/wireless/ti/wlcore/vendor_cmd.c
> +++ b/drivers/net/wireless/ti/wlcore/vendor_cmd.c
> @@ -8,6 +8,8 @@
>   * version 2 as published by the Free Software Foundation.
>   */
>
> +#include <linux/pm_runtime.h>
> +
>  #include <net/mac80211.h>
>  #include <net/netlink.h>
>
> @@ -55,14 +57,16 @@ wlcore_vendor_cmd_smart_config_start(struct wiphy *wiphy,
>                 goto out;
>         }
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         ret = wlcore_smart_config_start(wl,
>                         nla_get_u32(tb[WLCORE_VENDOR_ATTR_GROUP_ID]));
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>
> @@ -87,13 +91,15 @@ wlcore_vendor_cmd_smart_config_stop(struct wiphy *wiphy,
>                 goto out;
>         }
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         ret = wlcore_smart_config_stop(wl);
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>
> @@ -131,16 +137,18 @@ wlcore_vendor_cmd_smart_config_set_group_key(struct wiphy *wiphy,
>                 goto out;
>         }
>
> -       ret = wl1271_ps_elp_wakeup(wl);
> -       if (ret < 0)
> +       ret = pm_runtime_get_sync(wl->dev);
> +       if (ret < 0) {
> +               pm_runtime_put_noidle(wl->dev);
>                 goto out;
> +       }
>
>         ret = wlcore_smart_config_set_group_key(wl,
>                         nla_get_u32(tb[WLCORE_VENDOR_ATTR_GROUP_ID]),
>                         nla_len(tb[WLCORE_VENDOR_ATTR_GROUP_KEY]),
>                         nla_data(tb[WLCORE_VENDOR_ATTR_GROUP_KEY]));
>
> -       wl1271_ps_elp_sleep(wl);
> +       pm_runtime_put(wl->dev);
>  out:
>         mutex_unlock(&wl->mutex);
>
> diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
> --- a/drivers/net/wireless/ti/wlcore/wlcore.h
> +++ b/drivers/net/wireless/ti/wlcore/wlcore.h
> @@ -348,7 +348,6 @@ struct wl1271 {
>         enum nl80211_band band;
>
>         struct completion *elp_compl;
> -       struct delayed_work elp_work;
>
>         /* in dBm */
>         int power_level;
> diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
> --- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
> +++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
> @@ -233,7 +233,6 @@ enum wl12xx_flags {
>         WL1271_FLAG_TX_QUEUE_STOPPED,
>         WL1271_FLAG_TX_PENDING,
>         WL1271_FLAG_IN_ELP,
> -       WL1271_FLAG_ELP_REQUESTED,
>         WL1271_FLAG_IRQ_RUNNING,
>         WL1271_FLAG_FW_TX_BUSY,
>         WL1271_FLAG_DUMMY_PACKET_PENDING,
> --
> 2.17.0
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
| Michael Nazzareno Trimarchi                     Amarula Solutions BV |
| COO  -  Founder                                      Cruquiuskade 47 |
| +31(0)851119172                                 Amsterdam 1018 AM NL |
|                  [`as] http://www.amarulasolutions.com               |
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux