All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-17 18:50 ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-17 18:50 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Eyal Reizer, Kishon Vijay Abraham I, Guy Mishol, Luca Coelho,
	Maital Hahn, Maxim Altshul, Shahar Patury, linux-wireless,
	linux-omap

Hi all,

Here's a series of patches to add runtime PM support for wlcore. It does not
yet implement autosuspend support, but let's get this tested first as the
autosuspend can mask enable/disable issues easily.

Regards,

Tony

Changes since v1:

- Fix issues reported by Eyal for recovery

- Add few patches for enable/disable issues found when using runtime PM

- Remove unused ps.h includes

Tony Lindgren (5):
  wlcore: Add missing PM call for wlcore_cmd_wait_for_event_or_timeout()
  wlcore: Make sure PM calls are paired
  wlcore: Add support for runtime PM
  wlcore: Fix misplaced PM call for scan_complete_work()
  wlcore: sdio: Warn about runtime PM suspend errors

 drivers/net/wireless/ti/wl18xx/debugfs.c    |  26 +-
 drivers/net/wireless/ti/wlcore/acx.c        |   1 -
 drivers/net/wireless/ti/wlcore/cmd.c        |   9 +
 drivers/net/wireless/ti/wlcore/debugfs.c    |  79 ++--
 drivers/net/wireless/ti/wlcore/main.c       | 404 ++++++++++++++------
 drivers/net/wireless/ti/wlcore/ps.c         | 146 -------
 drivers/net/wireless/ti/wlcore/ps.h         |   3 -
 drivers/net/wireless/ti/wlcore/scan.c       |  12 +-
 drivers/net/wireless/ti/wlcore/sdio.c       |   7 +
 drivers/net/wireless/ti/wlcore/sysfs.c      |  12 +-
 drivers/net/wireless/ti/wlcore/testmode.c   |  18 +-
 drivers/net/wireless/ti/wlcore/tx.c         |   9 +-
 drivers/net/wireless/ti/wlcore/vendor_cmd.c |  27 +-
 drivers/net/wireless/ti/wlcore/wlcore.h     |   1 -
 drivers/net/wireless/ti/wlcore/wlcore_i.h   |   1 -
 15 files changed, 421 insertions(+), 334 deletions(-)

-- 
2.17.0

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-17 18:50 ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-17 18:50 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Eyal Reizer, Kishon Vijay Abraham I, Guy Mishol, Luca Coelho,
	Maital Hahn, Maxim Altshul, Shahar Patury,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA

Hi all,

Here's a series of patches to add runtime PM support for wlcore. It does not
yet implement autosuspend support, but let's get this tested first as the
autosuspend can mask enable/disable issues easily.

Regards,

Tony

Changes since v1:

- Fix issues reported by Eyal for recovery

- Add few patches for enable/disable issues found when using runtime PM

- Remove unused ps.h includes

Tony Lindgren (5):
  wlcore: Add missing PM call for wlcore_cmd_wait_for_event_or_timeout()
  wlcore: Make sure PM calls are paired
  wlcore: Add support for runtime PM
  wlcore: Fix misplaced PM call for scan_complete_work()
  wlcore: sdio: Warn about runtime PM suspend errors

 drivers/net/wireless/ti/wl18xx/debugfs.c    |  26 +-
 drivers/net/wireless/ti/wlcore/acx.c        |   1 -
 drivers/net/wireless/ti/wlcore/cmd.c        |   9 +
 drivers/net/wireless/ti/wlcore/debugfs.c    |  79 ++--
 drivers/net/wireless/ti/wlcore/main.c       | 404 ++++++++++++++------
 drivers/net/wireless/ti/wlcore/ps.c         | 146 -------
 drivers/net/wireless/ti/wlcore/ps.h         |   3 -
 drivers/net/wireless/ti/wlcore/scan.c       |  12 +-
 drivers/net/wireless/ti/wlcore/sdio.c       |   7 +
 drivers/net/wireless/ti/wlcore/sysfs.c      |  12 +-
 drivers/net/wireless/ti/wlcore/testmode.c   |  18 +-
 drivers/net/wireless/ti/wlcore/tx.c         |   9 +-
 drivers/net/wireless/ti/wlcore/vendor_cmd.c |  27 +-
 drivers/net/wireless/ti/wlcore/wlcore.h     |   1 -
 drivers/net/wireless/ti/wlcore/wlcore_i.h   |   1 -
 15 files changed, 421 insertions(+), 334 deletions(-)

-- 
2.17.0

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 1/5] wlcore: Add missing PM call for wlcore_cmd_wait_for_event_or_timeout()
@ 2018-05-17 18:50   ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-17 18:50 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Eyal Reizer, Kishon Vijay Abraham I, Guy Mishol, Luca Coelho,
	Maital Hahn, Maxim Altshul, Shahar Patury, linux-wireless,
	linux-omap

Otherwise we can get:

WARNING: CPU: 0 PID: 55 at drivers/net/wireless/ti/wlcore/io.h:84

I've only seen this few times with the runtime PM patches enabled
so this one is probably not needed before that. This seems to
work currently based on the current PM implementation timer. Let's
apply this separately though in case others are hitting this issue.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/net/wireless/ti/wlcore/cmd.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -35,6 +35,7 @@
 #include "wl12xx_80211.h"
 #include "cmd.h"
 #include "event.h"
+#include "ps.h"
 #include "tx.h"
 #include "hw_ops.h"
 
@@ -191,6 +192,10 @@ int wlcore_cmd_wait_for_event_or_timeout(struct wl1271 *wl,
 
 	timeout_time = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT);
 
+	ret = wl1271_ps_elp_wakeup(wl);
+	if (ret < 0)
+		return ret;
+
 	do {
 		if (time_after(jiffies, timeout_time)) {
 			wl1271_debug(DEBUG_CMD, "timeout waiting for event %d",
@@ -222,6 +227,7 @@ int wlcore_cmd_wait_for_event_or_timeout(struct wl1271 *wl,
 	} while (!event);
 
 out:
+	wl1271_ps_elp_sleep(wl);
 	kfree(events_vector);
 	return ret;
 }
-- 
2.17.0

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 1/5] wlcore: Add missing PM call for wlcore_cmd_wait_for_event_or_timeout()
@ 2018-05-17 18:50   ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-17 18:50 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Eyal Reizer, Kishon Vijay Abraham I, Guy Mishol, Luca Coelho,
	Maital Hahn, Maxim Altshul, Shahar Patury,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA

Otherwise we can get:

WARNING: CPU: 0 PID: 55 at drivers/net/wireless/ti/wlcore/io.h:84

I've only seen this few times with the runtime PM patches enabled
so this one is probably not needed before that. This seems to
work currently based on the current PM implementation timer. Let's
apply this separately though in case others are hitting this issue.

Signed-off-by: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
---
 drivers/net/wireless/ti/wlcore/cmd.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -35,6 +35,7 @@
 #include "wl12xx_80211.h"
 #include "cmd.h"
 #include "event.h"
+#include "ps.h"
 #include "tx.h"
 #include "hw_ops.h"
 
@@ -191,6 +192,10 @@ int wlcore_cmd_wait_for_event_or_timeout(struct wl1271 *wl,
 
 	timeout_time = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT);
 
+	ret = wl1271_ps_elp_wakeup(wl);
+	if (ret < 0)
+		return ret;
+
 	do {
 		if (time_after(jiffies, timeout_time)) {
 			wl1271_debug(DEBUG_CMD, "timeout waiting for event %d",
@@ -222,6 +227,7 @@ int wlcore_cmd_wait_for_event_or_timeout(struct wl1271 *wl,
 	} while (!event);
 
 out:
+	wl1271_ps_elp_sleep(wl);
 	kfree(events_vector);
 	return ret;
 }
-- 
2.17.0

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 2/5] wlcore: Make sure PM calls are paired
@ 2018-05-17 18:50   ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-17 18:50 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Eyal Reizer, Kishon Vijay Abraham I, Guy Mishol, Luca Coelho,
	Maital Hahn, Maxim Altshul, Shahar Patury, linux-wireless,
	linux-omap

The call to wl1271_ps_elp_wakeup() in wl12xx_queue_recovery_work() is
unpaired. Let's remove it and add paired calls to wl1271_recovery_work()
instead in preparation for changing things to use runtime PM.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/net/wireless/ti/wlcore/main.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

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
@@ -796,8 +796,6 @@ void wl12xx_queue_recovery_work(struct wl1271 *wl)
 
 		wl->state = WLCORE_STATE_RESTARTING;
 		set_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags);
-		wl1271_ps_elp_wakeup(wl);
-		wlcore_disable_interrupts_nosync(wl);
 		ieee80211_queue_work(wl->hw, &wl->recovery_work);
 	}
 }
@@ -919,12 +917,18 @@ static void wl1271_recovery_work(struct work_struct *work)
 		container_of(work, struct wl1271, recovery_work);
 	struct wl12xx_vif *wlvif;
 	struct ieee80211_vif *vif;
+	int error;
 
 	mutex_lock(&wl->mutex);
 
 	if (wl->state == WLCORE_STATE_OFF || wl->plt)
 		goto out_unlock;
 
+	error = wl1271_ps_elp_wakeup(wl);
+	if (error < 0)
+		wl1271_warning("Enable for recovery failed");
+	wlcore_disable_interrupts_nosync(wl);
+
 	if (!test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)) {
 		if (wl->conf.fwlog.output == WL12XX_FWLOG_OUTPUT_HOST)
 			wl12xx_read_fwlog_panic(wl);
@@ -967,6 +971,8 @@ static void wl1271_recovery_work(struct work_struct *work)
 	 */
 	wlcore_wake_queues(wl, WLCORE_QUEUE_STOP_REASON_FW_RESTART);
 
+	wl1271_ps_elp_sleep(wl);
+
 out_unlock:
 	wl->watchdog_recovery = false;
 	clear_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags);
-- 
2.17.0

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 2/5] wlcore: Make sure PM calls are paired
@ 2018-05-17 18:50   ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-17 18:50 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Eyal Reizer, Kishon Vijay Abraham I, Guy Mishol, Luca Coelho,
	Maital Hahn, Maxim Altshul, Shahar Patury,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA

The call to wl1271_ps_elp_wakeup() in wl12xx_queue_recovery_work() is
unpaired. Let's remove it and add paired calls to wl1271_recovery_work()
instead in preparation for changing things to use runtime PM.

Signed-off-by: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
---
 drivers/net/wireless/ti/wlcore/main.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

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
@@ -796,8 +796,6 @@ void wl12xx_queue_recovery_work(struct wl1271 *wl)
 
 		wl->state = WLCORE_STATE_RESTARTING;
 		set_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags);
-		wl1271_ps_elp_wakeup(wl);
-		wlcore_disable_interrupts_nosync(wl);
 		ieee80211_queue_work(wl->hw, &wl->recovery_work);
 	}
 }
@@ -919,12 +917,18 @@ static void wl1271_recovery_work(struct work_struct *work)
 		container_of(work, struct wl1271, recovery_work);
 	struct wl12xx_vif *wlvif;
 	struct ieee80211_vif *vif;
+	int error;
 
 	mutex_lock(&wl->mutex);
 
 	if (wl->state == WLCORE_STATE_OFF || wl->plt)
 		goto out_unlock;
 
+	error = wl1271_ps_elp_wakeup(wl);
+	if (error < 0)
+		wl1271_warning("Enable for recovery failed");
+	wlcore_disable_interrupts_nosync(wl);
+
 	if (!test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)) {
 		if (wl->conf.fwlog.output == WL12XX_FWLOG_OUTPUT_HOST)
 			wl12xx_read_fwlog_panic(wl);
@@ -967,6 +971,8 @@ static void wl1271_recovery_work(struct work_struct *work)
 	 */
 	wlcore_wake_queues(wl, WLCORE_QUEUE_STOP_REASON_FW_RESTART);
 
+	wl1271_ps_elp_sleep(wl);
+
 out_unlock:
 	wl->watchdog_recovery = false;
 	clear_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags);
-- 
2.17.0

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 3/5] wlcore: Add support for runtime PM
@ 2018-05-17 18:50   ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-17 18:50 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Eyal Reizer, Kishon Vijay Abraham I, Guy Mishol, Luca Coelho,
	Maital Hahn, Maxim Altshul, Shahar Patury, linux-wireless,
	linux-omap

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.

Pretty much the only place where we are not just converting the existing
functions is wl1271_op_suspend() where we add pm_runtime_put_noidle()
to keep the calls paired.

As the next step is to implement runtime PM autosuspend, let's not add
wrapper functions for the generic runtime PM calls. We would be getting
rid of any wrapper functions anyways.

After autoidle we should be able to start using Linux generic wakeirqs
for the padconf interrupt.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/net/wireless/ti/wl18xx/debugfs.c    |  26 +-
 drivers/net/wireless/ti/wlcore/acx.c        |   1 -
 drivers/net/wireless/ti/wlcore/cmd.c        |  11 +-
 drivers/net/wireless/ti/wlcore/debugfs.c    |  79 ++--
 drivers/net/wireless/ti/wlcore/main.c       | 400 ++++++++++++++------
 drivers/net/wireless/ti/wlcore/ps.c         | 146 -------
 drivers/net/wireless/ti/wlcore/ps.h         |   3 -
 drivers/net/wireless/ti/wlcore/scan.c       |  10 +-
 drivers/net/wireless/ti/wlcore/sysfs.c      |  12 +-
 drivers/net/wireless/ti/wlcore/testmode.c   |  18 +-
 drivers/net/wireless/ti/wlcore/tx.c         |   9 +-
 drivers/net/wireless/ti/wlcore/vendor_cmd.c |  27 +-
 drivers/net/wireless/ti/wlcore/wlcore.h     |   1 -
 drivers/net/wireless/ti/wlcore/wlcore_i.h   |   1 -
 14 files changed, 406 insertions(+), 338 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;
+	}
 
 	ret = wl18xx_acx_dynamic_fw_traces(wl);
 	if (ret < 0)
 		count = ret;
 
-	wl1271_ps_elp_sleep(wl);
+	pm_runtime_put(wl->dev);
 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);
 out:
 	mutex_unlock(&wl->mutex);
 	return count;
diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c
--- a/drivers/net/wireless/ti/wlcore/acx.c
+++ b/drivers/net/wireless/ti/wlcore/acx.c
@@ -31,7 +31,6 @@
 #include "wlcore.h"
 #include "debug.h"
 #include "wl12xx_80211.h"
-#include "ps.h"
 #include "hw_ops.h"
 
 int wl1271_acx_wake_up_conditions(struct wl1271 *wl, struct wl12xx_vif *wlvif,
diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -23,6 +23,7 @@
 
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/spi/spi.h>
 #include <linux/etherdevice.h>
 #include <linux/ieee80211.h>
@@ -35,7 +36,6 @@
 #include "wl12xx_80211.h"
 #include "cmd.h"
 #include "event.h"
-#include "ps.h"
 #include "tx.h"
 #include "hw_ops.h"
 
@@ -192,9 +192,12 @@ int wlcore_cmd_wait_for_event_or_timeout(struct wl1271 *wl,
 
 	timeout_time = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT);
 
-	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 ret;
+	}
 
 	do {
 		if (time_after(jiffies, timeout_time)) {
@@ -227,7 +230,7 @@ int wlcore_cmd_wait_for_event_or_timeout(struct wl1271 *wl,
 	} while (!event);
 
 out:
-	wl1271_ps_elp_sleep(wl);
+	pm_runtime_put(wl->dev);
 	kfree(events_vector);
 	return ret;
 }
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;
@@ -817,6 +826,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;
@@ -828,8 +838,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);
@@ -924,9 +937,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);
+	}
 	wlcore_disable_interrupts_nosync(wl);
 
 	if (!test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)) {
@@ -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,97 @@ 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);
+			/* Return no error for runtime PM for recovery */
+		}
+	}
+
+	clear_bit(WL1271_FLAG_IN_ELP, &wl->flags);
+
+	wl1271_debug(DEBUG_PSM, "wakeup time: %u ms",
+		     jiffies_to_msecs(jiffies - start_time));
+
+	return 0;
+
+err:
+	spin_lock_irqsave(&wl->wl_lock, flags);
+	wl->elp_compl = NULL;
+	spin_unlock_irqrestore(&wl->wl_lock, flags);
+	return ret;
+}
+
+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 +6772,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 +6784,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,13 +22,13 @@
  */
 
 #include <linux/ieee80211.h>
+#include <linux/pm_runtime.h>
 
 #include "wlcore.h"
 #include "debug.h"
 #include "cmd.h"
 #include "scan.h"
 #include "acx.h"
-#include "ps.h"
 #include "tx.h"
 
 void wl1271_scan_complete_work(struct work_struct *work)
@@ -67,16 +67,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,9 +19,11 @@
  *
  */
 
+#include <linux/pm_runtime.h>
+
+#include "acx.h"
 #include "wlcore.h"
 #include "debug.h"
-#include "ps.h"
 #include "sysfs.h"
 
 static ssize_t wl1271_sysfs_show_bt_coex_state(struct device *dev,
@@ -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,13 +22,13 @@
  */
 #include "testmode.h"
 
+#include <linux/pm_runtime.h>
 #include <linux/slab.h>
 #include <net/genetlink.h>
 
 #include "wlcore.h"
 #include "debug.h"
 #include "acx.h"
-#include "ps.h"
 #include "io.h"
 
 #define WL1271_TM_MAX_DATA_LENGTH 1024
@@ -97,9 +97,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 +143,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 +171,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 +209,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,12 +8,13 @@
  * version 2 as published by the Free Software Foundation.
  */
 
+#include <linux/pm_runtime.h>
+
 #include <net/mac80211.h>
 #include <net/netlink.h>
 
 #include "wlcore.h"
 #include "debug.h"
-#include "ps.h"
 #include "hw_ops.h"
 #include "vendor_cmd.h"
 
@@ -55,14 +56,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 +90,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 +136,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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 3/5] wlcore: Add support for runtime PM
@ 2018-05-17 18:50   ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-17 18:50 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Eyal Reizer, Kishon Vijay Abraham I, Guy Mishol, Luca Coelho,
	Maital Hahn, Maxim Altshul, Shahar Patury,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA

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.

Pretty much the only place where we are not just converting the existing
functions is wl1271_op_suspend() where we add pm_runtime_put_noidle()
to keep the calls paired.

As the next step is to implement runtime PM autosuspend, let's not add
wrapper functions for the generic runtime PM calls. We would be getting
rid of any wrapper functions anyways.

After autoidle we should be able to start using Linux generic wakeirqs
for the padconf interrupt.

Signed-off-by: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
---
 drivers/net/wireless/ti/wl18xx/debugfs.c    |  26 +-
 drivers/net/wireless/ti/wlcore/acx.c        |   1 -
 drivers/net/wireless/ti/wlcore/cmd.c        |  11 +-
 drivers/net/wireless/ti/wlcore/debugfs.c    |  79 ++--
 drivers/net/wireless/ti/wlcore/main.c       | 400 ++++++++++++++------
 drivers/net/wireless/ti/wlcore/ps.c         | 146 -------
 drivers/net/wireless/ti/wlcore/ps.h         |   3 -
 drivers/net/wireless/ti/wlcore/scan.c       |  10 +-
 drivers/net/wireless/ti/wlcore/sysfs.c      |  12 +-
 drivers/net/wireless/ti/wlcore/testmode.c   |  18 +-
 drivers/net/wireless/ti/wlcore/tx.c         |   9 +-
 drivers/net/wireless/ti/wlcore/vendor_cmd.c |  27 +-
 drivers/net/wireless/ti/wlcore/wlcore.h     |   1 -
 drivers/net/wireless/ti/wlcore/wlcore_i.h   |   1 -
 14 files changed, 406 insertions(+), 338 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;
+	}
 
 	ret = wl18xx_acx_dynamic_fw_traces(wl);
 	if (ret < 0)
 		count = ret;
 
-	wl1271_ps_elp_sleep(wl);
+	pm_runtime_put(wl->dev);
 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);
 out:
 	mutex_unlock(&wl->mutex);
 	return count;
diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c
--- a/drivers/net/wireless/ti/wlcore/acx.c
+++ b/drivers/net/wireless/ti/wlcore/acx.c
@@ -31,7 +31,6 @@
 #include "wlcore.h"
 #include "debug.h"
 #include "wl12xx_80211.h"
-#include "ps.h"
 #include "hw_ops.h"
 
 int wl1271_acx_wake_up_conditions(struct wl1271 *wl, struct wl12xx_vif *wlvif,
diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -23,6 +23,7 @@
 
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/spi/spi.h>
 #include <linux/etherdevice.h>
 #include <linux/ieee80211.h>
@@ -35,7 +36,6 @@
 #include "wl12xx_80211.h"
 #include "cmd.h"
 #include "event.h"
-#include "ps.h"
 #include "tx.h"
 #include "hw_ops.h"
 
@@ -192,9 +192,12 @@ int wlcore_cmd_wait_for_event_or_timeout(struct wl1271 *wl,
 
 	timeout_time = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT);
 
-	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 ret;
+	}
 
 	do {
 		if (time_after(jiffies, timeout_time)) {
@@ -227,7 +230,7 @@ int wlcore_cmd_wait_for_event_or_timeout(struct wl1271 *wl,
 	} while (!event);
 
 out:
-	wl1271_ps_elp_sleep(wl);
+	pm_runtime_put(wl->dev);
 	kfree(events_vector);
 	return ret;
 }
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;
@@ -817,6 +826,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;
@@ -828,8 +838,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);
@@ -924,9 +937,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);
+	}
 	wlcore_disable_interrupts_nosync(wl);
 
 	if (!test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)) {
@@ -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,97 @@ 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);
+			/* Return no error for runtime PM for recovery */
+		}
+	}
+
+	clear_bit(WL1271_FLAG_IN_ELP, &wl->flags);
+
+	wl1271_debug(DEBUG_PSM, "wakeup time: %u ms",
+		     jiffies_to_msecs(jiffies - start_time));
+
+	return 0;
+
+err:
+	spin_lock_irqsave(&wl->wl_lock, flags);
+	wl->elp_compl = NULL;
+	spin_unlock_irqrestore(&wl->wl_lock, flags);
+	return ret;
+}
+
+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 +6772,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 +6784,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,13 +22,13 @@
  */
 
 #include <linux/ieee80211.h>
+#include <linux/pm_runtime.h>
 
 #include "wlcore.h"
 #include "debug.h"
 #include "cmd.h"
 #include "scan.h"
 #include "acx.h"
-#include "ps.h"
 #include "tx.h"
 
 void wl1271_scan_complete_work(struct work_struct *work)
@@ -67,16 +67,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,9 +19,11 @@
  *
  */
 
+#include <linux/pm_runtime.h>
+
+#include "acx.h"
 #include "wlcore.h"
 #include "debug.h"
-#include "ps.h"
 #include "sysfs.h"
 
 static ssize_t wl1271_sysfs_show_bt_coex_state(struct device *dev,
@@ -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,13 +22,13 @@
  */
 #include "testmode.h"
 
+#include <linux/pm_runtime.h>
 #include <linux/slab.h>
 #include <net/genetlink.h>
 
 #include "wlcore.h"
 #include "debug.h"
 #include "acx.h"
-#include "ps.h"
 #include "io.h"
 
 #define WL1271_TM_MAX_DATA_LENGTH 1024
@@ -97,9 +97,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 +143,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 +171,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 +209,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,12 +8,13 @@
  * version 2 as published by the Free Software Foundation.
  */
 
+#include <linux/pm_runtime.h>
+
 #include <net/mac80211.h>
 #include <net/netlink.h>
 
 #include "wlcore.h"
 #include "debug.h"
-#include "ps.h"
 #include "hw_ops.h"
 #include "vendor_cmd.h"
 
@@ -55,14 +56,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 +90,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 +136,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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 4/5] wlcore: Fix misplaced PM call for scan_complete_work()
@ 2018-05-17 18:50   ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-17 18:50 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Eyal Reizer, Kishon Vijay Abraham I, Guy Mishol, Luca Coelho,
	Maital Hahn, Maxim Altshul, Shahar Patury, linux-wireless,
	linux-omap

With runtime PM enabled, we now need to have wlcore enabled longer
until after we're done calling wlcore_cmd_regdomain_config_locked():

scan_complete_work()
 wlcore_cmd_regdomain_config_locked()
   wlcore_cmd_send_failsafe()
     wl12xx_sdio_raw_read()

Note that this is not needed before runtime PM support as the
custom PM code had it's own timer. We have not yet enabled runtime
PM autosuspend for wlcore and this is why this issue now shows up.

Let's fix the issues first before we enable runtime PM autosuspend.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/net/wireless/ti/wlcore/scan.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

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
@@ -78,8 +78,6 @@ void wl1271_scan_complete_work(struct work_struct *work)
 		wl1271_cmd_build_ap_probe_req(wl, wlvif, wlvif->probereq);
 	}
 
-	pm_runtime_put(wl->dev);
-
 	if (wl->scan.failed) {
 		wl1271_info("Scan completed due to error.");
 		wl12xx_queue_recovery_work(wl);
@@ -87,6 +85,8 @@ void wl1271_scan_complete_work(struct work_struct *work)
 
 	wlcore_cmd_regdomain_config_locked(wl);
 
+	pm_runtime_put(wl->dev);
+
 	ieee80211_scan_completed(wl->hw, &info);
 
 out:
-- 
2.17.0

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 4/5] wlcore: Fix misplaced PM call for scan_complete_work()
@ 2018-05-17 18:50   ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-17 18:50 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Eyal Reizer, Kishon Vijay Abraham I, Guy Mishol, Luca Coelho,
	Maital Hahn, Maxim Altshul, Shahar Patury,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA

With runtime PM enabled, we now need to have wlcore enabled longer
until after we're done calling wlcore_cmd_regdomain_config_locked():

scan_complete_work()
 wlcore_cmd_regdomain_config_locked()
   wlcore_cmd_send_failsafe()
     wl12xx_sdio_raw_read()

Note that this is not needed before runtime PM support as the
custom PM code had it's own timer. We have not yet enabled runtime
PM autosuspend for wlcore and this is why this issue now shows up.

Let's fix the issues first before we enable runtime PM autosuspend.

Signed-off-by: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
---
 drivers/net/wireless/ti/wlcore/scan.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

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
@@ -78,8 +78,6 @@ void wl1271_scan_complete_work(struct work_struct *work)
 		wl1271_cmd_build_ap_probe_req(wl, wlvif, wlvif->probereq);
 	}
 
-	pm_runtime_put(wl->dev);

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 5/5] wlcore: sdio: Warn about runtime PM suspend errors
@ 2018-05-17 18:50   ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-17 18:50 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Eyal Reizer, Kishon Vijay Abraham I, Guy Mishol, Luca Coelho,
	Maital Hahn, Maxim Altshul, Shahar Patury, linux-wireless,
	linux-omap

We may get -EBUSY from runtime PM and that most likely means some
earlier wlcore command did not complete yet and further calls may
fail. Let's add a warning to make it easier to track down and fix
such issues in wlcore code.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/net/wireless/ti/wlcore/sdio.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c
--- a/drivers/net/wireless/ti/wlcore/sdio.c
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
@@ -188,6 +188,13 @@ static int wl12xx_sdio_power_off(struct wl12xx_sdio_glue *glue)
 		return error;
 	}
 
+	if (error == -EBUSY) {
+		dev_warn(&card->dev,
+			 "%s: wlcore write did not yet complete?\n",
+			__func__);
+		dump_stack();
+	}
+
 	return 0;
 }
 
-- 
2.17.0

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 5/5] wlcore: sdio: Warn about runtime PM suspend errors
@ 2018-05-17 18:50   ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-17 18:50 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Eyal Reizer, Kishon Vijay Abraham I, Guy Mishol, Luca Coelho,
	Maital Hahn, Maxim Altshul, Shahar Patury,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA

We may get -EBUSY from runtime PM and that most likely means some
earlier wlcore command did not complete yet and further calls may
fail. Let's add a warning to make it easier to track down and fix
such issues in wlcore code.

Signed-off-by: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
---
 drivers/net/wireless/ti/wlcore/sdio.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c
--- a/drivers/net/wireless/ti/wlcore/sdio.c
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
@@ -188,6 +188,13 @@ static int wl12xx_sdio_power_off(struct wl12xx_sdio_glue *glue)
 		return error;
 	}
 
+	if (error == -EBUSY) {
+		dev_warn(&card->dev,
+			 "%s: wlcore write did not yet complete?\n",
+			__func__);
+		dump_stack();
+	}
+
 	return 0;
 }
 
-- 
2.17.0

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-17 18:59   ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-17 18:59 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Eyal Reizer, Kishon Vijay Abraham I, Guy Mishol, Luca Coelho,
	Maital Hahn, Maxim Altshul, Shahar Patury, linux-wireless,
	linux-omap

* Tony Lindgren <tony@atomide.com> [180517 18:52]:
> Hi all,
> 
> Here's a series of patches to add runtime PM support for wlcore. It does not
> yet implement autosuspend support, but let's get this tested first as the
> autosuspend can mask enable/disable issues easily.

Sorry forgot to mention that you will want to have patch
"[PATCHv2] wlcore: sdio: Fix flakey SDIO runtime PM handling"
applied when testing to avoid bogus errors.

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-17 18:59   ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-17 18:59 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Eyal Reizer, Kishon Vijay Abraham I, Guy Mishol, Luca Coelho,
	Maital Hahn, Maxim Altshul, Shahar Patury,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA

* Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> [180517 18:52]:
> Hi all,
> 
> Here's a series of patches to add runtime PM support for wlcore. It does not
> yet implement autosuspend support, but let's get this tested first as the
> autosuspend can mask enable/disable issues easily.

Sorry forgot to mention that you will want to have patch
"[PATCHv2] wlcore: sdio: Fix flakey SDIO runtime PM handling"
applied when testing to avoid bogus errors.

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* RE: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-21  7:29   ` Reizer, Eyal
  0 siblings, 0 replies; 46+ messages in thread
From: Reizer, Eyal @ 2018-05-21  7:29 UTC (permalink / raw)
  To: Tony Lindgren, Kalle Valo
  Cc: KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn, Maital,
	Altshul, Maxim, Shahar Patury, linux-wireless, linux-omap, Loewy,
	Chen

Hi Tony,

>=20
> Hi all,
>=20
> Here's a series of patches to add runtime PM support for wlcore. It does =
not
> yet implement autosuspend support, but let's get this tested first as the
> autosuspend can mask enable/disable issues easily.
>=20
> Regards,
>=20
> Tony
>=20
> Changes since v1:
>=20
> - Fix issues reported by Eyal for recovery
>=20

Testing on BBB+WL1837 cape, scan, recovery, down/up and basic traffic seems=
 ok now.
Of course we need to test some more.
Standard suspend/resume seems to work ok as well.
Ennabling wowlan and suspending is  crashing on resume. See below.

root@am335x-evm:/usr/share/wl18xx# iw phy0 wowlan enable any=20
root@am335x-evm:/usr/share/wl18xx#
root@am335x-evm:/usr/share/wl18xx# echo mem > /sys/power/state
[  541.567039] PM: suspend entry (deep)
[  541.570688] PM: Syncing filesystems ... done.
[  541.594277] Freezing user space processes ... (elapsed 0.001 seconds) do=
ne.
[  541.603160] OOM killer disabled.
[  541.606738] Freezing remaining freezable tasks ... (elapsed 0.001 second=
s) done.
[  541.615984] Suspending console(s) (use no_console_suspend to debug)
[  542.895091] pm33xx pm33xx: PM: Successfully put all powerdomains to targ=
et state
[  542.895091] PM: Wakeup source UART
[  542.919791] net eth0: initializing cpsw version 1.12 (0)
[  543.017880] SMSC LAN8710/LAN8720 4a101000.mdio:00: attached PHY driver [=
SMSC LAN8710/LAN8720] (mii_bus:phy_addr=3D4a101000.mdio:00, irq=3DPOLL)
[  543.027646] ------------[ cut here ]------------
[  543.028023] WARNING: CPU: 0 PID: 932 at drivers/net/wireless/ti/wlcore/c=
md.c:76 wlcore_cmd_send_failsafe+0x498/0x4f8 [wlcore]
[  543.028033] Modules linked in: ctr aes_arm_bs crypto_simd cryptd ccm arc=
4 pru_rproc pruss_intc wl18xx usb_f_acm u_serial wlcore mac80211 cfg80211 p=
russ usb_f_ecm musb_dsps musb_hdrc usbcore phy_am335x phy_generic phy_am335=
x_control xfrm_user xfrm4_tunnel ipcomp xfrm_ipcomp esp4 ah4 af_key xfrm_al=
go g_multi usb_f_mass_storage usb_f_rndis u_ether libcomposite udc_core usb=
_common bluetooth ecdh_generic snd_soc_simple_card snd_soc_simple_card_util=
s pm33xx wkup_m3_ipc wkup_m3_rproc remoteproc omap_aes_driver crypto_engine=
 omap_crypto omap_sham ti_emif_sram pruss_soc_bus wlcore_sdio rtc_omap musb=
_am335x omap_wdt sch_fq_codel
[  543.028408] CPU: 0 PID: 932 Comm: kworker/u2:9 Not tainted 4.14.40-01413=
-g36a61bea-dirty #104
[  543.028418] Hardware name: Generic AM33XX (Flattened Device Tree)
[  543.028466] Workqueue: events_unbound async_run_entry_fn
[  543.028480] Backtrace:
[  543.028541] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+=
0x18/0x1c)
[  543.028565]  r6:00000000 r5:bf3a759c r4:00000000 r3:c0d53158
[  543.028602] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20=
/0x28)
[  543.028637] [<c0805db0>] (dump_stack) from [<c01287bc>] (__warn+0xdc/0x1=
04)
[  543.028665] [<c01286e0>] (__warn) from [<c012880c>] (warn_slowpath_null+=
0x28/0x30)
[  543.028691]  r10:c0d5310c r8:00000000 r7:00000000 r6:d6be5080 r5:0000000=
c r4:db59ed00
[  543.028896] [<c01287e4>] (warn_slowpath_null) from [<bf393874>] (wlcore_=
cmd_send_failsafe+0x498/0x4f8 [wlcore])
[  543.029232] [<bf3933dc>] (wlcore_cmd_send_failsafe [wlcore]) from [<bf39=
4e60>] (wlcore_cmd_configure_failsafe+0x60/0xd8 [wlcore])
[  543.029259]  r10:c0d5310c r9:db59e258 r8:00000000 r7:00000000 r6:0000002=
4 r5:db59ed00
[  543.029269]  r4:d6be5080
[  543.029597] [<bf394e00>] (wlcore_cmd_configure_failsafe [wlcore]) from [=
<bf394ef4>] (wl1271_cmd_configure+0x1c/0x28 [wlcore])
[  543.029614]  r6:db59ed00 r5:00000001 r4:d6be5080
[  543.029943] [<bf394ed8>] (wl1271_cmd_configure [wlcore]) from [<bf39da70=
>] (wl1271_acx_default_rx_filter_enable+0x60/0xac [wlcore])
[  543.030272] [<bf39da10>] (wl1271_acx_default_rx_filter_enable [wlcore]) =
from [<bf39201c>] (wl1271_configure_wowlan+0x148/0x3c4 [wlcore])
[  543.030292]  r7:db59ed38 r6:db59ee20 r5:00000000 r4:dc705bc8
[  543.030616] [<bf391ed4>] (wl1271_configure_wowlan [wlcore]) from [<bf392=
5a8>] (wl1271_op_resume+0x310/0x344 [wlcore])
[  543.030643]  r10:c0d5310c r9:db59e258 r8:00000000 r7:db59ed38 r6:db59ee2=
0 r5:db59ed00
[  543.030652]  r4:dc705bc8
[  543.031484] [<bf392298>] (wl1271_op_resume [wlcore]) from [<bf343a0c>] (=
ieee80211_reconfig+0x418/0xc0c [mac80211])
[  543.031509]  r8:00000000 r7:db59e28c r6:bf2c75e8 r5:00000000 r4:db59e420
[  543.032290] [<bf3435f4>] (ieee80211_reconfig [mac80211]) from [<bf32fd9c=
>] (ieee80211_resume+0x58/0x70 [mac80211])
[  543.032318]  r10:c0d5310c r9:db59e258 r8:00000000 r7:db59e28c r6:bf2c75e=
8 r5:00000000
[  543.032327]  r4:db59e420
[  543.033150] [<bf32fd44>] (ieee80211_resume [mac80211]) from [<bf2c763c>]=
 (wiphy_resume+0x54/0x64 [cfg80211])
[  543.033165]  r4:db59e258 r3:bf32fd44
[  543.033448] [<bf2c75e8>] (wiphy_resume [cfg80211]) from [<c053c79c>] (dp=
m_run_callback+0x40/0xcc)
[  543.033462]  r4:00000000 r3:00000000
[  543.033489] [<c053c75c>] (dpm_run_callback) from [<c053ce24>] (device_re=
sume+0xbc/0x234)
[  543.033515]  r10:00000000 r9:dc005000 r8:00000000 r6:00000010 r5:0000000=
1 r4:db59e258
[  543.033542] [<c053cd68>] (device_resume) from [<c053cfbc>] (async_resume=
+0x20/0x4c)
[  543.033567]  r8:00000000 r7:dc004100 r6:c0d4fde0 r5:c0d89b30 r4:db59e258=
 r3:00000000
[  543.033600] [<c053cf9c>] (async_resume) from [<c01483e4>] (async_run_ent=
ry_fn+0x44/0x140)
[  543.033614]  r5:d6be5480 r4:d6be5490
[  543.033646] [<c01483a0>] (async_run_entry_fn) from [<c013f128>] (process=
_one_work+0x12c/0x374)
[  543.033666]  r6:dc005000 r5:d6be5490 r4:db5ee780 r3:c01483a0
[  543.033690] [<c013effc>] (process_one_work) from [<c013f570>] (worker_th=
read+0x1c0/0x5b8)
[  543.033717]  r10:00000088 r9:dc005000 r8:c0d16380 r7:db5ee798 r6:dc00501=
4 r5:dc005000
[  543.033727]  r4:db5ee780
[  543.033760] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11=
c/0x154)
[  543.033786]  r10:c013f3b0 r9:db5a1eb4 r8:db5ee780 r7:d6be53d8 r6:d6be550=
0 r5:00000000
[  543.033798]  r4:d6be53c0 r3:00000000
[  543.033833] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14=
/0x2c)
[  543.033859]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:0000000=
0 r5:c0145150
[  543.033872]  r4:d6be5500 r3:ffffffff
[  543.033885] ---[ end trace 980798e27041136d ]---

> - Add few patches for enable/disable issues found when using runtime PM
>=20
> - Remove unused ps.h includes
>=20
> Tony Lindgren (5):
>   wlcore: Add missing PM call for wlcore_cmd_wait_for_event_or_timeout()
>   wlcore: Make sure PM calls are paired
>   wlcore: Add support for runtime PM
>   wlcore: Fix misplaced PM call for scan_complete_work()
>   wlcore: sdio: Warn about runtime PM suspend errors
>=20
>  drivers/net/wireless/ti/wl18xx/debugfs.c    |  26 +-
>  drivers/net/wireless/ti/wlcore/acx.c        |   1 -
>  drivers/net/wireless/ti/wlcore/cmd.c        |   9 +
>  drivers/net/wireless/ti/wlcore/debugfs.c    |  79 ++--
>  drivers/net/wireless/ti/wlcore/main.c       | 404 ++++++++++++++------
>  drivers/net/wireless/ti/wlcore/ps.c         | 146 -------
>  drivers/net/wireless/ti/wlcore/ps.h         |   3 -
>  drivers/net/wireless/ti/wlcore/scan.c       |  12 +-
>  drivers/net/wireless/ti/wlcore/sdio.c       |   7 +
>  drivers/net/wireless/ti/wlcore/sysfs.c      |  12 +-
>  drivers/net/wireless/ti/wlcore/testmode.c   |  18 +-
>  drivers/net/wireless/ti/wlcore/tx.c         |   9 +-
>  drivers/net/wireless/ti/wlcore/vendor_cmd.c |  27 +-
>  drivers/net/wireless/ti/wlcore/wlcore.h     |   1 -
>  drivers/net/wireless/ti/wlcore/wlcore_i.h   |   1 -
>  15 files changed, 421 insertions(+), 334 deletions(-)
>=20
> --
> 2.17.0

Best Regards,
Eyal

^ permalink raw reply	[flat|nested] 46+ messages in thread

* RE: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-21  7:29   ` Reizer, Eyal
  0 siblings, 0 replies; 46+ messages in thread
From: Reizer, Eyal @ 2018-05-21  7:29 UTC (permalink / raw)
  To: Tony Lindgren, Kalle Valo
  Cc: KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn, Maital,
	Altshul, Maxim, Shahar Patury,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Loewy, Chen

Hi Tony,

> 
> Hi all,
> 
> Here's a series of patches to add runtime PM support for wlcore. It does not
> yet implement autosuspend support, but let's get this tested first as the
> autosuspend can mask enable/disable issues easily.
> 
> Regards,
> 
> Tony
> 
> Changes since v1:
> 
> - Fix issues reported by Eyal for recovery
> 

Testing on BBB+WL1837 cape, scan, recovery, down/up and basic traffic seems ok now.
Of course we need to test some more.
Standard suspend/resume seems to work ok as well.
Ennabling wowlan and suspending is  crashing on resume. See below.

root@am335x-evm:/usr/share/wl18xx# iw phy0 wowlan enable any 
root@am335x-evm:/usr/share/wl18xx#
root@am335x-evm:/usr/share/wl18xx# echo mem > /sys/power/state
[  541.567039] PM: suspend entry (deep)
[  541.570688] PM: Syncing filesystems ... done.
[  541.594277] Freezing user space processes ... (elapsed 0.001 seconds) done.
[  541.603160] OOM killer disabled.
[  541.606738] Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done.
[  541.615984] Suspending console(s) (use no_console_suspend to debug)
[  542.895091] pm33xx pm33xx: PM: Successfully put all powerdomains to target state
[  542.895091] PM: Wakeup source UART
[  542.919791] net eth0: initializing cpsw version 1.12 (0)
[  543.017880] SMSC LAN8710/LAN8720 4a101000.mdio:00: attached PHY driver [SMSC LAN8710/LAN8720] (mii_bus:phy_addr=4a101000.mdio:00, irq=POLL)
[  543.027646] ------------[ cut here ]------------
[  543.028023] WARNING: CPU: 0 PID: 932 at drivers/net/wireless/ti/wlcore/cmd.c:76 wlcore_cmd_send_failsafe+0x498/0x4f8 [wlcore]
[  543.028033] Modules linked in: ctr aes_arm_bs crypto_simd cryptd ccm arc4 pru_rproc pruss_intc wl18xx usb_f_acm u_serial wlcore mac80211 cfg80211 pruss usb_f_ecm musb_dsps musb_hdrc usbcore phy_am335x phy_generic phy_am335x_control xfrm_user xfrm4_tunnel ipcomp xfrm_ipcomp esp4 ah4 af_key xfrm_algo g_multi usb_f_mass_storage usb_f_rndis u_ether libcomposite udc_core usb_common bluetooth ecdh_generic snd_soc_simple_card snd_soc_simple_card_utils pm33xx wkup_m3_ipc wkup_m3_rproc remoteproc omap_aes_driver crypto_engine omap_crypto omap_sham ti_emif_sram pruss_soc_bus wlcore_sdio rtc_omap musb_am335x omap_wdt sch_fq_codel
[  543.028408] CPU: 0 PID: 932 Comm: kworker/u2:9 Not tainted 4.14.40-01413-g36a61bea-dirty #104
[  543.028418] Hardware name: Generic AM33XX (Flattened Device Tree)
[  543.028466] Workqueue: events_unbound async_run_entry_fn
[  543.028480] Backtrace:
[  543.028541] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+0x18/0x1c)
[  543.028565]  r6:00000000 r5:bf3a759c r4:00000000 r3:c0d53158
[  543.028602] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20/0x28)
[  543.028637] [<c0805db0>] (dump_stack) from [<c01287bc>] (__warn+0xdc/0x104)
[  543.028665] [<c01286e0>] (__warn) from [<c012880c>] (warn_slowpath_null+0x28/0x30)
[  543.028691]  r10:c0d5310c r8:00000000 r7:00000000 r6:d6be5080 r5:0000000c r4:db59ed00
[  543.028896] [<c01287e4>] (warn_slowpath_null) from [<bf393874>] (wlcore_cmd_send_failsafe+0x498/0x4f8 [wlcore])
[  543.029232] [<bf3933dc>] (wlcore_cmd_send_failsafe [wlcore]) from [<bf394e60>] (wlcore_cmd_configure_failsafe+0x60/0xd8 [wlcore])
[  543.029259]  r10:c0d5310c r9:db59e258 r8:00000000 r7:00000000 r6:00000024 r5:db59ed00
[  543.029269]  r4:d6be5080
[  543.029597] [<bf394e00>] (wlcore_cmd_configure_failsafe [wlcore]) from [<bf394ef4>] (wl1271_cmd_configure+0x1c/0x28 [wlcore])
[  543.029614]  r6:db59ed00 r5:00000001 r4:d6be5080
[  543.029943] [<bf394ed8>] (wl1271_cmd_configure [wlcore]) from [<bf39da70>] (wl1271_acx_default_rx_filter_enable+0x60/0xac [wlcore])
[  543.030272] [<bf39da10>] (wl1271_acx_default_rx_filter_enable [wlcore]) from [<bf39201c>] (wl1271_configure_wowlan+0x148/0x3c4 [wlcore])
[  543.030292]  r7:db59ed38 r6:db59ee20 r5:00000000 r4:dc705bc8
[  543.030616] [<bf391ed4>] (wl1271_configure_wowlan [wlcore]) from [<bf3925a8>] (wl1271_op_resume+0x310/0x344 [wlcore])
[  543.030643]  r10:c0d5310c r9:db59e258 r8:00000000 r7:db59ed38 r6:db59ee20 r5:db59ed00
[  543.030652]  r4:dc705bc8
[  543.031484] [<bf392298>] (wl1271_op_resume [wlcore]) from [<bf343a0c>] (ieee80211_reconfig+0x418/0xc0c [mac80211])
[  543.031509]  r8:00000000 r7:db59e28c r6:bf2c75e8 r5:00000000 r4:db59e420
[  543.032290] [<bf3435f4>] (ieee80211_reconfig [mac80211]) from [<bf32fd9c>] (ieee80211_resume+0x58/0x70 [mac80211])
[  543.032318]  r10:c0d5310c r9:db59e258 r8:00000000 r7:db59e28c r6:bf2c75e8 r5:00000000
[  543.032327]  r4:db59e420
[  543.033150] [<bf32fd44>] (ieee80211_resume [mac80211]) from [<bf2c763c>] (wiphy_resume+0x54/0x64 [cfg80211])
[  543.033165]  r4:db59e258 r3:bf32fd44
[  543.033448] [<bf2c75e8>] (wiphy_resume [cfg80211]) from [<c053c79c>] (dpm_run_callback+0x40/0xcc)
[  543.033462]  r4:00000000 r3:00000000
[  543.033489] [<c053c75c>] (dpm_run_callback) from [<c053ce24>] (device_resume+0xbc/0x234)
[  543.033515]  r10:00000000 r9:dc005000 r8:00000000 r6:00000010 r5:00000001 r4:db59e258
[  543.033542] [<c053cd68>] (device_resume) from [<c053cfbc>] (async_resume+0x20/0x4c)
[  543.033567]  r8:00000000 r7:dc004100 r6:c0d4fde0 r5:c0d89b30 r4:db59e258 r3:00000000
[  543.033600] [<c053cf9c>] (async_resume) from [<c01483e4>] (async_run_entry_fn+0x44/0x140)
[  543.033614]  r5:d6be5480 r4:d6be5490
[  543.033646] [<c01483a0>] (async_run_entry_fn) from [<c013f128>] (process_one_work+0x12c/0x374)
[  543.033666]  r6:dc005000 r5:d6be5490 r4:db5ee780 r3:c01483a0
[  543.033690] [<c013effc>] (process_one_work) from [<c013f570>] (worker_thread+0x1c0/0x5b8)
[  543.033717]  r10:00000088 r9:dc005000 r8:c0d16380 r7:db5ee798 r6:dc005014 r5:dc005000
[  543.033727]  r4:db5ee780
[  543.033760] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11c/0x154)
[  543.033786]  r10:c013f3b0 r9:db5a1eb4 r8:db5ee780 r7:d6be53d8 r6:d6be5500 r5:00000000
[  543.033798]  r4:d6be53c0 r3:00000000
[  543.033833] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14/0x2c)
[  543.033859]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0145150
[  543.033872]  r4:d6be5500 r3:ffffffff
[  543.033885] ---[ end trace 980798e27041136d ]---

> - Add few patches for enable/disable issues found when using runtime PM
> 
> - Remove unused ps.h includes
> 
> Tony Lindgren (5):
>   wlcore: Add missing PM call for wlcore_cmd_wait_for_event_or_timeout()
>   wlcore: Make sure PM calls are paired
>   wlcore: Add support for runtime PM
>   wlcore: Fix misplaced PM call for scan_complete_work()
>   wlcore: sdio: Warn about runtime PM suspend errors
> 
>  drivers/net/wireless/ti/wl18xx/debugfs.c    |  26 +-
>  drivers/net/wireless/ti/wlcore/acx.c        |   1 -
>  drivers/net/wireless/ti/wlcore/cmd.c        |   9 +
>  drivers/net/wireless/ti/wlcore/debugfs.c    |  79 ++--
>  drivers/net/wireless/ti/wlcore/main.c       | 404 ++++++++++++++------
>  drivers/net/wireless/ti/wlcore/ps.c         | 146 -------
>  drivers/net/wireless/ti/wlcore/ps.h         |   3 -
>  drivers/net/wireless/ti/wlcore/scan.c       |  12 +-
>  drivers/net/wireless/ti/wlcore/sdio.c       |   7 +
>  drivers/net/wireless/ti/wlcore/sysfs.c      |  12 +-
>  drivers/net/wireless/ti/wlcore/testmode.c   |  18 +-
>  drivers/net/wireless/ti/wlcore/tx.c         |   9 +-
>  drivers/net/wireless/ti/wlcore/vendor_cmd.c |  27 +-
>  drivers/net/wireless/ti/wlcore/wlcore.h     |   1 -
>  drivers/net/wireless/ti/wlcore/wlcore_i.h   |   1 -
>  15 files changed, 421 insertions(+), 334 deletions(-)
> 
> --
> 2.17.0

Best Regards,
Eyal

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-21 16:38     ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-21 16:38 UTC (permalink / raw)
  To: Reizer, Eyal
  Cc: Kalle Valo, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn,
	Maital, Altshul, Maxim, Shahar Patury, linux-wireless,
	linux-omap, Loewy, Chen

* Reizer, Eyal <eyalr@ti.com> [180521 07:31]:
> > Here's a series of patches to add runtime PM support for wlcore. It does not
> > yet implement autosuspend support, but let's get this tested first as the
> > autosuspend can mask enable/disable issues easily.
> 
> Testing on BBB+WL1837 cape, scan, recovery, down/up and basic traffic seems ok now.
> Of course we need to test some more.

Thanks for testing. Yes let's do more testing, no rush with these.
Hopefully they'll be ready for v4.19 merge window though.

> Standard suspend/resume seems to work ok as well.
> Ennabling wowlan and suspending is  crashing on resume. See below.
> 
> root@am335x-evm:/usr/share/wl18xx# iw phy0 wowlan enable any dme
> root@am335x-evm:/usr/share/wl18xx#
> root@am335x-evm:/usr/share/wl18xx# echo mem > /sys/power/state
> [  541.567039] PM: suspend entry (deep)
> [  541.570688] PM: Syncing filesystems ... done.
> [  541.594277] Freezing user space processes ... (elapsed 0.001 seconds) done.
> [  541.603160] OOM killer disabled.
> [  541.606738] Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done.
> [  541.615984] Suspending console(s) (use no_console_suspend to debug)
> [  542.895091] pm33xx pm33xx: PM: Successfully put all powerdomains to target state
> [  542.895091] PM: Wakeup source UART
> [  542.919791] net eth0: initializing cpsw version 1.12 (0)
> [  543.017880] SMSC LAN8710/LAN8720 4a101000.mdio:00: attached PHY driver [SMSC LAN8710/LAN8720] (mii_bus:phy_addr=4a101000.mdio:00, irq=POLL)
> [  543.027646] ------------[ cut here ]------------
> [  543.028023] WARNING: CPU: 0 PID: 932 at drivers/net/wireless/ti/wlcore/cmd.c:76 wlcore_cmd_send_failsafe+0x498/0x4f8 [wlcore]

This warning is because wlcore is wlcore is still in ELP. This is
somehow possible even though we call pm_runtime_get_sync() in
wl1271_op_resume(). Anyways, I'll try to reproduce it here.

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-21 16:38     ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-21 16:38 UTC (permalink / raw)
  To: Reizer, Eyal
  Cc: Kalle Valo, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn,
	Maital, Altshul, Maxim, Shahar Patury,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Loewy, Chen

* Reizer, Eyal <eyalr-l0cyMroinI0@public.gmane.org> [180521 07:31]:
> > Here's a series of patches to add runtime PM support for wlcore. It does not
> > yet implement autosuspend support, but let's get this tested first as the
> > autosuspend can mask enable/disable issues easily.
> 
> Testing on BBB+WL1837 cape, scan, recovery, down/up and basic traffic seems ok now.
> Of course we need to test some more.

Thanks for testing. Yes let's do more testing, no rush with these.
Hopefully they'll be ready for v4.19 merge window though.

> Standard suspend/resume seems to work ok as well.
> Ennabling wowlan and suspending is  crashing on resume. See below.
> 
> root@am335x-evm:/usr/share/wl18xx# iw phy0 wowlan enable any dme
> root@am335x-evm:/usr/share/wl18xx#
> root@am335x-evm:/usr/share/wl18xx# echo mem > /sys/power/state
> [  541.567039] PM: suspend entry (deep)
> [  541.570688] PM: Syncing filesystems ... done.
> [  541.594277] Freezing user space processes ... (elapsed 0.001 seconds) done.
> [  541.603160] OOM killer disabled.
> [  541.606738] Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done.
> [  541.615984] Suspending console(s) (use no_console_suspend to debug)
> [  542.895091] pm33xx pm33xx: PM: Successfully put all powerdomains to target state
> [  542.895091] PM: Wakeup source UART
> [  542.919791] net eth0: initializing cpsw version 1.12 (0)
> [  543.017880] SMSC LAN8710/LAN8720 4a101000.mdio:00: attached PHY driver [SMSC LAN8710/LAN8720] (mii_bus:phy_addr=4a101000.mdio:00, irq=POLL)
> [  543.027646] ------------[ cut here ]------------
> [  543.028023] WARNING: CPU: 0 PID: 932 at drivers/net/wireless/ti/wlcore/cmd.c:76 wlcore_cmd_send_failsafe+0x498/0x4f8 [wlcore]

This warning is because wlcore is wlcore is still in ELP. This is
somehow possible even though we call pm_runtime_get_sync() in
wl1271_op_resume(). Anyways, I'll try to reproduce it here.

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 5/5] wlcore: sdio: Warn about runtime PM suspend errors
@ 2018-05-21 22:32     ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-21 22:32 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Eyal Reizer, Kishon Vijay Abraham I, Guy Mishol, Luca Coelho,
	Maital Hahn, Maxim Altshul, Shahar Patury, linux-wireless,
	linux-omap

* Tony Lindgren <tony@atomide.com> [180517 18:53]:
> We may get -EBUSY from runtime PM and that most likely means some
> earlier wlcore command did not complete yet and further calls may
> fail. Let's add a warning to make it easier to track down and fix
> such issues in wlcore code.

Related to the warnings produced with this patch, the following additional
patch seems to fix the timeout errors that happen at some point after
forcing recovery a few times.

Regards,

Tony

8< -------------------------
>From tony Mon Sep 17 00:00:00 2001
From: Tony Lindgren <tony@atomide.com>
Date: Wed, 16 May 2018 14:14:47 -0700
Subject: [PATCH] wclore: Fix timout errors after recovery

After enabling runtime PM, if we force hardware reset multiple times with:

# echo 1 > /sys/kernel/debug/ieee80211/phy0/wlcore/start_recovery

We will after few tries get the following error:

wlcore: ERROR timeout waiting for the hardware to complete initialization

And then wlcore is unable to reconnect until after the wlcore related modules
are reloaded.

Let's fix this by moving pm_runtime_put() earlier before we restart the hardware.
And let's use the sync version to make sure we're done before we restart.

Note that we still will get -EBUSY warning from wl12xx_sdio_set_power() but let's
fix that separately once we know exactly why we get the warning.

Reported-by: Eyal Reizer <eyalr@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/net/wireless/ti/wlcore/main.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

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
@@ -977,6 +977,7 @@ static void wl1271_recovery_work(struct work_struct *work)
 	}
 
 	wlcore_op_stop_locked(wl);
+	pm_runtime_put_sync(wl->dev);
 
 	ieee80211_restart_hw(wl->hw);
 
@@ -986,8 +987,6 @@ static void wl1271_recovery_work(struct work_struct *work)
 	 */
 	wlcore_wake_queues(wl, WLCORE_QUEUE_STOP_REASON_FW_RESTART);
 
-	pm_runtime_put(wl->dev);
-
 out_unlock:
 	wl->watchdog_recovery = false;
 	clear_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags);
-- 
2.17.0

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 5/5] wlcore: sdio: Warn about runtime PM suspend errors
@ 2018-05-21 22:32     ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-21 22:32 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Eyal Reizer, Kishon Vijay Abraham I, Guy Mishol, Luca Coelho,
	Maital Hahn, Maxim Altshul, Shahar Patury,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA

* Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> [180517 18:53]:
> We may get -EBUSY from runtime PM and that most likely means some
> earlier wlcore command did not complete yet and further calls may
> fail. Let's add a warning to make it easier to track down and fix
> such issues in wlcore code.

Related to the warnings produced with this patch, the following additional
patch seems to fix the timeout errors that happen at some point after
forcing recovery a few times.

Regards,

Tony

8< -------------------------
>From tony Mon Sep 17 00:00:00 2001
From: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
Date: Wed, 16 May 2018 14:14:47 -0700
Subject: [PATCH] wclore: Fix timout errors after recovery

After enabling runtime PM, if we force hardware reset multiple times with:

# echo 1 > /sys/kernel/debug/ieee80211/phy0/wlcore/start_recovery

We will after few tries get the following error:

wlcore: ERROR timeout waiting for the hardware to complete initialization

And then wlcore is unable to reconnect until after the wlcore related modules
are reloaded.

Let's fix this by moving pm_runtime_put() earlier before we restart the hardware.
And let's use the sync version to make sure we're done before we restart.

Note that we still will get -EBUSY warning from wl12xx_sdio_set_power() but let's
fix that separately once we know exactly why we get the warning.

Reported-by: Eyal Reizer <eyalr-l0cyMroinI0@public.gmane.org>
Signed-off-by: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
---
 drivers/net/wireless/ti/wlcore/main.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

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
@@ -977,6 +977,7 @@ static void wl1271_recovery_work(struct work_struct *work)
 	}
 
 	wlcore_op_stop_locked(wl);
+	pm_runtime_put_sync(wl->dev);
 
 	ieee80211_restart_hw(wl->hw);
 
@@ -986,8 +987,6 @@ static void wl1271_recovery_work(struct work_struct *work)
 	 */
 	wlcore_wake_queues(wl, WLCORE_QUEUE_STOP_REASON_FW_RESTART);
 
-	pm_runtime_put(wl->dev);

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-21 22:43       ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-21 22:43 UTC (permalink / raw)
  To: Reizer, Eyal
  Cc: Kalle Valo, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn,
	Maital, Altshul, Maxim, Shahar Patury, linux-wireless,
	linux-omap, Loewy, Chen

* Tony Lindgren <tony@atomide.com> [180521 16:40]:
> * Reizer, Eyal <eyalr@ti.com> [180521 07:31]:
> > > Here's a series of patches to add runtime PM support for wlcore. It does not
> > > yet implement autosuspend support, but let's get this tested first as the
> > > autosuspend can mask enable/disable issues easily.
> > 
> > Testing on BBB+WL1837 cape, scan, recovery, down/up and basic traffic seems ok now.
> > Of course we need to test some more.
> 
> Thanks for testing. Yes let's do more testing, no rush with these.
> Hopefully they'll be ready for v4.19 merge window though.
> 
> > Standard suspend/resume seems to work ok as well.
> > Ennabling wowlan and suspending is  crashing on resume. See below.
> > 
> > root@am335x-evm:/usr/share/wl18xx# iw phy0 wowlan enable any dme
> > root@am335x-evm:/usr/share/wl18xx#
> > root@am335x-evm:/usr/share/wl18xx# echo mem > /sys/power/state
> > [  541.567039] PM: suspend entry (deep)
> > [  541.570688] PM: Syncing filesystems ... done.
> > [  541.594277] Freezing user space processes ... (elapsed 0.001 seconds) done.
> > [  541.603160] OOM killer disabled.
> > [  541.606738] Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done.
> > [  541.615984] Suspending console(s) (use no_console_suspend to debug)
> > [  542.895091] pm33xx pm33xx: PM: Successfully put all powerdomains to target state
> > [  542.895091] PM: Wakeup source UART
> > [  542.919791] net eth0: initializing cpsw version 1.12 (0)
> > [  543.017880] SMSC LAN8710/LAN8720 4a101000.mdio:00: attached PHY driver [SMSC LAN8710/LAN8720] (mii_bus:phy_addr=4a101000.mdio:00, irq=POLL)
> > [  543.027646] ------------[ cut here ]------------
> > [  543.028023] WARNING: CPU: 0 PID: 932 at drivers/net/wireless/ti/wlcore/cmd.c:76 wlcore_cmd_send_failsafe+0x498/0x4f8 [wlcore]
> 
> This warning is because wlcore is wlcore is still in ELP. This is
> somehow possible even though we call pm_runtime_get_sync() in
> wl1271_op_resume(). Anyways, I'll try to reproduce it here.

Sorry I can't somehow get my beagleboard to wake-up from suspend,
I'm almost certain that worked the last time I tried.

Anyways, maybe the following patch fixes this if you care to
test again.

Regards,

Tony

8< ------------------------
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
@@ -1867,8 +1867,6 @@ static int __maybe_unused wl1271_op_resume(struct ieee80211_hw *hw)
 			if (ret)
 				wl12xx_queue_recovery_work(wl);
 		}
-
-		wlcore_enable_interrupts(wl);
 	}
 
 	if (pending_recovery) {
@@ -1877,6 +1875,8 @@ static int __maybe_unused wl1271_op_resume(struct ieee80211_hw *hw)
 		goto out_sleep;
 	}
 
+	wlcore_enable_interrupts(wl);
+
 	ret = pm_runtime_get_sync(wl->dev);
 	if (ret < 0) {
 		pm_runtime_put_noidle(wl->dev);

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-21 22:43       ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-21 22:43 UTC (permalink / raw)
  To: Reizer, Eyal
  Cc: Kalle Valo, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn,
	Maital, Altshul, Maxim, Shahar Patury,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Loewy, Chen

* Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> [180521 16:40]:
> * Reizer, Eyal <eyalr-l0cyMroinI0@public.gmane.org> [180521 07:31]:
> > > Here's a series of patches to add runtime PM support for wlcore. It does not
> > > yet implement autosuspend support, but let's get this tested first as the
> > > autosuspend can mask enable/disable issues easily.
> > 
> > Testing on BBB+WL1837 cape, scan, recovery, down/up and basic traffic seems ok now.
> > Of course we need to test some more.
> 
> Thanks for testing. Yes let's do more testing, no rush with these.
> Hopefully they'll be ready for v4.19 merge window though.
> 
> > Standard suspend/resume seems to work ok as well.
> > Ennabling wowlan and suspending is  crashing on resume. See below.
> > 
> > root@am335x-evm:/usr/share/wl18xx# iw phy0 wowlan enable any dme
> > root@am335x-evm:/usr/share/wl18xx#
> > root@am335x-evm:/usr/share/wl18xx# echo mem > /sys/power/state
> > [  541.567039] PM: suspend entry (deep)
> > [  541.570688] PM: Syncing filesystems ... done.
> > [  541.594277] Freezing user space processes ... (elapsed 0.001 seconds) done.
> > [  541.603160] OOM killer disabled.
> > [  541.606738] Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done.
> > [  541.615984] Suspending console(s) (use no_console_suspend to debug)
> > [  542.895091] pm33xx pm33xx: PM: Successfully put all powerdomains to target state
> > [  542.895091] PM: Wakeup source UART
> > [  542.919791] net eth0: initializing cpsw version 1.12 (0)
> > [  543.017880] SMSC LAN8710/LAN8720 4a101000.mdio:00: attached PHY driver [SMSC LAN8710/LAN8720] (mii_bus:phy_addr=4a101000.mdio:00, irq=POLL)
> > [  543.027646] ------------[ cut here ]------------
> > [  543.028023] WARNING: CPU: 0 PID: 932 at drivers/net/wireless/ti/wlcore/cmd.c:76 wlcore_cmd_send_failsafe+0x498/0x4f8 [wlcore]
> 
> This warning is because wlcore is wlcore is still in ELP. This is
> somehow possible even though we call pm_runtime_get_sync() in
> wl1271_op_resume(). Anyways, I'll try to reproduce it here.

Sorry I can't somehow get my beagleboard to wake-up from suspend,
I'm almost certain that worked the last time I tried.

Anyways, maybe the following patch fixes this if you care to
test again.

Regards,

Tony

8< ------------------------
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
@@ -1867,8 +1867,6 @@ static int __maybe_unused wl1271_op_resume(struct ieee80211_hw *hw)
 			if (ret)
 				wl12xx_queue_recovery_work(wl);
 		}

^ permalink raw reply	[flat|nested] 46+ messages in thread

* RE: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-22  6:40         ` Reizer, Eyal
  0 siblings, 0 replies; 46+ messages in thread
From: Reizer, Eyal @ 2018-05-22  6:40 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Kalle Valo, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn,
	Maital, Altshul, Maxim, Shahar Patury, linux-wireless,
	linux-omap, Loewy, Chen

> >
> > This warning is because wlcore is wlcore is still in ELP. This is
> > somehow possible even though we call pm_runtime_get_sync() in
> > wl1271_op_resume(). Anyways, I'll try to reproduce it here.
>=20
> Sorry I can't somehow get my beagleboard to wake-up from suspend,
> I'm almost certain that worked the last time I tried.
>=20
> Anyways, maybe the following patch fixes this if you care to
> test again.
>=20
> Regards,
>=20
> Tony
>=20
> 8< ------------------------
> 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
> @@ -1867,8 +1867,6 @@ static int __maybe_unused
> wl1271_op_resume(struct ieee80211_hw *hw)
>  			if (ret)
>  				wl12xx_queue_recovery_work(wl);
>  		}
> -
> -		wlcore_enable_interrupts(wl);
>  	}
>=20
>  	if (pending_recovery) {
> @@ -1877,6 +1875,8 @@ static int __maybe_unused
> wl1271_op_resume(struct ieee80211_hw *hw)
>  		goto out_sleep;
>  	}
>=20
> +	wlcore_enable_interrupts(wl);
> +
>  	ret =3D pm_runtime_get_sync(wl->dev);
>  	if (ret < 0) {
>  		pm_runtime_put_noidle(wl->dev);

It still crash.
The crash is different now.
It also complains about:
[   60.544224] Unbalanced enable for IRQ 65
Need down/up of the interface to recover after it.
Log below:

root@am335x-evm:~#
root@am335x-evm:~#
root@am335x-evm:~# echo mem > /sys/power/state
[   42.994534] PM: suspend entry (deep)
[   42.998182] PM: Syncing filesystems ... done.
[   43.946134] Freezing user space processes ... (elapsed 0.002 seconds) do=
ne.
[   43.957020] OOM killer disabled.
[   43.960449] Freezing remaining freezable tasks ... (elapsed 0.002 second=
s) done.
[   43.971227] Suspending console(s) (use no_console_suspend to debug)
[   44.093784] wlcore: down
[   44.181597] pm33xx pm33xx: PM: Successfully put all powerdomains to targ=
et state
[   44.181597] PM: Wakeup source UART
[   44.206334] net eth0: initializing cpsw version 1.12 (0)
[   44.304417] SMSC LAN8710/LAN8720 4a101000.mdio:00: attached PHY driver [=
SMSC LAN8710/LAN8720] (mii_bus:phy_addr=3D4a101000.mdio:00, irq=3DPOLL)
[   44.650784] wlcore: PHY firmware version: Rev 8.2.0.0.242
[   44.746182] wlcore: firmware booted (Rev 8.9.0.0.78)
[   44.929226] OOM killer enabled.
[   44.932602] Restarting tasks ... done.
[   44.961136] PM: suspend exit
root@am335x-evm:~# iw phy0 wowlan enable any
root@am335x-evm:~#
root@am335x-evm:~#
root@am335x-evm:~#
root@am335x-evm:~#
root@am335x-evm:~# echo mem > /sys/power/state
[   60.114495] PM: suspend entry (deep)
[   60.118146] PM: Syncing filesystems ... done.
[   60.139243] Freezing user space processes ... (elapsed 0.001 seconds) do=
ne.
[   60.148483] OOM killer disabled.
[   60.151723] Freezing remaining freezable tasks ... (elapsed 0.001 second=
s) done.
[   60.160874] Suspending console(s) (use no_console_suspend to debug)
[   60.411089] pm33xx pm33xx: PM: Successfully put all powerdomains to targ=
et state
[   60.411089] PM: Wakeup source UART
[   60.435069] net eth0: initializing cpsw version 1.12 (0)
[   60.534303] SMSC LAN8710/LAN8720 4a101000.mdio:00: attached PHY driver [=
SMSC LAN8710/LAN8720] (mii_bus:phy_addr=3D4a101000.mdio:00, irq=3DPOLL)
[   60.544143] ------------[ cut here ]------------
[   60.544213] WARNING: CPU: 0 PID: 730 at kernel/irq/manage.c:525 __enable=
_irq+0x4c/0x6c
[   60.544224] Unbalanced enable for IRQ 65
[   60.544232] Modules linked in: usb_f_acm u_serial arc4 pru_rproc pruss_i=
ntc wl18xx usb_f_ecm wlcore musb_dsps mac80211 musb_hdrc cfg80211 pruss phy=
_am335x usbcore phy_generic phy_am335x_control xfrm_user xfrm4_tunnel ipcom=
p xfrm_ipcomp esp4 ah4 af_key xfrm_algo g_multi usb_f_mass_storage usb_f_rn=
dis u_ether libcomposite udc_core usb_common bluetooth ecdh_generic snd_soc=
_simple_card snd_soc_simple_card_utils wkup_m3_rproc pm33xx wkup_m3_ipc rem=
oteproc omap_aes_driver crypto_engine omap_crypto omap_sham ti_emif_sram pr=
uss_soc_bus wlcore_sdio rtc_omap musb_am335x omap_wdt sch_fq_codel
[   60.544574] CPU: 0 PID: 730 Comm: kworker/u2:11 Not tainted 4.14.40-0141=
3-g36a61bea-dirty #105
[   60.544584] Hardware name: Generic AM33XX (Flattened Device Tree)
[   60.544624] Workqueue: events_unbound async_run_entry_fn
[   60.544639] Backtrace:
[   60.544698] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+=
0x18/0x1c)
[   60.544722]  r6:00000000 r5:c0a95d64 r4:db363d78 r3:c0d53158
[   60.544758] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20=
/0x28)
[   60.544794] [<c0805db0>] (dump_stack) from [<c01287bc>] (__warn+0xdc/0x1=
04)
[   60.544821] [<c01286e0>] (__warn) from [<c012889c>] (warn_slowpath_fmt+0=
x40/0x48)
[   60.544848]  r10:c0d5310c r8:00000000 r7:db5a6d38 r6:00000000 r5:0000004=
1 r4:00000000
[   60.544874] [<c0128860>] (warn_slowpath_fmt) from [<c0169760>] (__enable=
_irq+0x4c/0x6c)
[   60.544889]  r3:00000041 r2:c0a95ec4
[   60.544898]  r4:db278000
[   60.544922] [<c0169714>] (__enable_irq) from [<c01697bc>] (enable_irq+0x=
3c/0x74)
[   60.545265] [<c0169780>] (enable_irq) from [<bf39e068>] (wlcore_enable_i=
nterrupts+0x14/0x18 [wlcore])
[   60.545280]  r5:db5a6d00 r4:bf3b3c40
[   60.545619] [<bf39e054>] (wlcore_enable_interrupts [wlcore]) from [<bf39=
9428>] (wl1271_op_resume+0x144/0x334 [wlcore])
[   60.546524] [<bf3992e4>] (wl1271_op_resume [wlcore]) from [<bf3291f8>] (=
ieee80211_reconfig+0x418/0xc0c [mac80211])
[   60.546548]  r7:db5a628c r6:bf26d640 r5:00000000 r4:db5a6420
[   60.547408] [<bf328de0>] (ieee80211_reconfig [mac80211]) from [<bf314ab8=
>] (ieee80211_resume+0x58/0x70 [mac80211])
[   60.547436]  r10:c0d5310c r9:db5a6258 r8:00000000 r7:db5a628c r6:bf26d64=
0 r5:00000000
[   60.547446]  r4:db5a6420
[   60.548310] [<bf314a60>] (ieee80211_resume [mac80211]) from [<bf26d694>]=
 (wiphy_resume+0x54/0x64 [cfg80211])
[   60.548326]  r4:db5a6258 r3:bf314a60
[   60.548611] [<bf26d640>] (wiphy_resume [cfg80211]) from [<c053c79c>] (dp=
m_run_callback+0x40/0xcc)
[   60.548625]  r4:00000000 r3:00000000
[   60.548652] [<c053c75c>] (dpm_run_callback) from [<c053ce24>] (device_re=
sume+0xbc/0x234)
[   60.548679]  r10:00000000 r9:dc005000 r8:00000000 r6:00000010 r5:0000000=
1 r4:db5a6258
[   60.548706] [<c053cd68>] (device_resume) from [<c053cfbc>] (async_resume=
+0x20/0x4c)
[   60.548732]  r8:00000000 r7:dc004100 r6:c0d4fde0 r5:c0d89b30 r4:db5a6258=
 r3:00000000
[   60.548765] [<c053cf9c>] (async_resume) from [<c01483e4>] (async_run_ent=
ry_fn+0x44/0x140)
[   60.548779]  r5:db56f480 r4:db56f490
[   60.548810] [<c01483a0>] (async_run_entry_fn) from [<c013f128>] (process=
_one_work+0x12c/0x374)
[   60.548830]  r6:dc005000 r5:db56f490 r4:db44eb80 r3:c01483a0
[   60.548855] [<c013effc>] (process_one_work) from [<c013f570>] (worker_th=
read+0x1c0/0x5b8)
[   60.548882]  r10:00000088 r9:dc005000 r8:c0d16380 r7:db44eb98 r6:dc00501=
4 r5:dc005000
[   60.548891]  r4:db44eb80
[   60.548924] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11=
c/0x154)
[   60.548950]  r10:c013f3b0 r9:db3cfeb4 r8:db44eb80 r7:db56ff58 r6:db56f40=
0 r5:00000000
[   60.548963]  r4:db56ff40 r3:00000000
[   60.548996] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14=
/0x2c)
[   60.549022]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:0000000=
0 r5:c0145150
[   60.549034]  r4:db56f400 r3:ffffffff
[   60.549047] ---[ end trace 06c90d424e072151 ]---
[   60.549082] ------------[ cut here ]------------
[   60.549343] WARNING: CPU: 0 PID: 730 at drivers/net/wireless/ti/wlcore/c=
md.c:76 wlcore_cmd_send_failsafe+0x498/0x4f8 [wlcore]
[   60.549352] Modules linked in: usb_f_acm u_serial arc4 pru_rproc pruss_i=
ntc wl18xx usb_f_ecm wlcore musb_dsps mac80211 musb_hdrc cfg80211 pruss phy=
_am335x usbcore phy_generic phy_am335x_control xfrm_user xfrm4_tunnel ipcom=
p xfrm_ipcomp esp4 ah4 af_key xfrm_algo g_multi usb_f_mass_storage usb_f_rn=
dis u_ether libcomposite udc_core usb_common bluetooth ecdh_generic snd_soc=
_simple_card snd_soc_simple_card_utils wkup_m3_rproc pm33xx wkup_m3_ipc rem=
oteproc omap_aes_driver crypto_engine omap_crypto omap_sham ti_emif_sram pr=
uss_soc_bus wlcore_sdio rtc_omap musb_am335x omap_wdt sch_fq_codel
[   60.549675] CPU: 0 PID: 730 Comm: kworker/u2:11 Tainted: G        W     =
  4.14.40-01413-g36a61bea-dirty #105
[   60.549685] Hardware name: Generic AM33XX (Flattened Device Tree)
[   60.549714] Workqueue: events_unbound async_run_entry_fn
[   60.549728] Backtrace:
[   60.549773] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+=
0x18/0x1c)
[   60.549794]  r6:00000000 r5:bf3ae59c r4:00000000 r3:c0d53158
[   60.549828] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20=
/0x28)
[   60.549861] [<c0805db0>] (dump_stack) from [<c01287bc>] (__warn+0xdc/0x1=
04)
[   60.549888] [<c01286e0>] (__warn) from [<c012880c>] (warn_slowpath_null+=
0x28/0x30)
[   60.549915]  r10:c0d5310c r8:00000000 r7:db5a6d38 r6:db1b1980 r5:0000000=
c r4:db5a6d00
[   60.550110] [<c01287e4>] (warn_slowpath_null) from [<bf39a8b0>] (wlcore_=
cmd_send_failsafe+0x498/0x4f8 [wlcore])
[   60.550443] [<bf39a418>] (wlcore_cmd_send_failsafe [wlcore]) from [<bf39=
bea8>] (wlcore_cmd_configure_failsafe+0x60/0xd8 [wlcore])
[   60.550470]  r10:c0d5310c r9:db5a6258 r8:00000000 r7:db5a6d38 r6:0000005=
7 r5:db5a6d00
[   60.550480]  r4:db1b1980
[   60.550808] [<bf39be48>] (wlcore_cmd_configure_failsafe [wlcore]) from [=
<bf39bf3c>] (wl1271_cmd_configure+0x1c/0x28 [wlcore])
[   60.550825]  r6:00000001 r5:db5a6d00 r4:db1b1980
[   60.551133] [<bf39bf20>] (wl1271_cmd_configure [wlcore]) from [<bf3d47e8=
>] (wl18xx_acx_interrupt_notify_config+0x48/0x80 [wl18xx])
[   60.551374] [<bf3d47a0>] (wl18xx_acx_interrupt_notify_config [wl18xx]) f=
rom [<bf3994f4>] (wl1271_op_resume+0x210/0x334 [wlcore])
[   60.551395]  r6:db5a6e20 r5:db5a6d00 r4:db5a6e1c r3:bf3e3000
[   60.552096] [<bf3992e4>] (wl1271_op_resume [wlcore]) from [<bf3291f8>] (=
ieee80211_reconfig+0x418/0xc0c [mac80211])
[   60.552118]  r7:db5a628c r6:bf26d640 r5:00000000 r4:db5a6420
[   60.552941] [<bf328de0>] (ieee80211_reconfig [mac80211]) from [<bf314ab8=
>] (ieee80211_resume+0x58/0x70 [mac80211])
[   60.552968]  r10:c0d5310c r9:db5a6258 r8:00000000 r7:db5a628c r6:bf26d64=
0 r5:00000000
[   60.553361]  r4:db5a6420
[   60.554209] [<bf314a60>] (ieee80211_resume [mac80211]) from [<bf26d694>]=
 (wiphy_resume+0x54/0x64 [cfg80211])
[   60.554226]  r4:db5a6258 r3:bf314a60
[   60.554500] [<bf26d640>] (wiphy_resume [cfg80211]) from [<c053c79c>] (dp=
m_run_callback+0x40/0xcc)
[   60.554515]  r4:00000000 r3:00000000
[   60.554543] [<c053c75c>] (dpm_run_callback) from [<c053ce24>] (device_re=
sume+0xbc/0x234)
[   60.554569]  r10:00000000 r9:dc005000 r8:00000000 r6:00000010 r5:0000000=
1 r4:db5a6258
[   60.554596] [<c053cd68>] (device_resume) from [<c053cfbc>] (async_resume=
+0x20/0x4c)
[   60.554623]  r8:00000000 r7:dc004100 r6:c0d4fde0 r5:c0d89b30 r4:db5a6258=
 r3:00000000
[   60.554655] [<c053cf9c>] (async_resume) from [<c01483e4>] (async_run_ent=
ry_fn+0x44/0x140)
[   60.554669]  r5:db56f480 r4:db56f490
[   60.554699] [<c01483a0>] (async_run_entry_fn) from [<c013f128>] (process=
_one_work+0x12c/0x374)
[   60.554719]  r6:dc005000 r5:db56f490 r4:db44eb80 r3:c01483a0
[   60.554744] [<c013effc>] (process_one_work) from [<c013f570>] (worker_th=
read+0x1c0/0x5b8)
[   60.554770]  r10:00000088 r9:dc005000 r8:c0d16380 r7:db44eb98 r6:dc00501=
4 r5:dc005000
[   60.554780]  r4:db44eb80
[   60.554811] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11=
c/0x154)
[   60.554837]  r10:c013f3b0 r9:db3cfeb4 r8:db44eb80 r7:db56ff58 r6:db56f40=
0 r5:00000000
[   60.554850]  r4:db56ff40 r3:00000000
[   60.554883] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14=
/0x2c)
[   60.554909]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:0000000=
0 r5:c0145150
[   60.554923]  r4:db56f400 r3:ffffffff
[   60.554937] ---[ end trace 06c90d424e072152 ]---
[   60.554950] ------------[ cut here ]------------
[   60.555200] WARNING: CPU: 0 PID: 730 at drivers/net/wireless/ti/wlcore/i=
o.h:66 wlcore_cmd_send_failsafe+0xb8/0x4f8 [wlcore]
[   60.555208] Modules linked in: usb_f_acm u_serial arc4 pru_rproc pruss_i=
ntc wl18xx usb_f_ecm wlcore musb_dsps mac80211 musb_hdrc cfg80211 pruss phy=
_am335x usbcore phy_generic phy_am335x_control xfrm_user xfrm4_tunnel ipcom=
p xfrm_ipcomp esp4 ah4 af_key xfrm_algo g_multi usb_f_mass_storage usb_f_rn=
dis u_ether libcomposite udc_core usb_common bluetooth ecdh_generic snd_soc=
_simple_card snd_soc_simple_card_utils wkup_m3_rproc pm33xx wkup_m3_ipc rem=
oteproc omap_aes_driver crypto_engine omap_crypto omap_sham ti_emif_sram pr=
uss_soc_bus wlcore_sdio rtc_omap musb_am335x omap_wdt sch_fq_codel
[   60.555529] CPU: 0 PID: 730 Comm: kworker/u2:11 Tainted: G        W     =
  4.14.40-01413-g36a61bea-dirty #105
[   60.555539] Hardware name: Generic AM33XX (Flattened Device Tree)
[   60.555568] Workqueue: events_unbound async_run_entry_fn
[   60.555582] Backtrace:
[   60.555627] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+=
0x18/0x1c)
[   60.555647]  r6:00000000 r5:bf3ae61c r4:00000000 r3:c0d53158
[   60.555679] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20=
/0x28)
[   60.555710] [<c0805db0>] (dump_stack) from [<c01287bc>] (__warn+0xdc/0x1=
04)
[   60.555739] [<c01286e0>] (__warn) from [<c012880c>] (warn_slowpath_null+=
0x28/0x30)
[   60.555766]  r10:c0d5310c r8:00000000 r7:db5a6d38 r6:db1b1980 r5:0000000=
c r4:db5a6d00
[   60.555961] [<c01287e4>] (warn_slowpath_null) from [<bf39a4d0>] (wlcore_=
cmd_send_failsafe+0xb8/0x4f8 [wlcore])
[   60.556294] [<bf39a418>] (wlcore_cmd_send_failsafe [wlcore]) from [<bf39=
bea8>] (wlcore_cmd_configure_failsafe+0x60/0xd8 [wlcore])
[   60.556321]  r10:c0d5310c r9:db5a6258 r8:00000000 r7:db5a6d38 r6:0000005=
7 r5:db5a6d00
[   60.556331]  r4:db1b1980
[   60.556659] [<bf39be48>] (wlcore_cmd_configure_failsafe [wlcore]) from [=
<bf39bf3c>] (wl1271_cmd_configure+0x1c/0x28 [wlcore])
[   60.556676]  r6:00000001 r5:db5a6d00 r4:db1b1980
[   60.556952] [<bf39bf20>] (wl1271_cmd_configure [wlcore]) from [<bf3d47e8=
>] (wl18xx_acx_interrupt_notify_config+0x48/0x80 [wl18xx])
[   60.557193] [<bf3d47a0>] (wl18xx_acx_interrupt_notify_config [wl18xx]) f=
rom [<bf3994f4>] (wl1271_op_resume+0x210/0x334 [wlcore])
[   60.557214]  r6:db5a6e20 r5:db5a6d00 r4:db5a6e1c r3:bf3e3000
[   60.557892] [<bf3992e4>] (wl1271_op_resume [wlcore]) from [<bf3291f8>] (=
ieee80211_reconfig+0x418/0xc0c [mac80211])
[   60.557913]  r7:db5a628c r6:bf26d640 r5:00000000 r4:db5a6420
[   60.558735] [<bf328de0>] (ieee80211_reconfig [mac80211]) from [<bf314ab8=
>] (ieee80211_resume+0x58/0x70 [mac80211])
[   60.558762]  r10:c0d5310c r9:db5a6258 r8:00000000 r7:db5a628c r6:bf26d64=
0 r5:00000000
[   60.558771]  r4:db5a6420
[   60.559488] [<bf314a60>] (ieee80211_resume [mac80211]) from [<bf26d694>]=
 (wiphy_resume+0x54/0x64 [cfg80211])
[   60.559502]  r4:db5a6258 r3:bf314a60
[   60.559770] [<bf26d640>] (wiphy_resume [cfg80211]) from [<c053c79c>] (dp=
m_run_callback+0x40/0xcc)
[   60.559784]  r4:00000000 r3:00000000
[   60.559811] [<c053c75c>] (dpm_run_callback) from [<c053ce24>] (device_re=
sume+0xbc/0x234)
[   60.559838]  r10:00000000 r9:dc005000 r8:00000000 r6:00000010 r5:0000000=
1 r4:db5a6258
[   60.559864] [<c053cd68>] (device_resume) from [<c053cfbc>] (async_resume=
+0x20/0x4c)
[   60.559890]  r8:00000000 r7:dc004100 r6:c0d4fde0 r5:c0d89b30 r4:db5a6258=
 r3:00000000
[   60.559919] [<c053cf9c>] (async_resume) from [<c01483e4>] (async_run_ent=
ry_fn+0x44/0x140)
[   60.559933]  r5:db56f480 r4:db56f490
[   60.559962] [<c01483a0>] (async_run_entry_fn) from [<c013f128>] (process=
_one_work+0x12c/0x374)
[   60.559982]  r6:dc005000 r5:db56f490 r4:db44eb80 r3:c01483a0
[   60.560006] [<c013effc>] (process_one_work) from [<c013f570>] (worker_th=
read+0x1c0/0x5b8)
[   60.560032]  r10:00000088 r9:dc005000 r8:c0d16380 r7:db44eb98 r6:dc00501=
4 r5:dc005000
[   60.560041]  r4:db44eb80
[   60.560071] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11=
c/0x154)
[   60.560097]  r10:c013f3b0 r9:db3cfeb4 r8:db44eb80 r7:db56ff58 r6:db56f40=
0 r5:00000000
[   60.560110]  r4:db56ff40 r3:00000000
[   60.560140] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14=
/0x2c)
[   60.560166]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:0000000=
0 r5:c0145150
[   60.560179]  r4:db56f400 r3:ffffffff
[   60.560190] ---[ end trace 06c90d424e072153 ]---
[   60.560200] ------------[ cut here ]------------
[   60.560417] WARNING: CPU: 0 PID: 730 at drivers/net/wireless/ti/wlcore/m=
ain.c:806 wl12xx_queue_recovery_work+0x64/0x6c [wlcore]
[   60.560424] Modules linked in: usb_f_acm u_serial arc4 pru_rproc pruss_i=
ntc wl18xx usb_f_ecm wlcore musb_dsps mac80211 musb_hdrc cfg80211 pruss phy=
_am335x usbcore phy_generic phy_am335x_control xfrm_user xfrm4_tunnel ipcom=
p xfrm_ipcomp esp4 ah4 af_key xfrm_algo g_multi usb_f_mass_storage usb_f_rn=
dis u_ether libcomposite udc_core usb_common bluetooth ecdh_generic snd_soc=
_simple_card snd_soc_simple_card_utils wkup_m3_rproc pm33xx wkup_m3_ipc rem=
oteproc omap_aes_driver crypto_engine omap_crypto omap_sham ti_emif_sram pr=
uss_soc_bus wlcore_sdio rtc_omap musb_am335x omap_wdt sch_fq_codel
[   60.560736] CPU: 0 PID: 730 Comm: kworker/u2:11 Tainted: G        W     =
  4.14.40-01413-g36a61bea-dirty #105
[   60.560746] Hardware name: Generic AM33XX (Flattened Device Tree)
[   60.560772] Workqueue: events_unbound async_run_entry_fn
[   60.560785] Backtrace:
[   60.560825] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+=
0x18/0x1c)
[   60.560847]  r6:00000000 r5:bf3ac5f4 r4:00000000 r3:c0d53158
[   60.560877] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20=
/0x28)
[   60.560908] [<c0805db0>] (dump_stack) from [<c01287bc>] (__warn+0xdc/0x1=
04)
[   60.560934] [<c01286e0>] (__warn) from [<c012880c>] (warn_slowpath_null+=
0x28/0x30)
[   60.560961]  r10:c0d5310c r8:00000000 r7:db5a6d38 r6:db1b1980 r5:0000000=
c r4:db5a6d00
[   60.561154] [<c01287e4>] (warn_slowpath_null) from [<bf3974d0>] (wl12xx_=
queue_recovery_work+0x64/0x6c [wlcore])
[   60.561485] [<bf39746c>] (wl12xx_queue_recovery_work [wlcore]) from [<bf=
39a498>] (wlcore_cmd_send_failsafe+0x80/0x4f8 [wlcore])
[   60.561500]  r4:db5a6d00 r3:c0d53158
[   60.561826] [<bf39a418>] (wlcore_cmd_send_failsafe [wlcore]) from [<bf39=
bea8>] (wlcore_cmd_configure_failsafe+0x60/0xd8 [wlcore])
[   60.561852]  r10:c0d5310c r9:db5a6258 r8:00000000 r7:db5a6d38 r6:0000005=
7 r5:db5a6d00
[   60.561862]  r4:db1b1980
[   60.562188] [<bf39be48>] (wlcore_cmd_configure_failsafe [wlcore]) from [=
<bf39bf3c>] (wl1271_cmd_configure+0x1c/0x28 [wlcore])
[   60.562205]  r6:00000001 r5:db5a6d00 r4:db1b1980
[   60.562466] [<bf39bf20>] (wl1271_cmd_configure [wlcore]) from [<bf3d47e8=
>] (wl18xx_acx_interrupt_notify_config+0x48/0x80 [wl18xx])
[   60.562708] [<bf3d47a0>] (wl18xx_acx_interrupt_notify_config [wl18xx]) f=
rom [<bf3994f4>] (wl1271_op_resume+0x210/0x334 [wlcore])
[   60.562729]  r6:db5a6e20 r5:db5a6d00 r4:db5a6e1c r3:bf3e3000
[   60.563368] [<bf3992e4>] (wl1271_op_resume [wlcore]) from [<bf3291f8>] (=
ieee80211_reconfig+0x418/0xc0c [mac80211])
[   60.563526]  r7:db5a628c r6:bf26d640 r5:00000000 r4:db5a6420
[   60.564377] [<bf328de0>] (ieee80211_reconfig [mac80211]) from [<bf314ab8=
>] (ieee80211_resume+0x58/0x70 [mac80211])
[   60.564405]  r10:c0d5310c r9:db5a6258 r8:00000000 r7:db5a628c r6:bf26d64=
0 r5:00000000
[   60.564415]  r4:db5a6420
[   60.565129] [<bf314a60>] (ieee80211_resume [mac80211]) from [<bf26d694>]=
 (wiphy_resume+0x54/0x64 [cfg80211])
[   60.565144]  r4:db5a6258 r3:bf314a60
[   60.565413] [<bf26d640>] (wiphy_resume [cfg80211]) from [<c053c79c>] (dp=
m_run_callback+0x40/0xcc)
[   60.565429]  r4:00000000 r3:00000000
[   60.565456] [<c053c75c>] (dpm_run_callback) from [<c053ce24>] (device_re=
sume+0xbc/0x234)
[   60.565482]  r10:00000000 r9:dc005000 r8:00000000 r6:00000010 r5:0000000=
1 r4:db5a6258
[   60.565509] [<c053cd68>] (device_resume) from [<c053cfbc>] (async_resume=
+0x20/0x4c)
[   60.565535]  r8:00000000 r7:dc004100 r6:c0d4fde0 r5:c0d89b30 r4:db5a6258=
 r3:00000000
[   60.565565] [<c053cf9c>] (async_resume) from [<c01483e4>] (async_run_ent=
ry_fn+0x44/0x140)
[   60.565579]  r5:db56f480 r4:db56f490
[   60.565609] [<c01483a0>] (async_run_entry_fn) from [<c013f128>] (process=
_one_work+0x12c/0x374)
[   60.565629]  r6:dc005000 r5:db56f490 r4:db44eb80 r3:c01483a0
[   60.565653] [<c013effc>] (process_one_work) from [<c013f570>] (worker_th=
read+0x1c0/0x5b8)
[   60.565679]  r10:00000088 r9:dc005000 r8:c0d16380 r7:db44eb98 r6:dc00501=
4 r5:dc005000
[   60.565689]  r4:db44eb80
[   60.565718] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11=
c/0x154)
[   60.565744]  r10:c013f3b0 r9:db3cfeb4 r8:db44eb80 r7:db56ff58 r6:db56f40=
0 r5:00000000
[   60.565756]  r4:db56ff40 r3:00000000
[   60.565788] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14=
/0x2c)
[   60.565814]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:0000000=
0 r5:c0145150
[   60.565827]  r4:db56f400 r3:ffffffff
[   60.565839] ---[ end trace 06c90d424e072154 ]---
[   60.565949] wlcore: WARNING CONFIGURE command NOK
[   60.565965] wlcore: WARNING acx interrupt notify setting failed: -5
[   60.566025] wlcore: Hardware recovery in progress. FW ver: Rev 8.9.0.0.7=
8
[   60.566037] ------------[ cut here ]------------
[   60.566280] WARNING: CPU: 0 PID: 713 at drivers/net/wireless/ti/wlcore/i=
o.h:66 wlcore_set_partition+0xa0/0x50c [wlcore]
[   60.566288] Modules linked in: usb_f_acm u_serial arc4 pru_rproc pruss_i=
ntc wl18xx usb_f_ecm wlcore musb_dsps mac80211 musb_hdrc cfg80211 pruss phy=
_am335x usbcore phy_generic phy_am335x_control xfrm_user xfrm4_tunnel ipcom=
p xfrm_ipcomp esp4 ah4 af_key xfrm_algo g_multi usb_f_mass_storage usb_f_rn=
dis u_ether libcomposite udc_core usb_common bluetooth ecdh_generic snd_soc=
_simple_card snd_soc_simple_card_utils wkup_m3_rproc pm33xx wkup_m3_ipc rem=
oteproc omap_aes_driver crypto_engine omap_crypto omap_sham ti_emif_sram pr=
uss_soc_bus wlcore_sdio rtc_omap musb_am335x omap_wdt sch_fq_codel
[   60.566605] CPU: 0 PID: 713 Comm: kworker/u2:5 Tainted: G        W      =
 4.14.40-01413-g36a61bea-dirty #105
[   60.566614] Hardware name: Generic AM33XX (Flattened Device Tree)
[   60.566800] Workqueue: phy0 wl1271_recovery_work [wlcore]
[   60.566813] Backtrace:
[   60.566860] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+=
0x18/0x1c)
[   60.566882]  r6:00000000 r5:bf3af4c4 r4:00000000 r3:c0d53158
[   60.566914] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20=
/0x28)
[   60.566944] [<c0805db0>] (dump_stack) from [<c01287bc>] (__warn+0xdc/0x1=
04)
[   60.566971] [<c01286e0>] (__warn) from [<c012880c>] (warn_slowpath_null+=
0x28/0x30)
[   60.566999]  r10:00000000 r8:db5a6d38 r7:00000000 r6:bf3b3c40 r5:bf3dc06=
4 r4:db5a6d00
[   60.567188] [<c01287e4>] (warn_slowpath_null) from [<bf39dae0>] (wlcore_=
set_partition+0xa0/0x50c [wlcore])
[   60.567520] [<bf39da40>] (wlcore_set_partition [wlcore]) from [<bf396884=
>] (wl1271_recovery_work+0x174/0x40c [wlcore])
[   60.567541]  r7:dc639a00 r6:db5a6d00 r5:00000000 r4:db5a6f94
[   60.567719] [<bf396710>] (wl1271_recovery_work [wlcore]) from [<c013f128=
>] (process_one_work+0x12c/0x374)
[   60.567743]  r8:00000005 r7:dc639a00 r6:dc005000 r5:db5a6f94 r4:db264880
[   60.567768] [<c013effc>] (process_one_work) from [<c013f570>] (worker_th=
read+0x1c0/0x5b8)
[   60.567794]  r10:00000088 r9:dc005000 r8:c0d16380 r7:db264898 r6:dc00501=
4 r5:dc005000
[   60.567804]  r4:db264880
[   60.567831] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11=
c/0x154)
[   60.567857]  r10:c013f3b0 r9:d6b73eb4 r8:db264880 r7:db1eb4d8 r6:db1eb48=
0 r5:00000000
[   60.567870]  r4:db1eb4c0 r3:00000000
[   60.567899] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14=
/0x2c)
[   60.567925]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:0000000=
0 r5:c0145150
[   60.567938]  r4:db1eb480 r3:ffffffff
[   60.567948] ---[ end trace 06c90d424e072155 ]---
[   60.567984] wlcore: down
[   60.568843] ieee80211 phy0: Hardware restart was requested
[   62.536363] OOM killer enabled.
[   62.539523] Restarting tasks ... done.
root@am335x-evm:~# [   62.613165] PM: suspend exit
[   64.259379] ------------[ cut here ]------------
[   64.264263] WARNING: CPU: 0 PID: 3 at drivers/net/wireless/ti/wlcore/sdi=
o.c:145 wl12xx_sdio_raw_write+0xb4/0x138 [wlcore_sdio]
[   64.281202] Modules linked in: usb_f_acm u_serial arc4 pru_rproc pruss_i=
ntc wl18xx usb_f_ecm wlcore musb_dsps mac80211 musb_hdrc cfg80211 pruss phy=
_am335x usbcore phy_generic phy_am335x_control xfrm_user xfrm4_tunnel ipcom=
p xfrm_ipcomp esp4 ah4 af_key xfrm_algo g_multi usb_f_mass_storage usb_f_rn=
dis u_ether libcomposite udc_core usb_common bluetooth ecdh_generic snd_soc=
_simple_card snd_soc_simple_card_utils wkup_m3_rproc pm33xx wkup_m3_ipc rem=
oteproc omap_aes_driver crypto_engine omap_crypto omap_sham ti_emif_sram pr=
uss_soc_bus wlcore_sdio rtc_omap musb_am335x omap_wdt sch_fq_codel
[   64.348727] CPU: 0 PID: 3 Comm: kworker/0:0 Tainted: G        W       4.=
14.40-01413-g36a61bea-dirty #105
[   64.362411] Hardware name: Generic AM33XX (Flattened Device Tree)
[   64.373346] Workqueue: events_freezable ieee80211_restart_work [mac80211=
]
[   64.380520] Backtrace:
[   64.388153] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+=
0x18/0x1c)
[   64.401930]  r6:00000000 r5:bf024b00 r4:00000000 r3:00000000
[   64.411432] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20=
/0x28)
[   64.422527] [<c0805db0>] (dump_stack) from [<c01287bc>] (__warn+0xdc/0x1=
04)
[   64.433906] [<c01286e0>] (__warn) from [<c012880c>] (warn_slowpath_null+=
0x28/0x30)
[   64.441563]  r10:00000000 r8:00000004 r7:db7fc200 r6:db245810 r5:0001ffc=
4 r4:dc58ca00
[   64.454433] [<c01287e4>] (warn_slowpath_null) from [<bf023324>] (wl12xx_=
sdio_raw_write+0xb4/0x138 [wlcore_sdio])
[   64.471018] [<bf023270>] (wl12xx_sdio_raw_write [wlcore_sdio]) from [<bf=
39db0c>] (wlcore_set_partition+0xcc/0x50c [wlcore])
[   64.486457]  r10:00000000 r8:dc727bc8 r7:00000000 r6:bf3b3c40 r5:bf3dc06=
4 r4:db5a6d00
[   64.498730] [<bf39da40>] (wlcore_set_partition [wlcore]) from [<bf39015c=
>] (wl12xx_set_power_on+0x90/0x164 [wlcore])
[   64.513428]  r7:bf3b3c40 r6:db5a6d38 r5:00000000 r4:db5a6d00
[   64.519578] [<bf3900cc>] (wl12xx_set_power_on [wlcore]) from [<bf397160>=
] (wl1271_op_add_interface+0x644/0x950 [wlcore])
[   64.536110]  r5:db5a6d00 r4:dc727aa0
[   64.540729] [<bf396b1c>] (wl1271_op_add_interface [wlcore]) from [<bf2f9=
fe0>] (drv_add_interface+0x34/0x80 [mac80211])
[   64.561506]  r10:db5a6a00 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a642=
0 r5:dc7274e0
[   64.573554]  r4:dc7274e0
[   64.577270] [<bf2f9fac>] (drv_add_interface [mac80211]) from [<bf328f44>=
] (ieee80211_reconfig+0x164/0xc0c [mac80211])
[   64.595516]  r4:db5a6420 r3:00000001
[   64.600231] [<bf328de0>] (ieee80211_reconfig [mac80211]) from [<bf2f8354=
>] (ieee80211_restart_work+0x90/0xbc [mac80211])
[   64.616691]  r10:00000000 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a642=
0 r5:db5a6a00
[   64.630527]  r4:db5a6a00
[   64.637503] [<bf2f82c4>] (ieee80211_restart_work [mac80211]) from [<c013=
f128>] (process_one_work+0x12c/0x374)
[   64.651859]  r7:dcb39400 r6:c0d0ea60 r5:db5a6c28 r4:dc031180
[   64.661572] [<c013effc>] (process_one_work) from [<c013f570>] (worker_th=
read+0x1c0/0x5b8)
[   64.673966]  r10:00000008 r9:c0d0ea60 r8:c0d16380 r7:dc031198 r6:c0d0ea7=
4 r5:c0d0ea60
[   64.681867]  r4:dc031180
[   64.689198] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11=
c/0x154)
[   64.702654]  r10:c013f3b0 r9:dc04fe9c r8:dc031180 r7:dc030658 r6:dc03060=
0 r5:00000000
[   64.714610]  r4:dc030640 r3:00000000
[   64.718295] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14=
/0x2c)
[   64.730394]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:0000000=
0 r5:c0145150
[   64.744797]  r4:dc030600 r3:ffffffff
[   64.748427] ---[ end trace 06c90d424e072156 ]---
[   64.757792] wl1271_sdio mmc1:0001:2: sdio write failed (-110)
[   64.772377] mmc mmc1:0001: wl12xx_sdio_power_off: wlcore write did not y=
et complete?
[   64.786318] CPU: 0 PID: 3 Comm: kworker/0:0 Tainted: G        W       4.=
14.40-01413-g36a61bea-dirty #105
[   64.799746] Hardware name: Generic AM33XX (Flattened Device Tree)
[   64.810624] Workqueue: events_freezable ieee80211_restart_work [mac80211=
]
[   64.821602] Backtrace:
[   64.828002] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+=
0x18/0x1c)
[   64.839410]  r6:db5a6d38 r5:dc5ad008 r4:00000000 r3:00000000
[   64.848960] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20=
/0x28)
[   64.860074] [<c0805db0>] (dump_stack) from [<bf023258>] (wl12xx_sdio_set=
_power+0x140/0x158 [wlcore_sdio])
[   64.874019] [<bf023118>] (wl12xx_sdio_set_power [wlcore_sdio]) from [<bf=
390204>] (wl12xx_set_power_on+0x138/0x164 [wlcore])
[   64.889128]  r7:bf3b3c40 r6:db5a6d38 r5:ffffff92 r4:db5a6d00
[   64.899225] [<bf3900cc>] (wl12xx_set_power_on [wlcore]) from [<bf397160>=
] (wl1271_op_add_interface+0x644/0x950 [wlcore])
[   64.914290]  r5:db5a6d00 r4:dc727aa0
[   64.918887] [<bf396b1c>] (wl1271_op_add_interface [wlcore]) from [<bf2f9=
fe0>] (drv_add_interface+0x34/0x80 [mac80211])
[   64.935169]  r10:db5a6a00 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a642=
0 r5:dc7274e0
[   64.949035]  r4:dc7274e0
[   64.952742] [<bf2f9fac>] (drv_add_interface [mac80211]) from [<bf328f44>=
] (ieee80211_reconfig+0x164/0xc0c [mac80211])
[   64.968580]  r4:db5a6420 r3:00000001
[   64.973279] [<bf328de0>] (ieee80211_reconfig [mac80211]) from [<bf2f8354=
>] (ieee80211_restart_work+0x90/0xbc [mac80211])
[   64.994171]  r10:00000000 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a642=
0 r5:db5a6a00
[   65.002067]  r4:db5a6a00
[   65.010091] [<bf2f82c4>] (ieee80211_restart_work [mac80211]) from [<c013=
f128>] (process_one_work+0x12c/0x374)
[   65.026590]  r7:dcb39400 r6:c0d0ea60 r5:db5a6c28 r4:dc031180
[   65.032348] [<c013effc>] (process_one_work) from [<c013f570>] (worker_th=
read+0x1c0/0x5b8)
[   65.045963]  r10:00000008 r9:c0d0ea60 r8:c0d16380 r7:dc031198 r6:c0d0ea7=
4 r5:c0d0ea60
[   65.059710]  r4:dc031180
[   65.062336] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11=
c/0x154)
[   65.074803]  r10:c013f3b0 r9:dc04fe9c r8:dc031180 r7:dc030658 r6:dc03060=
0 r5:00000000
[   65.082708]  r4:dc030640 r3:00000000
[   65.095591] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14=
/0x2c)
[   65.102898]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:0000000=
0 r5:c0145150
[   65.115719]  r4:dc030600 r3:ffffffff
[   66.839684] ------------[ cut here ]------------
[   66.844563] WARNING: CPU: 0 PID: 3 at drivers/net/wireless/ti/wlcore/sdi=
o.c:145 wl12xx_sdio_raw_write+0xb4/0x138 [wlcore_sdio]
[   66.861361] Modules linked in: usb_f_acm u_serial arc4 pru_rproc pruss_i=
ntc wl18xx usb_f_ecm wlcore musb_dsps mac80211 musb_hdrc cfg80211 pruss phy=
_am335x usbcore phy_generic phy_am335x_control xfrm_user xfrm4_tunnel ipcom=
p xfrm_ipcomp esp4 ah4 af_key xfrm_algo g_multi usb_f_mass_storage usb_f_rn=
dis u_ether libcomposite udc_core usb_common bluetooth ecdh_generic snd_soc=
_simple_card snd_soc_simple_card_utils wkup_m3_rproc pm33xx wkup_m3_ipc rem=
oteproc omap_aes_driver crypto_engine omap_crypto omap_sham ti_emif_sram pr=
uss_soc_bus wlcore_sdio rtc_omap musb_am335x omap_wdt sch_fq_codel
[   66.928850] CPU: 0 PID: 3 Comm: kworker/0:0 Tainted: G        W       4.=
14.40-01413-g36a61bea-dirty #105
[   66.942559] Hardware name: Generic AM33XX (Flattened Device Tree)
[   66.953446] Workqueue: events_freezable ieee80211_restart_work [mac80211=
]
[   66.960627] Backtrace:
[   66.968163] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+=
0x18/0x1c)
[   66.981969]  r6:00000000 r5:bf024b00 r4:00000000 r3:00000000
[   66.991481] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20=
/0x28)
[   67.002560] [<c0805db0>] (dump_stack) from [<c01287bc>] (__warn+0xdc/0x1=
04)
[   67.013807] [<c01286e0>] (__warn) from [<c012880c>] (warn_slowpath_null+=
0x28/0x30)
[   67.021460]  r10:00000000 r8:00000004 r7:db7fc200 r6:db245810 r5:0001ffc=
4 r4:dc58ca00
[   67.034435] [<c01287e4>] (warn_slowpath_null) from [<bf023324>] (wl12xx_=
sdio_raw_write+0xb4/0x138 [wlcore_sdio])
[   67.051044] [<bf023270>] (wl12xx_sdio_raw_write [wlcore_sdio]) from [<bf=
39db0c>] (wlcore_set_partition+0xcc/0x50c [wlcore])
[   67.066297]  r10:00000000 r8:dc727bc8 r7:00000000 r6:bf3b3c40 r5:bf3dc06=
4 r4:db5a6d00
[   67.078668] [<bf39da40>] (wlcore_set_partition [wlcore]) from [<bf39015c=
>] (wl12xx_set_power_on+0x90/0x164 [wlcore])
[   67.093422]  r7:bf3b3c40 r6:db5a6d38 r5:00000000 r4:db5a6d00
[   67.099581] [<bf3900cc>] (wl12xx_set_power_on [wlcore]) from [<bf397160>=
] (wl1271_op_add_interface+0x644/0x950 [wlcore])
[   67.115910]  r5:db5a6d00 r4:ffffff92
[   67.120529] [<bf396b1c>] (wl1271_op_add_interface [wlcore]) from [<bf2f9=
fe0>] (drv_add_interface+0x34/0x80 [mac80211])
[   67.140965]  r10:db5a6a00 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a642=
0 r5:dc7274e0
[   67.152812]  r4:dc7274e0
[   67.160260] [<bf2f9fac>] (drv_add_interface [mac80211]) from [<bf328f44>=
] (ieee80211_reconfig+0x164/0xc0c [mac80211])
[   67.175659]  r4:db5a6420 r3:00000001
[   67.180363] [<bf328de0>] (ieee80211_reconfig [mac80211]) from [<bf2f8354=
>] (ieee80211_restart_work+0x90/0xbc [mac80211])
[   67.196643]  r10:00000000 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a642=
0 r5:db5a6a00
[   67.210562]  r4:db5a6a00
[   67.217633] [<bf2f82c4>] (ieee80211_restart_work [mac80211]) from [<c013=
f128>] (process_one_work+0x12c/0x374)
[   67.231776]  r7:dcb39400 r6:c0d0ea60 r5:db5a6c28 r4:dc031180
[   67.241634] [<c013effc>] (process_one_work) from [<c013f570>] (worker_th=
read+0x1c0/0x5b8)
[   67.253848]  r10:00000008 r9:c0d0ea60 r8:c0d16380 r7:dc031198 r6:c0d0ea7=
4 r5:c0d0ea60
[   67.261747]  r4:dc031180
[   67.269183] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11=
c/0x154)
[   67.282565]  r10:c013f3b0 r9:dc04fe9c r8:dc031180 r7:dc030658 r6:dc03060=
0 r5:00000000
[   67.294532]  r4:dc030640 r3:00000000
[   67.298212] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14=
/0x2c)
[   67.310193]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:0000000=
0 r5:c0145150
[   67.324496]  r4:dc030600 r3:ffffffff
[   67.328127] ---[ end trace 06c90d424e072157 ]---
[   67.332801] wl1271_sdio mmc1:0001:2: sdio write failed (-110)
[   67.343419] mmc mmc1:0001: wl12xx_sdio_power_off: wlcore write did not y=
et complete?
[   67.351251] CPU: 0 PID: 3 Comm: kworker/0:0 Tainted: G        W       4.=
14.40-01413-g36a61bea-dirty #105
[   67.378058] Hardware name: Generic AM33XX (Flattened Device Tree)
[   67.388937] Workqueue: events_freezable ieee80211_restart_work [mac80211=
]
[   67.400047] Backtrace:
[   67.402618] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+=
0x18/0x1c)
[   67.415557]  r6:db5a6d38 r5:dc5ad008 r4:00000000 r3:00000000
[   67.421327] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20=
/0x28)
[   67.437885] [<c0805db0>] (dump_stack) from [<bf023258>] (wl12xx_sdio_set=
_power+0x140/0x158 [wlcore_sdio])
[   67.451892] [<bf023118>] (wl12xx_sdio_set_power [wlcore_sdio]) from [<bf=
390204>] (wl12xx_set_power_on+0x138/0x164 [wlcore])
[   67.467074]  r7:bf3b3c40 r6:db5a6d38 r5:ffffff92 r4:db5a6d00
[   67.473232] [<bf3900cc>] (wl12xx_set_power_on [wlcore]) from [<bf397160>=
] (wl1271_op_add_interface+0x644/0x950 [wlcore])
[   67.491756]  r5:db5a6d00 r4:ffffff92
[   67.500162] [<bf396b1c>] (wl1271_op_add_interface [wlcore]) from [<bf2f9=
fe0>] (drv_add_interface+0x34/0x80 [mac80211])
[   67.515502]  r10:db5a6a00 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a642=
0 r5:dc7274e0
[   67.527255]  r4:dc7274e0
[   67.530956] [<bf2f9fac>] (drv_add_interface [mac80211]) from [<bf328f44>=
] (ieee80211_reconfig+0x164/0xc0c [mac80211])
[   67.547152]  r4:db5a6420 r3:00000001
[   67.551854] [<bf328de0>] (ieee80211_reconfig [mac80211]) from [<bf2f8354=
>] (ieee80211_restart_work+0x90/0xbc [mac80211])
[   67.572462]  r10:00000000 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a642=
0 r5:db5a6a00
[   67.584507]  r4:db5a6a00
[   67.587806] [<bf2f82c4>] (ieee80211_restart_work [mac80211]) from [<c013=
f128>] (process_one_work+0x12c/0x374)
[   67.605215]  r7:dcb39400 r6:c0d0ea60 r5:db5a6c28 r4:dc031180
[   67.610986] [<c013effc>] (process_one_work) from [<c013f570>] (worker_th=
read+0x1c0/0x5b8)
[   67.629039]  r10:00000008 r9:c0d0ea60 r8:c0d16380 r7:dc031198 r6:c0d0ea7=
4 r5:c0d0ea60
[   67.640701]  r4:dc031180
[   67.647253] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11=
c/0x154)
[   67.658699]  r10:c013f3b0 r9:dc04fe9c r8:dc031180 r7:dc030658 r6:dc03060=
0 r5:00000000
[   67.670355]  r4:dc030640 r3:00000000
[   67.677815] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14=
/0x2c)
[   67.688918]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:0000000=
0 r5:c0145150
[   67.700531]  r4:dc030600 r3:ffffffff
[   69.429476] ------------[ cut here ]------------
[   69.434355] WARNING: CPU: 0 PID: 3 at drivers/net/wireless/ti/wlcore/sdi=
o.c:145 wl12xx_sdio_raw_write+0xb4/0x138 [wlcore_sdio]
[   69.451344] Modules linked in: usb_f_acm u_serial arc4 pru_rproc pruss_i=
ntc wl18xx usb_f_ecm wlcore musb_dsps mac80211 musb_hdrc cfg80211 pruss phy=
_am335x usbcore phy_generic phy_am335x_control xfrm_user xfrm4_tunnel ipcom=
p xfrm_ipcomp esp4 ah4 af_key xfrm_algo g_multi usb_f_mass_storage usb_f_rn=
dis u_ether libcomposite udc_core usb_common bluetooth ecdh_generic snd_soc=
_simple_card snd_soc_simple_card_utils wkup_m3_rproc pm33xx wkup_m3_ipc rem=
oteproc omap_aes_driver crypto_engine omap_crypto omap_sham ti_emif_sram pr=
uss_soc_bus wlcore_sdio rtc_omap musb_am335x omap_wdt sch_fq_codel
[   69.518879] CPU: 0 PID: 3 Comm: kworker/0:0 Tainted: G        W       4.=
14.40-01413-g36a61bea-dirty #105
[   69.532530] Hardware name: Generic AM33XX (Flattened Device Tree)
[   69.543540] Workqueue: events_freezable ieee80211_restart_work [mac80211=
]
[   69.550718] Backtrace:
[   69.558381] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+=
0x18/0x1c)
[   69.572307]  r6:00000000 r5:bf024b00 r4:00000000 r3:00000000
[   69.581846] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20=
/0x28)
[   69.593360] [<c0805db0>] (dump_stack) from [<c01287bc>] (__warn+0xdc/0x1=
04)
[   69.600478] [<c01286e0>] (__warn) from [<c012880c>] (warn_slowpath_null+=
0x28/0x30)
[   69.612769]  r10:00000000 r8:00000004 r7:db7fc200 r6:db245810 r5:0001ffc=
4 r4:dc58ca00
[   69.626945] [<c01287e4>] (warn_slowpath_null) from [<bf023324>] (wl12xx_=
sdio_raw_write+0xb4/0x138 [wlcore_sdio])
[   69.641383] [<bf023270>] (wl12xx_sdio_raw_write [wlcore_sdio]) from [<bf=
39db0c>] (wlcore_set_partition+0xcc/0x50c [wlcore])
[   69.656809]  r10:00000000 r8:dc727bc8 r7:00000000 r6:bf3b3c40 r5:bf3dc06=
4 r4:db5a6d00
[   69.668932] [<bf39da40>] (wlcore_set_partition [wlcore]) from [<bf39015c=
>] (wl12xx_set_power_on+0x90/0x164 [wlcore])
[   69.683503]  r7:bf3b3c40 r6:db5a6d38 r5:00000000 r4:db5a6d00
[   69.689907] [<bf3900cc>] (wl12xx_set_power_on [wlcore]) from [<bf397160>=
] (wl1271_op_add_interface+0x644/0x950 [wlcore])
[   69.706166]  r5:db5a6d00 r4:ffffff92
[   69.710781] [<bf396b1c>] (wl1271_op_add_interface [wlcore]) from [<bf2f9=
fe0>] (drv_add_interface+0x34/0x80 [mac80211])
[   69.731566]  r10:db5a6a00 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a642=
0 r5:dc7274e0
[   69.743519]  r4:dc7274e0
[   69.747317] [<bf2f9fac>] (drv_add_interface [mac80211]) from [<bf328f44>=
] (ieee80211_reconfig+0x164/0xc0c [mac80211])
[   69.763281]  r4:db5a6420 r3:00000001
[   69.767976] [<bf328de0>] (ieee80211_reconfig [mac80211]) from [<bf2f8354=
>] (ieee80211_restart_work+0x90/0xbc [mac80211])
[   69.788733]  r10:00000000 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a642=
0 r5:db5a6a00
[   69.800487]  r4:db5a6a00
[   69.807663] [<bf2f82c4>] (ieee80211_restart_work [mac80211]) from [<c013=
f128>] (process_one_work+0x12c/0x374)
[   69.821891]  r7:dcb39400 r6:c0d0ea60 r5:db5a6c28 r4:dc031180
[   69.831594] [<c013effc>] (process_one_work) from [<c013f570>] (worker_th=
read+0x1c0/0x5b8)
[   69.843909]  r10:00000008 r9:c0d0ea60 r8:c0d16380 r7:dc031198 r6:c0d0ea7=
4 r5:c0d0ea60
[   69.851807]  r4:dc031180
[   69.859227] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11=
c/0x154)
[   69.872667]  r10:c013f3b0 r9:dc04fe9c r8:dc031180 r7:dc030658 r6:dc03060=
0 r5:00000000
[   69.884690]  r4:dc030640 r3:00000000
[   69.888375] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14=
/0x2c)
[   69.900364]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:0000000=
0 r5:c0145150
[   69.914592]  r4:dc030600 r3:ffffffff
[   69.918222] ---[ end trace 06c90d424e072158 ]---
[   69.922897] wl1271_sdio mmc1:0001:2: sdio write failed (-110)
[   69.933405] mmc mmc1:0001: wl12xx_sdio_power_off: wlcore write did not y=
et complete?
[   69.941243] CPU: 0 PID: 3 Comm: kworker/0:0 Tainted: G        W       4.=
14.40-01413-g36a61bea-dirty #105
[   69.968249] Hardware name: Generic AM33XX (Flattened Device Tree)
[   69.979069] Workqueue: events_freezable ieee80211_restart_work [mac80211=
]
[   69.990223] Backtrace:
[   69.992794] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+=
0x18/0x1c)
[   70.005750]  r6:db5a6d38 r5:dc5ad008 r4:00000000 r3:00000000
[   70.011527] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20=
/0x28)
[   70.028035] [<c0805db0>] (dump_stack) from [<bf023258>] (wl12xx_sdio_set=
_power+0x140/0x158 [wlcore_sdio])
[   70.041927] [<bf023118>] (wl12xx_sdio_set_power [wlcore_sdio]) from [<bf=
390204>] (wl12xx_set_power_on+0x138/0x164 [wlcore])
[   70.057178]  r7:bf3b3c40 r6:db5a6d38 r5:ffffff92 r4:db5a6d00
[   70.063333] [<bf3900cc>] (wl12xx_set_power_on [wlcore]) from [<bf397160>=
] (wl1271_op_add_interface+0x644/0x950 [wlcore])
[   70.081996]  r5:db5a6d00 r4:ffffff92
[   70.090340] [<bf396b1c>] (wl1271_op_add_interface [wlcore]) from [<bf2f9=
fe0>] (drv_add_interface+0x34/0x80 [mac80211])
[   70.105745]  r10:db5a6a00 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a642=
0 r5:dc7274e0
[   70.117490]  r4:dc7274e0
[   70.121197] [<bf2f9fac>] (drv_add_interface [mac80211]) from [<bf328f44>=
] (ieee80211_reconfig+0x164/0xc0c [mac80211])
[   70.137336]  r4:db5a6420 r3:00000001
[   70.142045] [<bf328de0>] (ieee80211_reconfig [mac80211]) from [<bf2f8354=
>] (ieee80211_restart_work+0x90/0xbc [mac80211])
[   70.162550]  r10:00000000 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a642=
0 r5:db5a6a00
[   70.174625]  r4:db5a6a00
[   70.177923] [<bf2f82c4>] (ieee80211_restart_work [mac80211]) from [<c013=
f128>] (process_one_work+0x12c/0x374)
[   70.193199]  r7:dcb39400 r6:c0d0ea60 r5:db5a6c28 r4:dc031180
[   70.198959] [<c013effc>] (process_one_work) from [<c013f570>] (worker_th=
read+0x1c0/0x5b8)
[   70.217151]  r10:00000008 r9:c0d0ea60 r8:c0d16380 r7:dc031198 r6:c0d0ea7=
4 r5:c0d0ea60
[   70.228862]  r4:dc031180
[   70.231489] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11=
c/0x154)
[   70.243312]  r10:c013f3b0 r9:dc04fe9c r8:dc031180 r7:dc030658 r6:dc03060=
0 r5:00000000
[   70.251212]  r4:dc030640 r3:00000000
[   70.265017] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14=
/0x2c)
[   70.272321]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:0000000=
0 r5:c0145150
[   70.285370]  r4:dc030600 r3:ffffffff
[   70.289003] wlcore: ERROR firmware boot failed despite 3 retries
[   70.304327] ------------[ cut here ]------------
[   70.309755] WARNING: CPU: 0 PID: 3 at net/mac80211/util.c:1902 ieee80211=
_reconfig+0x17c/0xc0c [mac80211]
[   70.323490] Modules linked in: usb_f_acm u_serial arc4 pru_rproc pruss_i=
ntc wl18xx usb_f_ecm wlcore musb_dsps mac80211 musb_hdrc cfg80211 pruss phy=
_am335x usbcore phy_generic phy_am335x_control xfrm_user xfrm4_tunnel ipcom=
p xfrm_ipcomp esp4 ah4 af_key xfrm_algo g_multi usb_f_mass_storage usb_f_rn=
dis u_ether libcomposite udc_core usb_common bluetooth ecdh_generic snd_soc=
_simple_card snd_soc_simple_card_utils wkup_m3_rproc pm33xx wkup_m3_ipc rem=
oteproc omap_aes_driver crypto_engine omap_crypto omap_sham ti_emif_sram pr=
uss_soc_bus wlcore_sdio rtc_omap musb_am335x omap_wdt sch_fq_codel
[   70.392540] CPU: 0 PID: 3 Comm: kworker/0:0 Tainted: G        W       4.=
14.40-01413-g36a61bea-dirty #105
[   70.406641] Hardware name: Generic AM33XX (Flattened Device Tree)
[   70.413537] Workqueue: events_freezable ieee80211_restart_work [mac80211=
]
[   70.424850] Backtrace:
[   70.427396] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+=
0x18/0x1c)
[   70.440543]  r6:00000000 r5:bf3494ac r4:00000000 r3:00000000
[   70.452546] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20=
/0x28)
[   70.466545] [<c0805db0>] (dump_stack) from [<c01287bc>] (__warn+0xdc/0x1=
04)
[   70.477427] [<c01286e0>] (__warn) from [<c012880c>] (warn_slowpath_null+=
0x28/0x30)
[   70.488858]  r10:db5a6a00 r8:ffffff92 r7:db5a6420 r6:db5a6420 r5:dc7274e=
0 r4:db5a6420
[   70.501458] [<c01287e4>] (warn_slowpath_null) from [<bf328f5c>] (ieee802=
11_reconfig+0x17c/0xc0c [mac80211])
[   70.516702] [<bf328de0>] (ieee80211_reconfig [mac80211]) from [<bf2f8354=
>] (ieee80211_restart_work+0x90/0xbc [mac80211])
[   70.531935]  r10:00000000 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a642=
0 r5:db5a6a00
[   70.543840]  r4:db5a6a00
[   70.547122] [<bf2f82c4>] (ieee80211_restart_work [mac80211]) from [<c013=
f128>] (process_one_work+0x12c/0x374)
[   70.562592]  r7:dcb39400 r6:c0d0ea60 r5:db5a6c28 r4:dc031180
[   70.574711] [<c013effc>] (process_one_work) from [<c013f570>] (worker_th=
read+0x1c0/0x5b8)
[   70.586858]  r10:00000008 r9:c0d0ea60 r8:c0d16380 r7:dc031198 r6:c0d0ea7=
4 r5:c0d0ea60
[   70.594931]  r4:dc031180
[   70.597541] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11=
c/0x154)
[   70.610248]  r10:c013f3b0 r9:dc04fe9c r8:dc031180 r7:dc030658 r6:dc03060=
0 r5:00000000
[   70.627088]  r4:dc030640 r3:00000000
[   70.630774] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14=
/0x2c)
[   70.642831]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:0000000=
0 r5:c0145150
[   70.657197]  r4:dc030600 r3:ffffffff
[   70.660830] ---[ end trace 06c90d424e072159 ]---
[   70.677592] ------------[ cut here ]------------
[   70.683361] WARNING: CPU: 0 PID: 3 at net/mac80211/driver-ops.h:18 drv_r=
emove_interface+0x64/0x70 [mac80211]
[   70.699764] wlan0:  Failed check-sdata-in-driver check, flags: 0x0
[   70.707634] Modules linked in: usb_f_acm u_serial arc4 pru_rproc pruss_i=
ntc wl18xx usb_f_ecm wlcore musb_dsps mac80211 musb_hdrc cfg80211 pruss phy=
_am335x usbcore phy_generic phy_am335x_control xfrm_user xfrm4_tunnel ipcom=
p xfrm_ipcomp esp4 ah4 af_key xfrm_algo g_multi usb_f_mass_storage usb_f_rn=
dis u_ether libcomposite udc_core usb_common bluetooth ecdh_generic snd_soc=
_simple_card snd_soc_simple_card_utils wkup_m3_rproc pm33xx wkup_m3_ipc rem=
oteproc omap_aes_driver crypto_engine omap_crypto omap_sham ti_emif_sram pr=
uss_soc_bus wlcore_sdio rtc_omap musb_am335x omap_wdt sch_fq_codel
[   70.764973] CPU: 0 PID: 3 Comm: kworker/0:0 Tainted: G        W       4.=
14.40-01413-g36a61bea-dirty #105
[   70.776384] Hardware name: Generic AM33XX (Flattened Device Tree)
[   70.782902] Workqueue: events_freezable ieee80211_restart_work [mac80211=
]
[   70.792756] Backtrace:
[   70.796872] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+=
0x18/0x1c)
[   70.806114]  r6:00000000 r5:bf348224 r4:dc05dd68 r3:00000000
[   70.811835] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20=
/0x28)
[   70.821797] [<c0805db0>] (dump_stack) from [<c01287bc>] (__warn+0xdc/0x1=
04)
[   70.830440] [<c01286e0>] (__warn) from [<c012889c>] (warn_slowpath_fmt+0=
x40/0x48)
[   70.839599]  r10:db5a6420 r8:00000000 r7:00000000 r6:db5a6a28 r5:dc7274e=
0 r4:00000000
[   70.849459] [<c0128860>] (warn_slowpath_fmt) from [<bf2fa0f4>] (drv_remo=
ve_interface+0x64/0x70 [mac80211])
[   70.861026]  r3:dc727000 r2:bf348240
[   70.866248]  r4:dc7274e0
[   70.869282] [<bf2fa090>] (drv_remove_interface [mac80211]) from [<bf30c0=
dc>] (ieee80211_do_stop+0x7d4/0x8dc [mac80211])
[   70.883184]  r4:db5a698c
[   70.886246] [<bf30b908>] (ieee80211_do_stop [mac80211]) from [<bf30c1fc>=
] (ieee80211_stop+0x18/0x20 [mac80211])
[   70.899279]  r10:db5a6a00 r9:c0d0ea60 r8:dc05de58 r7:00000001 r6:db5a600=
0 r5:dc05de58
[   70.908837]  r4:dc727000
[   70.911754] [<bf30c1e4>] (ieee80211_stop [mac80211]) from [<c06e62f0>] (=
__dev_close_many+0x90/0xd0)
[   70.923892] [<c06e6260>] (__dev_close_many) from [<c06e63a4>] (dev_close=
_many+0x74/0xf0)
[   70.932029]  r5:db5a63e8 r4:dc7274e8
[   70.938308] [<c06e6330>] (dev_close_many) from [<c06e88c0>] (dev_close+0=
x44/0x5c)
[   70.947444]  r8:ffffff92 r7:db5a6420 r6:db5a6000 r5:db5a63e8 r4:dc7274e8=
 r3:dc727000
[   70.957120] [<c06e887c>] (dev_close) from [<bf26cb18>] (cfg80211_shutdow=
n_all_interfaces+0x3c/0xc0 [cfg80211])
[   70.969490] [<bf26cadc>] (cfg80211_shutdown_all_interfaces [cfg80211]) f=
rom [<bf326c14>] (ieee80211_handle_reconfig_failure+0xcc/0xd0 [mac80211])
[   70.984618]  r6:db5a6420 r5:db5a6b10 r4:db5a6420 r3:db5a6b08
[   70.990774] [<bf326b48>] (ieee80211_handle_reconfig_failure [mac80211]) =
from [<bf329128>] (ieee80211_reconfig+0x348/0xc0c [mac80211])
[   71.005701]  r5:db5a6a00 r4:db5a6420
[   71.009760] [<bf328de0>] (ieee80211_reconfig [mac80211]) from [<bf2f8354=
>] (ieee80211_restart_work+0x90/0xbc [mac80211])
[   71.023910]  r10:00000000 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a642=
0 r5:db5a6a00
[   71.031785]  r4:db5a6a00
[   71.037253] [<bf2f82c4>] (ieee80211_restart_work [mac80211]) from [<c013=
f128>] (process_one_work+0x12c/0x374)
[   71.049089]  r7:dcb39400 r6:c0d0ea60 r5:db5a6c28 r4:dc031180
[   71.056485] [<c013effc>] (process_one_work) from [<c013f570>] (worker_th=
read+0x1c0/0x5b8)
[   71.066280]  r10:00000008 r9:c0d0ea60 r8:c0d16380 r7:dc031198 r6:c0d0ea7=
4 r5:c0d0ea60
[   71.075666]  r4:dc031180
[   71.078241] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11=
c/0x154)
[   71.088235]  r10:c013f3b0 r9:dc04fe9c r8:dc031180 r7:dc030658 r6:dc03060=
0 r5:00000000
[   71.097655]  r4:dc030640 r3:00000000
[   71.101282] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14=
/0x2c)
[   71.111064]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:0000000=
0 r5:c0145150
[   71.120527]  r4:dc030600 r3:ffffffff
[   71.125652] ---[ end trace 06c90d424e07215a ]---

root@am335x-evm:~# ifconfig wlan0 down
root@am335x-evm:~# ifconfig wlan0 up
[  590.896452] wlcore: PHY firmware version: Rev 8.2.0.0.242
[  591.017507] wlcore: firmware booted (Rev 8.9.0.0.78)
[  591.109143] IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
root@am335x-evm:~#

Regards,
Eyal

^ permalink raw reply	[flat|nested] 46+ messages in thread

* RE: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-22  6:40         ` Reizer, Eyal
  0 siblings, 0 replies; 46+ messages in thread
From: Reizer, Eyal @ 2018-05-22  6:40 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Kalle Valo, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn,
	Maital, Altshul, Maxim, Shahar Patury,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Loewy, Chen

> >
> > This warning is because wlcore is wlcore is still in ELP. This is
> > somehow possible even though we call pm_runtime_get_sync() in
> > wl1271_op_resume(). Anyways, I'll try to reproduce it here.
> 
> Sorry I can't somehow get my beagleboard to wake-up from suspend,
> I'm almost certain that worked the last time I tried.
> 
> Anyways, maybe the following patch fixes this if you care to
> test again.
> 
> Regards,
> 
> Tony
> 
> 8< ------------------------
> 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
> @@ -1867,8 +1867,6 @@ static int __maybe_unused
> wl1271_op_resume(struct ieee80211_hw *hw)
>  			if (ret)
>  				wl12xx_queue_recovery_work(wl);
>  		}
> -
> -		wlcore_enable_interrupts(wl);
>  	}
> 
>  	if (pending_recovery) {
> @@ -1877,6 +1875,8 @@ static int __maybe_unused
> wl1271_op_resume(struct ieee80211_hw *hw)
>  		goto out_sleep;
>  	}
> 
> +	wlcore_enable_interrupts(wl);
> +
>  	ret = pm_runtime_get_sync(wl->dev);
>  	if (ret < 0) {
>  		pm_runtime_put_noidle(wl->dev);

It still crash.
The crash is different now.
It also complains about:
[   60.544224] Unbalanced enable for IRQ 65
Need down/up of the interface to recover after it.
Log below:

root@am335x-evm:~#
root@am335x-evm:~#
root@am335x-evm:~# echo mem > /sys/power/state
[   42.994534] PM: suspend entry (deep)
[   42.998182] PM: Syncing filesystems ... done.
[   43.946134] Freezing user space processes ... (elapsed 0.002 seconds) done.
[   43.957020] OOM killer disabled.
[   43.960449] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
[   43.971227] Suspending console(s) (use no_console_suspend to debug)
[   44.093784] wlcore: down
[   44.181597] pm33xx pm33xx: PM: Successfully put all powerdomains to target state
[   44.181597] PM: Wakeup source UART
[   44.206334] net eth0: initializing cpsw version 1.12 (0)
[   44.304417] SMSC LAN8710/LAN8720 4a101000.mdio:00: attached PHY driver [SMSC LAN8710/LAN8720] (mii_bus:phy_addr=4a101000.mdio:00, irq=POLL)
[   44.650784] wlcore: PHY firmware version: Rev 8.2.0.0.242
[   44.746182] wlcore: firmware booted (Rev 8.9.0.0.78)
[   44.929226] OOM killer enabled.
[   44.932602] Restarting tasks ... done.
[   44.961136] PM: suspend exit
root@am335x-evm:~# iw phy0 wowlan enable any
root@am335x-evm:~#
root@am335x-evm:~#
root@am335x-evm:~#
root@am335x-evm:~#
root@am335x-evm:~# echo mem > /sys/power/state
[   60.114495] PM: suspend entry (deep)
[   60.118146] PM: Syncing filesystems ... done.
[   60.139243] Freezing user space processes ... (elapsed 0.001 seconds) done.
[   60.148483] OOM killer disabled.
[   60.151723] Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done.
[   60.160874] Suspending console(s) (use no_console_suspend to debug)
[   60.411089] pm33xx pm33xx: PM: Successfully put all powerdomains to target state
[   60.411089] PM: Wakeup source UART
[   60.435069] net eth0: initializing cpsw version 1.12 (0)
[   60.534303] SMSC LAN8710/LAN8720 4a101000.mdio:00: attached PHY driver [SMSC LAN8710/LAN8720] (mii_bus:phy_addr=4a101000.mdio:00, irq=POLL)
[   60.544143] ------------[ cut here ]------------
[   60.544213] WARNING: CPU: 0 PID: 730 at kernel/irq/manage.c:525 __enable_irq+0x4c/0x6c
[   60.544224] Unbalanced enable for IRQ 65
[   60.544232] Modules linked in: usb_f_acm u_serial arc4 pru_rproc pruss_intc wl18xx usb_f_ecm wlcore musb_dsps mac80211 musb_hdrc cfg80211 pruss phy_am335x usbcore phy_generic phy_am335x_control xfrm_user xfrm4_tunnel ipcomp xfrm_ipcomp esp4 ah4 af_key xfrm_algo g_multi usb_f_mass_storage usb_f_rndis u_ether libcomposite udc_core usb_common bluetooth ecdh_generic snd_soc_simple_card snd_soc_simple_card_utils wkup_m3_rproc pm33xx wkup_m3_ipc remoteproc omap_aes_driver crypto_engine omap_crypto omap_sham ti_emif_sram pruss_soc_bus wlcore_sdio rtc_omap musb_am335x omap_wdt sch_fq_codel
[   60.544574] CPU: 0 PID: 730 Comm: kworker/u2:11 Not tainted 4.14.40-01413-g36a61bea-dirty #105
[   60.544584] Hardware name: Generic AM33XX (Flattened Device Tree)
[   60.544624] Workqueue: events_unbound async_run_entry_fn
[   60.544639] Backtrace:
[   60.544698] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+0x18/0x1c)
[   60.544722]  r6:00000000 r5:c0a95d64 r4:db363d78 r3:c0d53158
[   60.544758] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20/0x28)
[   60.544794] [<c0805db0>] (dump_stack) from [<c01287bc>] (__warn+0xdc/0x104)
[   60.544821] [<c01286e0>] (__warn) from [<c012889c>] (warn_slowpath_fmt+0x40/0x48)
[   60.544848]  r10:c0d5310c r8:00000000 r7:db5a6d38 r6:00000000 r5:00000041 r4:00000000
[   60.544874] [<c0128860>] (warn_slowpath_fmt) from [<c0169760>] (__enable_irq+0x4c/0x6c)
[   60.544889]  r3:00000041 r2:c0a95ec4
[   60.544898]  r4:db278000
[   60.544922] [<c0169714>] (__enable_irq) from [<c01697bc>] (enable_irq+0x3c/0x74)
[   60.545265] [<c0169780>] (enable_irq) from [<bf39e068>] (wlcore_enable_interrupts+0x14/0x18 [wlcore])
[   60.545280]  r5:db5a6d00 r4:bf3b3c40
[   60.545619] [<bf39e054>] (wlcore_enable_interrupts [wlcore]) from [<bf399428>] (wl1271_op_resume+0x144/0x334 [wlcore])
[   60.546524] [<bf3992e4>] (wl1271_op_resume [wlcore]) from [<bf3291f8>] (ieee80211_reconfig+0x418/0xc0c [mac80211])
[   60.546548]  r7:db5a628c r6:bf26d640 r5:00000000 r4:db5a6420
[   60.547408] [<bf328de0>] (ieee80211_reconfig [mac80211]) from [<bf314ab8>] (ieee80211_resume+0x58/0x70 [mac80211])
[   60.547436]  r10:c0d5310c r9:db5a6258 r8:00000000 r7:db5a628c r6:bf26d640 r5:00000000
[   60.547446]  r4:db5a6420
[   60.548310] [<bf314a60>] (ieee80211_resume [mac80211]) from [<bf26d694>] (wiphy_resume+0x54/0x64 [cfg80211])
[   60.548326]  r4:db5a6258 r3:bf314a60
[   60.548611] [<bf26d640>] (wiphy_resume [cfg80211]) from [<c053c79c>] (dpm_run_callback+0x40/0xcc)
[   60.548625]  r4:00000000 r3:00000000
[   60.548652] [<c053c75c>] (dpm_run_callback) from [<c053ce24>] (device_resume+0xbc/0x234)
[   60.548679]  r10:00000000 r9:dc005000 r8:00000000 r6:00000010 r5:00000001 r4:db5a6258
[   60.548706] [<c053cd68>] (device_resume) from [<c053cfbc>] (async_resume+0x20/0x4c)
[   60.548732]  r8:00000000 r7:dc004100 r6:c0d4fde0 r5:c0d89b30 r4:db5a6258 r3:00000000
[   60.548765] [<c053cf9c>] (async_resume) from [<c01483e4>] (async_run_entry_fn+0x44/0x140)
[   60.548779]  r5:db56f480 r4:db56f490
[   60.548810] [<c01483a0>] (async_run_entry_fn) from [<c013f128>] (process_one_work+0x12c/0x374)
[   60.548830]  r6:dc005000 r5:db56f490 r4:db44eb80 r3:c01483a0
[   60.548855] [<c013effc>] (process_one_work) from [<c013f570>] (worker_thread+0x1c0/0x5b8)
[   60.548882]  r10:00000088 r9:dc005000 r8:c0d16380 r7:db44eb98 r6:dc005014 r5:dc005000
[   60.548891]  r4:db44eb80
[   60.548924] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11c/0x154)
[   60.548950]  r10:c013f3b0 r9:db3cfeb4 r8:db44eb80 r7:db56ff58 r6:db56f400 r5:00000000
[   60.548963]  r4:db56ff40 r3:00000000
[   60.548996] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14/0x2c)
[   60.549022]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0145150
[   60.549034]  r4:db56f400 r3:ffffffff
[   60.549047] ---[ end trace 06c90d424e072151 ]---
[   60.549082] ------------[ cut here ]------------
[   60.549343] WARNING: CPU: 0 PID: 730 at drivers/net/wireless/ti/wlcore/cmd.c:76 wlcore_cmd_send_failsafe+0x498/0x4f8 [wlcore]
[   60.549352] Modules linked in: usb_f_acm u_serial arc4 pru_rproc pruss_intc wl18xx usb_f_ecm wlcore musb_dsps mac80211 musb_hdrc cfg80211 pruss phy_am335x usbcore phy_generic phy_am335x_control xfrm_user xfrm4_tunnel ipcomp xfrm_ipcomp esp4 ah4 af_key xfrm_algo g_multi usb_f_mass_storage usb_f_rndis u_ether libcomposite udc_core usb_common bluetooth ecdh_generic snd_soc_simple_card snd_soc_simple_card_utils wkup_m3_rproc pm33xx wkup_m3_ipc remoteproc omap_aes_driver crypto_engine omap_crypto omap_sham ti_emif_sram pruss_soc_bus wlcore_sdio rtc_omap musb_am335x omap_wdt sch_fq_codel
[   60.549675] CPU: 0 PID: 730 Comm: kworker/u2:11 Tainted: G        W       4.14.40-01413-g36a61bea-dirty #105
[   60.549685] Hardware name: Generic AM33XX (Flattened Device Tree)
[   60.549714] Workqueue: events_unbound async_run_entry_fn
[   60.549728] Backtrace:
[   60.549773] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+0x18/0x1c)
[   60.549794]  r6:00000000 r5:bf3ae59c r4:00000000 r3:c0d53158
[   60.549828] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20/0x28)
[   60.549861] [<c0805db0>] (dump_stack) from [<c01287bc>] (__warn+0xdc/0x104)
[   60.549888] [<c01286e0>] (__warn) from [<c012880c>] (warn_slowpath_null+0x28/0x30)
[   60.549915]  r10:c0d5310c r8:00000000 r7:db5a6d38 r6:db1b1980 r5:0000000c r4:db5a6d00
[   60.550110] [<c01287e4>] (warn_slowpath_null) from [<bf39a8b0>] (wlcore_cmd_send_failsafe+0x498/0x4f8 [wlcore])
[   60.550443] [<bf39a418>] (wlcore_cmd_send_failsafe [wlcore]) from [<bf39bea8>] (wlcore_cmd_configure_failsafe+0x60/0xd8 [wlcore])
[   60.550470]  r10:c0d5310c r9:db5a6258 r8:00000000 r7:db5a6d38 r6:00000057 r5:db5a6d00
[   60.550480]  r4:db1b1980
[   60.550808] [<bf39be48>] (wlcore_cmd_configure_failsafe [wlcore]) from [<bf39bf3c>] (wl1271_cmd_configure+0x1c/0x28 [wlcore])
[   60.550825]  r6:00000001 r5:db5a6d00 r4:db1b1980
[   60.551133] [<bf39bf20>] (wl1271_cmd_configure [wlcore]) from [<bf3d47e8>] (wl18xx_acx_interrupt_notify_config+0x48/0x80 [wl18xx])
[   60.551374] [<bf3d47a0>] (wl18xx_acx_interrupt_notify_config [wl18xx]) from [<bf3994f4>] (wl1271_op_resume+0x210/0x334 [wlcore])
[   60.551395]  r6:db5a6e20 r5:db5a6d00 r4:db5a6e1c r3:bf3e3000
[   60.552096] [<bf3992e4>] (wl1271_op_resume [wlcore]) from [<bf3291f8>] (ieee80211_reconfig+0x418/0xc0c [mac80211])
[   60.552118]  r7:db5a628c r6:bf26d640 r5:00000000 r4:db5a6420
[   60.552941] [<bf328de0>] (ieee80211_reconfig [mac80211]) from [<bf314ab8>] (ieee80211_resume+0x58/0x70 [mac80211])
[   60.552968]  r10:c0d5310c r9:db5a6258 r8:00000000 r7:db5a628c r6:bf26d640 r5:00000000
[   60.553361]  r4:db5a6420
[   60.554209] [<bf314a60>] (ieee80211_resume [mac80211]) from [<bf26d694>] (wiphy_resume+0x54/0x64 [cfg80211])
[   60.554226]  r4:db5a6258 r3:bf314a60
[   60.554500] [<bf26d640>] (wiphy_resume [cfg80211]) from [<c053c79c>] (dpm_run_callback+0x40/0xcc)
[   60.554515]  r4:00000000 r3:00000000
[   60.554543] [<c053c75c>] (dpm_run_callback) from [<c053ce24>] (device_resume+0xbc/0x234)
[   60.554569]  r10:00000000 r9:dc005000 r8:00000000 r6:00000010 r5:00000001 r4:db5a6258
[   60.554596] [<c053cd68>] (device_resume) from [<c053cfbc>] (async_resume+0x20/0x4c)
[   60.554623]  r8:00000000 r7:dc004100 r6:c0d4fde0 r5:c0d89b30 r4:db5a6258 r3:00000000
[   60.554655] [<c053cf9c>] (async_resume) from [<c01483e4>] (async_run_entry_fn+0x44/0x140)
[   60.554669]  r5:db56f480 r4:db56f490
[   60.554699] [<c01483a0>] (async_run_entry_fn) from [<c013f128>] (process_one_work+0x12c/0x374)
[   60.554719]  r6:dc005000 r5:db56f490 r4:db44eb80 r3:c01483a0
[   60.554744] [<c013effc>] (process_one_work) from [<c013f570>] (worker_thread+0x1c0/0x5b8)
[   60.554770]  r10:00000088 r9:dc005000 r8:c0d16380 r7:db44eb98 r6:dc005014 r5:dc005000
[   60.554780]  r4:db44eb80
[   60.554811] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11c/0x154)
[   60.554837]  r10:c013f3b0 r9:db3cfeb4 r8:db44eb80 r7:db56ff58 r6:db56f400 r5:00000000
[   60.554850]  r4:db56ff40 r3:00000000
[   60.554883] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14/0x2c)
[   60.554909]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0145150
[   60.554923]  r4:db56f400 r3:ffffffff
[   60.554937] ---[ end trace 06c90d424e072152 ]---
[   60.554950] ------------[ cut here ]------------
[   60.555200] WARNING: CPU: 0 PID: 730 at drivers/net/wireless/ti/wlcore/io.h:66 wlcore_cmd_send_failsafe+0xb8/0x4f8 [wlcore]
[   60.555208] Modules linked in: usb_f_acm u_serial arc4 pru_rproc pruss_intc wl18xx usb_f_ecm wlcore musb_dsps mac80211 musb_hdrc cfg80211 pruss phy_am335x usbcore phy_generic phy_am335x_control xfrm_user xfrm4_tunnel ipcomp xfrm_ipcomp esp4 ah4 af_key xfrm_algo g_multi usb_f_mass_storage usb_f_rndis u_ether libcomposite udc_core usb_common bluetooth ecdh_generic snd_soc_simple_card snd_soc_simple_card_utils wkup_m3_rproc pm33xx wkup_m3_ipc remoteproc omap_aes_driver crypto_engine omap_crypto omap_sham ti_emif_sram pruss_soc_bus wlcore_sdio rtc_omap musb_am335x omap_wdt sch_fq_codel
[   60.555529] CPU: 0 PID: 730 Comm: kworker/u2:11 Tainted: G        W       4.14.40-01413-g36a61bea-dirty #105
[   60.555539] Hardware name: Generic AM33XX (Flattened Device Tree)
[   60.555568] Workqueue: events_unbound async_run_entry_fn
[   60.555582] Backtrace:
[   60.555627] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+0x18/0x1c)
[   60.555647]  r6:00000000 r5:bf3ae61c r4:00000000 r3:c0d53158
[   60.555679] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20/0x28)
[   60.555710] [<c0805db0>] (dump_stack) from [<c01287bc>] (__warn+0xdc/0x104)
[   60.555739] [<c01286e0>] (__warn) from [<c012880c>] (warn_slowpath_null+0x28/0x30)
[   60.555766]  r10:c0d5310c r8:00000000 r7:db5a6d38 r6:db1b1980 r5:0000000c r4:db5a6d00
[   60.555961] [<c01287e4>] (warn_slowpath_null) from [<bf39a4d0>] (wlcore_cmd_send_failsafe+0xb8/0x4f8 [wlcore])
[   60.556294] [<bf39a418>] (wlcore_cmd_send_failsafe [wlcore]) from [<bf39bea8>] (wlcore_cmd_configure_failsafe+0x60/0xd8 [wlcore])
[   60.556321]  r10:c0d5310c r9:db5a6258 r8:00000000 r7:db5a6d38 r6:00000057 r5:db5a6d00
[   60.556331]  r4:db1b1980
[   60.556659] [<bf39be48>] (wlcore_cmd_configure_failsafe [wlcore]) from [<bf39bf3c>] (wl1271_cmd_configure+0x1c/0x28 [wlcore])
[   60.556676]  r6:00000001 r5:db5a6d00 r4:db1b1980
[   60.556952] [<bf39bf20>] (wl1271_cmd_configure [wlcore]) from [<bf3d47e8>] (wl18xx_acx_interrupt_notify_config+0x48/0x80 [wl18xx])
[   60.557193] [<bf3d47a0>] (wl18xx_acx_interrupt_notify_config [wl18xx]) from [<bf3994f4>] (wl1271_op_resume+0x210/0x334 [wlcore])
[   60.557214]  r6:db5a6e20 r5:db5a6d00 r4:db5a6e1c r3:bf3e3000
[   60.557892] [<bf3992e4>] (wl1271_op_resume [wlcore]) from [<bf3291f8>] (ieee80211_reconfig+0x418/0xc0c [mac80211])
[   60.557913]  r7:db5a628c r6:bf26d640 r5:00000000 r4:db5a6420
[   60.558735] [<bf328de0>] (ieee80211_reconfig [mac80211]) from [<bf314ab8>] (ieee80211_resume+0x58/0x70 [mac80211])
[   60.558762]  r10:c0d5310c r9:db5a6258 r8:00000000 r7:db5a628c r6:bf26d640 r5:00000000
[   60.558771]  r4:db5a6420
[   60.559488] [<bf314a60>] (ieee80211_resume [mac80211]) from [<bf26d694>] (wiphy_resume+0x54/0x64 [cfg80211])
[   60.559502]  r4:db5a6258 r3:bf314a60
[   60.559770] [<bf26d640>] (wiphy_resume [cfg80211]) from [<c053c79c>] (dpm_run_callback+0x40/0xcc)
[   60.559784]  r4:00000000 r3:00000000
[   60.559811] [<c053c75c>] (dpm_run_callback) from [<c053ce24>] (device_resume+0xbc/0x234)
[   60.559838]  r10:00000000 r9:dc005000 r8:00000000 r6:00000010 r5:00000001 r4:db5a6258
[   60.559864] [<c053cd68>] (device_resume) from [<c053cfbc>] (async_resume+0x20/0x4c)
[   60.559890]  r8:00000000 r7:dc004100 r6:c0d4fde0 r5:c0d89b30 r4:db5a6258 r3:00000000
[   60.559919] [<c053cf9c>] (async_resume) from [<c01483e4>] (async_run_entry_fn+0x44/0x140)
[   60.559933]  r5:db56f480 r4:db56f490
[   60.559962] [<c01483a0>] (async_run_entry_fn) from [<c013f128>] (process_one_work+0x12c/0x374)
[   60.559982]  r6:dc005000 r5:db56f490 r4:db44eb80 r3:c01483a0
[   60.560006] [<c013effc>] (process_one_work) from [<c013f570>] (worker_thread+0x1c0/0x5b8)
[   60.560032]  r10:00000088 r9:dc005000 r8:c0d16380 r7:db44eb98 r6:dc005014 r5:dc005000
[   60.560041]  r4:db44eb80
[   60.560071] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11c/0x154)
[   60.560097]  r10:c013f3b0 r9:db3cfeb4 r8:db44eb80 r7:db56ff58 r6:db56f400 r5:00000000
[   60.560110]  r4:db56ff40 r3:00000000
[   60.560140] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14/0x2c)
[   60.560166]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0145150
[   60.560179]  r4:db56f400 r3:ffffffff
[   60.560190] ---[ end trace 06c90d424e072153 ]---
[   60.560200] ------------[ cut here ]------------
[   60.560417] WARNING: CPU: 0 PID: 730 at drivers/net/wireless/ti/wlcore/main.c:806 wl12xx_queue_recovery_work+0x64/0x6c [wlcore]
[   60.560424] Modules linked in: usb_f_acm u_serial arc4 pru_rproc pruss_intc wl18xx usb_f_ecm wlcore musb_dsps mac80211 musb_hdrc cfg80211 pruss phy_am335x usbcore phy_generic phy_am335x_control xfrm_user xfrm4_tunnel ipcomp xfrm_ipcomp esp4 ah4 af_key xfrm_algo g_multi usb_f_mass_storage usb_f_rndis u_ether libcomposite udc_core usb_common bluetooth ecdh_generic snd_soc_simple_card snd_soc_simple_card_utils wkup_m3_rproc pm33xx wkup_m3_ipc remoteproc omap_aes_driver crypto_engine omap_crypto omap_sham ti_emif_sram pruss_soc_bus wlcore_sdio rtc_omap musb_am335x omap_wdt sch_fq_codel
[   60.560736] CPU: 0 PID: 730 Comm: kworker/u2:11 Tainted: G        W       4.14.40-01413-g36a61bea-dirty #105
[   60.560746] Hardware name: Generic AM33XX (Flattened Device Tree)
[   60.560772] Workqueue: events_unbound async_run_entry_fn
[   60.560785] Backtrace:
[   60.560825] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+0x18/0x1c)
[   60.560847]  r6:00000000 r5:bf3ac5f4 r4:00000000 r3:c0d53158
[   60.560877] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20/0x28)
[   60.560908] [<c0805db0>] (dump_stack) from [<c01287bc>] (__warn+0xdc/0x104)
[   60.560934] [<c01286e0>] (__warn) from [<c012880c>] (warn_slowpath_null+0x28/0x30)
[   60.560961]  r10:c0d5310c r8:00000000 r7:db5a6d38 r6:db1b1980 r5:0000000c r4:db5a6d00
[   60.561154] [<c01287e4>] (warn_slowpath_null) from [<bf3974d0>] (wl12xx_queue_recovery_work+0x64/0x6c [wlcore])
[   60.561485] [<bf39746c>] (wl12xx_queue_recovery_work [wlcore]) from [<bf39a498>] (wlcore_cmd_send_failsafe+0x80/0x4f8 [wlcore])
[   60.561500]  r4:db5a6d00 r3:c0d53158
[   60.561826] [<bf39a418>] (wlcore_cmd_send_failsafe [wlcore]) from [<bf39bea8>] (wlcore_cmd_configure_failsafe+0x60/0xd8 [wlcore])
[   60.561852]  r10:c0d5310c r9:db5a6258 r8:00000000 r7:db5a6d38 r6:00000057 r5:db5a6d00
[   60.561862]  r4:db1b1980
[   60.562188] [<bf39be48>] (wlcore_cmd_configure_failsafe [wlcore]) from [<bf39bf3c>] (wl1271_cmd_configure+0x1c/0x28 [wlcore])
[   60.562205]  r6:00000001 r5:db5a6d00 r4:db1b1980
[   60.562466] [<bf39bf20>] (wl1271_cmd_configure [wlcore]) from [<bf3d47e8>] (wl18xx_acx_interrupt_notify_config+0x48/0x80 [wl18xx])
[   60.562708] [<bf3d47a0>] (wl18xx_acx_interrupt_notify_config [wl18xx]) from [<bf3994f4>] (wl1271_op_resume+0x210/0x334 [wlcore])
[   60.562729]  r6:db5a6e20 r5:db5a6d00 r4:db5a6e1c r3:bf3e3000
[   60.563368] [<bf3992e4>] (wl1271_op_resume [wlcore]) from [<bf3291f8>] (ieee80211_reconfig+0x418/0xc0c [mac80211])
[   60.563526]  r7:db5a628c r6:bf26d640 r5:00000000 r4:db5a6420
[   60.564377] [<bf328de0>] (ieee80211_reconfig [mac80211]) from [<bf314ab8>] (ieee80211_resume+0x58/0x70 [mac80211])
[   60.564405]  r10:c0d5310c r9:db5a6258 r8:00000000 r7:db5a628c r6:bf26d640 r5:00000000
[   60.564415]  r4:db5a6420
[   60.565129] [<bf314a60>] (ieee80211_resume [mac80211]) from [<bf26d694>] (wiphy_resume+0x54/0x64 [cfg80211])
[   60.565144]  r4:db5a6258 r3:bf314a60
[   60.565413] [<bf26d640>] (wiphy_resume [cfg80211]) from [<c053c79c>] (dpm_run_callback+0x40/0xcc)
[   60.565429]  r4:00000000 r3:00000000
[   60.565456] [<c053c75c>] (dpm_run_callback) from [<c053ce24>] (device_resume+0xbc/0x234)
[   60.565482]  r10:00000000 r9:dc005000 r8:00000000 r6:00000010 r5:00000001 r4:db5a6258
[   60.565509] [<c053cd68>] (device_resume) from [<c053cfbc>] (async_resume+0x20/0x4c)
[   60.565535]  r8:00000000 r7:dc004100 r6:c0d4fde0 r5:c0d89b30 r4:db5a6258 r3:00000000
[   60.565565] [<c053cf9c>] (async_resume) from [<c01483e4>] (async_run_entry_fn+0x44/0x140)
[   60.565579]  r5:db56f480 r4:db56f490
[   60.565609] [<c01483a0>] (async_run_entry_fn) from [<c013f128>] (process_one_work+0x12c/0x374)
[   60.565629]  r6:dc005000 r5:db56f490 r4:db44eb80 r3:c01483a0
[   60.565653] [<c013effc>] (process_one_work) from [<c013f570>] (worker_thread+0x1c0/0x5b8)
[   60.565679]  r10:00000088 r9:dc005000 r8:c0d16380 r7:db44eb98 r6:dc005014 r5:dc005000
[   60.565689]  r4:db44eb80
[   60.565718] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11c/0x154)
[   60.565744]  r10:c013f3b0 r9:db3cfeb4 r8:db44eb80 r7:db56ff58 r6:db56f400 r5:00000000
[   60.565756]  r4:db56ff40 r3:00000000
[   60.565788] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14/0x2c)
[   60.565814]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0145150
[   60.565827]  r4:db56f400 r3:ffffffff
[   60.565839] ---[ end trace 06c90d424e072154 ]---
[   60.565949] wlcore: WARNING CONFIGURE command NOK
[   60.565965] wlcore: WARNING acx interrupt notify setting failed: -5
[   60.566025] wlcore: Hardware recovery in progress. FW ver: Rev 8.9.0.0.78
[   60.566037] ------------[ cut here ]------------
[   60.566280] WARNING: CPU: 0 PID: 713 at drivers/net/wireless/ti/wlcore/io.h:66 wlcore_set_partition+0xa0/0x50c [wlcore]
[   60.566288] Modules linked in: usb_f_acm u_serial arc4 pru_rproc pruss_intc wl18xx usb_f_ecm wlcore musb_dsps mac80211 musb_hdrc cfg80211 pruss phy_am335x usbcore phy_generic phy_am335x_control xfrm_user xfrm4_tunnel ipcomp xfrm_ipcomp esp4 ah4 af_key xfrm_algo g_multi usb_f_mass_storage usb_f_rndis u_ether libcomposite udc_core usb_common bluetooth ecdh_generic snd_soc_simple_card snd_soc_simple_card_utils wkup_m3_rproc pm33xx wkup_m3_ipc remoteproc omap_aes_driver crypto_engine omap_crypto omap_sham ti_emif_sram pruss_soc_bus wlcore_sdio rtc_omap musb_am335x omap_wdt sch_fq_codel
[   60.566605] CPU: 0 PID: 713 Comm: kworker/u2:5 Tainted: G        W       4.14.40-01413-g36a61bea-dirty #105
[   60.566614] Hardware name: Generic AM33XX (Flattened Device Tree)
[   60.566800] Workqueue: phy0 wl1271_recovery_work [wlcore]
[   60.566813] Backtrace:
[   60.566860] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+0x18/0x1c)
[   60.566882]  r6:00000000 r5:bf3af4c4 r4:00000000 r3:c0d53158
[   60.566914] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20/0x28)
[   60.566944] [<c0805db0>] (dump_stack) from [<c01287bc>] (__warn+0xdc/0x104)
[   60.566971] [<c01286e0>] (__warn) from [<c012880c>] (warn_slowpath_null+0x28/0x30)
[   60.566999]  r10:00000000 r8:db5a6d38 r7:00000000 r6:bf3b3c40 r5:bf3dc064 r4:db5a6d00
[   60.567188] [<c01287e4>] (warn_slowpath_null) from [<bf39dae0>] (wlcore_set_partition+0xa0/0x50c [wlcore])
[   60.567520] [<bf39da40>] (wlcore_set_partition [wlcore]) from [<bf396884>] (wl1271_recovery_work+0x174/0x40c [wlcore])
[   60.567541]  r7:dc639a00 r6:db5a6d00 r5:00000000 r4:db5a6f94
[   60.567719] [<bf396710>] (wl1271_recovery_work [wlcore]) from [<c013f128>] (process_one_work+0x12c/0x374)
[   60.567743]  r8:00000005 r7:dc639a00 r6:dc005000 r5:db5a6f94 r4:db264880
[   60.567768] [<c013effc>] (process_one_work) from [<c013f570>] (worker_thread+0x1c0/0x5b8)
[   60.567794]  r10:00000088 r9:dc005000 r8:c0d16380 r7:db264898 r6:dc005014 r5:dc005000
[   60.567804]  r4:db264880
[   60.567831] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11c/0x154)
[   60.567857]  r10:c013f3b0 r9:d6b73eb4 r8:db264880 r7:db1eb4d8 r6:db1eb480 r5:00000000
[   60.567870]  r4:db1eb4c0 r3:00000000
[   60.567899] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14/0x2c)
[   60.567925]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0145150
[   60.567938]  r4:db1eb480 r3:ffffffff
[   60.567948] ---[ end trace 06c90d424e072155 ]---
[   60.567984] wlcore: down
[   60.568843] ieee80211 phy0: Hardware restart was requested
[   62.536363] OOM killer enabled.
[   62.539523] Restarting tasks ... done.
root@am335x-evm:~# [   62.613165] PM: suspend exit
[   64.259379] ------------[ cut here ]------------
[   64.264263] WARNING: CPU: 0 PID: 3 at drivers/net/wireless/ti/wlcore/sdio.c:145 wl12xx_sdio_raw_write+0xb4/0x138 [wlcore_sdio]
[   64.281202] Modules linked in: usb_f_acm u_serial arc4 pru_rproc pruss_intc wl18xx usb_f_ecm wlcore musb_dsps mac80211 musb_hdrc cfg80211 pruss phy_am335x usbcore phy_generic phy_am335x_control xfrm_user xfrm4_tunnel ipcomp xfrm_ipcomp esp4 ah4 af_key xfrm_algo g_multi usb_f_mass_storage usb_f_rndis u_ether libcomposite udc_core usb_common bluetooth ecdh_generic snd_soc_simple_card snd_soc_simple_card_utils wkup_m3_rproc pm33xx wkup_m3_ipc remoteproc omap_aes_driver crypto_engine omap_crypto omap_sham ti_emif_sram pruss_soc_bus wlcore_sdio rtc_omap musb_am335x omap_wdt sch_fq_codel
[   64.348727] CPU: 0 PID: 3 Comm: kworker/0:0 Tainted: G        W       4.14.40-01413-g36a61bea-dirty #105
[   64.362411] Hardware name: Generic AM33XX (Flattened Device Tree)
[   64.373346] Workqueue: events_freezable ieee80211_restart_work [mac80211]
[   64.380520] Backtrace:
[   64.388153] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+0x18/0x1c)
[   64.401930]  r6:00000000 r5:bf024b00 r4:00000000 r3:00000000
[   64.411432] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20/0x28)
[   64.422527] [<c0805db0>] (dump_stack) from [<c01287bc>] (__warn+0xdc/0x104)
[   64.433906] [<c01286e0>] (__warn) from [<c012880c>] (warn_slowpath_null+0x28/0x30)
[   64.441563]  r10:00000000 r8:00000004 r7:db7fc200 r6:db245810 r5:0001ffc4 r4:dc58ca00
[   64.454433] [<c01287e4>] (warn_slowpath_null) from [<bf023324>] (wl12xx_sdio_raw_write+0xb4/0x138 [wlcore_sdio])
[   64.471018] [<bf023270>] (wl12xx_sdio_raw_write [wlcore_sdio]) from [<bf39db0c>] (wlcore_set_partition+0xcc/0x50c [wlcore])
[   64.486457]  r10:00000000 r8:dc727bc8 r7:00000000 r6:bf3b3c40 r5:bf3dc064 r4:db5a6d00
[   64.498730] [<bf39da40>] (wlcore_set_partition [wlcore]) from [<bf39015c>] (wl12xx_set_power_on+0x90/0x164 [wlcore])
[   64.513428]  r7:bf3b3c40 r6:db5a6d38 r5:00000000 r4:db5a6d00
[   64.519578] [<bf3900cc>] (wl12xx_set_power_on [wlcore]) from [<bf397160>] (wl1271_op_add_interface+0x644/0x950 [wlcore])
[   64.536110]  r5:db5a6d00 r4:dc727aa0
[   64.540729] [<bf396b1c>] (wl1271_op_add_interface [wlcore]) from [<bf2f9fe0>] (drv_add_interface+0x34/0x80 [mac80211])
[   64.561506]  r10:db5a6a00 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a6420 r5:dc7274e0
[   64.573554]  r4:dc7274e0
[   64.577270] [<bf2f9fac>] (drv_add_interface [mac80211]) from [<bf328f44>] (ieee80211_reconfig+0x164/0xc0c [mac80211])
[   64.595516]  r4:db5a6420 r3:00000001
[   64.600231] [<bf328de0>] (ieee80211_reconfig [mac80211]) from [<bf2f8354>] (ieee80211_restart_work+0x90/0xbc [mac80211])
[   64.616691]  r10:00000000 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a6420 r5:db5a6a00
[   64.630527]  r4:db5a6a00
[   64.637503] [<bf2f82c4>] (ieee80211_restart_work [mac80211]) from [<c013f128>] (process_one_work+0x12c/0x374)
[   64.651859]  r7:dcb39400 r6:c0d0ea60 r5:db5a6c28 r4:dc031180
[   64.661572] [<c013effc>] (process_one_work) from [<c013f570>] (worker_thread+0x1c0/0x5b8)
[   64.673966]  r10:00000008 r9:c0d0ea60 r8:c0d16380 r7:dc031198 r6:c0d0ea74 r5:c0d0ea60
[   64.681867]  r4:dc031180
[   64.689198] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11c/0x154)
[   64.702654]  r10:c013f3b0 r9:dc04fe9c r8:dc031180 r7:dc030658 r6:dc030600 r5:00000000
[   64.714610]  r4:dc030640 r3:00000000
[   64.718295] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14/0x2c)
[   64.730394]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0145150
[   64.744797]  r4:dc030600 r3:ffffffff
[   64.748427] ---[ end trace 06c90d424e072156 ]---
[   64.757792] wl1271_sdio mmc1:0001:2: sdio write failed (-110)
[   64.772377] mmc mmc1:0001: wl12xx_sdio_power_off: wlcore write did not yet complete?
[   64.786318] CPU: 0 PID: 3 Comm: kworker/0:0 Tainted: G        W       4.14.40-01413-g36a61bea-dirty #105
[   64.799746] Hardware name: Generic AM33XX (Flattened Device Tree)
[   64.810624] Workqueue: events_freezable ieee80211_restart_work [mac80211]
[   64.821602] Backtrace:
[   64.828002] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+0x18/0x1c)
[   64.839410]  r6:db5a6d38 r5:dc5ad008 r4:00000000 r3:00000000
[   64.848960] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20/0x28)
[   64.860074] [<c0805db0>] (dump_stack) from [<bf023258>] (wl12xx_sdio_set_power+0x140/0x158 [wlcore_sdio])
[   64.874019] [<bf023118>] (wl12xx_sdio_set_power [wlcore_sdio]) from [<bf390204>] (wl12xx_set_power_on+0x138/0x164 [wlcore])
[   64.889128]  r7:bf3b3c40 r6:db5a6d38 r5:ffffff92 r4:db5a6d00
[   64.899225] [<bf3900cc>] (wl12xx_set_power_on [wlcore]) from [<bf397160>] (wl1271_op_add_interface+0x644/0x950 [wlcore])
[   64.914290]  r5:db5a6d00 r4:dc727aa0
[   64.918887] [<bf396b1c>] (wl1271_op_add_interface [wlcore]) from [<bf2f9fe0>] (drv_add_interface+0x34/0x80 [mac80211])
[   64.935169]  r10:db5a6a00 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a6420 r5:dc7274e0
[   64.949035]  r4:dc7274e0
[   64.952742] [<bf2f9fac>] (drv_add_interface [mac80211]) from [<bf328f44>] (ieee80211_reconfig+0x164/0xc0c [mac80211])
[   64.968580]  r4:db5a6420 r3:00000001
[   64.973279] [<bf328de0>] (ieee80211_reconfig [mac80211]) from [<bf2f8354>] (ieee80211_restart_work+0x90/0xbc [mac80211])
[   64.994171]  r10:00000000 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a6420 r5:db5a6a00
[   65.002067]  r4:db5a6a00
[   65.010091] [<bf2f82c4>] (ieee80211_restart_work [mac80211]) from [<c013f128>] (process_one_work+0x12c/0x374)
[   65.026590]  r7:dcb39400 r6:c0d0ea60 r5:db5a6c28 r4:dc031180
[   65.032348] [<c013effc>] (process_one_work) from [<c013f570>] (worker_thread+0x1c0/0x5b8)
[   65.045963]  r10:00000008 r9:c0d0ea60 r8:c0d16380 r7:dc031198 r6:c0d0ea74 r5:c0d0ea60
[   65.059710]  r4:dc031180
[   65.062336] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11c/0x154)
[   65.074803]  r10:c013f3b0 r9:dc04fe9c r8:dc031180 r7:dc030658 r6:dc030600 r5:00000000
[   65.082708]  r4:dc030640 r3:00000000
[   65.095591] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14/0x2c)
[   65.102898]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0145150
[   65.115719]  r4:dc030600 r3:ffffffff
[   66.839684] ------------[ cut here ]------------
[   66.844563] WARNING: CPU: 0 PID: 3 at drivers/net/wireless/ti/wlcore/sdio.c:145 wl12xx_sdio_raw_write+0xb4/0x138 [wlcore_sdio]
[   66.861361] Modules linked in: usb_f_acm u_serial arc4 pru_rproc pruss_intc wl18xx usb_f_ecm wlcore musb_dsps mac80211 musb_hdrc cfg80211 pruss phy_am335x usbcore phy_generic phy_am335x_control xfrm_user xfrm4_tunnel ipcomp xfrm_ipcomp esp4 ah4 af_key xfrm_algo g_multi usb_f_mass_storage usb_f_rndis u_ether libcomposite udc_core usb_common bluetooth ecdh_generic snd_soc_simple_card snd_soc_simple_card_utils wkup_m3_rproc pm33xx wkup_m3_ipc remoteproc omap_aes_driver crypto_engine omap_crypto omap_sham ti_emif_sram pruss_soc_bus wlcore_sdio rtc_omap musb_am335x omap_wdt sch_fq_codel
[   66.928850] CPU: 0 PID: 3 Comm: kworker/0:0 Tainted: G        W       4.14.40-01413-g36a61bea-dirty #105
[   66.942559] Hardware name: Generic AM33XX (Flattened Device Tree)
[   66.953446] Workqueue: events_freezable ieee80211_restart_work [mac80211]
[   66.960627] Backtrace:
[   66.968163] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+0x18/0x1c)
[   66.981969]  r6:00000000 r5:bf024b00 r4:00000000 r3:00000000
[   66.991481] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20/0x28)
[   67.002560] [<c0805db0>] (dump_stack) from [<c01287bc>] (__warn+0xdc/0x104)
[   67.013807] [<c01286e0>] (__warn) from [<c012880c>] (warn_slowpath_null+0x28/0x30)
[   67.021460]  r10:00000000 r8:00000004 r7:db7fc200 r6:db245810 r5:0001ffc4 r4:dc58ca00
[   67.034435] [<c01287e4>] (warn_slowpath_null) from [<bf023324>] (wl12xx_sdio_raw_write+0xb4/0x138 [wlcore_sdio])
[   67.051044] [<bf023270>] (wl12xx_sdio_raw_write [wlcore_sdio]) from [<bf39db0c>] (wlcore_set_partition+0xcc/0x50c [wlcore])
[   67.066297]  r10:00000000 r8:dc727bc8 r7:00000000 r6:bf3b3c40 r5:bf3dc064 r4:db5a6d00
[   67.078668] [<bf39da40>] (wlcore_set_partition [wlcore]) from [<bf39015c>] (wl12xx_set_power_on+0x90/0x164 [wlcore])
[   67.093422]  r7:bf3b3c40 r6:db5a6d38 r5:00000000 r4:db5a6d00
[   67.099581] [<bf3900cc>] (wl12xx_set_power_on [wlcore]) from [<bf397160>] (wl1271_op_add_interface+0x644/0x950 [wlcore])
[   67.115910]  r5:db5a6d00 r4:ffffff92
[   67.120529] [<bf396b1c>] (wl1271_op_add_interface [wlcore]) from [<bf2f9fe0>] (drv_add_interface+0x34/0x80 [mac80211])
[   67.140965]  r10:db5a6a00 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a6420 r5:dc7274e0
[   67.152812]  r4:dc7274e0
[   67.160260] [<bf2f9fac>] (drv_add_interface [mac80211]) from [<bf328f44>] (ieee80211_reconfig+0x164/0xc0c [mac80211])
[   67.175659]  r4:db5a6420 r3:00000001
[   67.180363] [<bf328de0>] (ieee80211_reconfig [mac80211]) from [<bf2f8354>] (ieee80211_restart_work+0x90/0xbc [mac80211])
[   67.196643]  r10:00000000 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a6420 r5:db5a6a00
[   67.210562]  r4:db5a6a00
[   67.217633] [<bf2f82c4>] (ieee80211_restart_work [mac80211]) from [<c013f128>] (process_one_work+0x12c/0x374)
[   67.231776]  r7:dcb39400 r6:c0d0ea60 r5:db5a6c28 r4:dc031180
[   67.241634] [<c013effc>] (process_one_work) from [<c013f570>] (worker_thread+0x1c0/0x5b8)
[   67.253848]  r10:00000008 r9:c0d0ea60 r8:c0d16380 r7:dc031198 r6:c0d0ea74 r5:c0d0ea60
[   67.261747]  r4:dc031180
[   67.269183] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11c/0x154)
[   67.282565]  r10:c013f3b0 r9:dc04fe9c r8:dc031180 r7:dc030658 r6:dc030600 r5:00000000
[   67.294532]  r4:dc030640 r3:00000000
[   67.298212] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14/0x2c)
[   67.310193]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0145150
[   67.324496]  r4:dc030600 r3:ffffffff
[   67.328127] ---[ end trace 06c90d424e072157 ]---
[   67.332801] wl1271_sdio mmc1:0001:2: sdio write failed (-110)
[   67.343419] mmc mmc1:0001: wl12xx_sdio_power_off: wlcore write did not yet complete?
[   67.351251] CPU: 0 PID: 3 Comm: kworker/0:0 Tainted: G        W       4.14.40-01413-g36a61bea-dirty #105
[   67.378058] Hardware name: Generic AM33XX (Flattened Device Tree)
[   67.388937] Workqueue: events_freezable ieee80211_restart_work [mac80211]
[   67.400047] Backtrace:
[   67.402618] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+0x18/0x1c)
[   67.415557]  r6:db5a6d38 r5:dc5ad008 r4:00000000 r3:00000000
[   67.421327] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20/0x28)
[   67.437885] [<c0805db0>] (dump_stack) from [<bf023258>] (wl12xx_sdio_set_power+0x140/0x158 [wlcore_sdio])
[   67.451892] [<bf023118>] (wl12xx_sdio_set_power [wlcore_sdio]) from [<bf390204>] (wl12xx_set_power_on+0x138/0x164 [wlcore])
[   67.467074]  r7:bf3b3c40 r6:db5a6d38 r5:ffffff92 r4:db5a6d00
[   67.473232] [<bf3900cc>] (wl12xx_set_power_on [wlcore]) from [<bf397160>] (wl1271_op_add_interface+0x644/0x950 [wlcore])
[   67.491756]  r5:db5a6d00 r4:ffffff92
[   67.500162] [<bf396b1c>] (wl1271_op_add_interface [wlcore]) from [<bf2f9fe0>] (drv_add_interface+0x34/0x80 [mac80211])
[   67.515502]  r10:db5a6a00 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a6420 r5:dc7274e0
[   67.527255]  r4:dc7274e0
[   67.530956] [<bf2f9fac>] (drv_add_interface [mac80211]) from [<bf328f44>] (ieee80211_reconfig+0x164/0xc0c [mac80211])
[   67.547152]  r4:db5a6420 r3:00000001
[   67.551854] [<bf328de0>] (ieee80211_reconfig [mac80211]) from [<bf2f8354>] (ieee80211_restart_work+0x90/0xbc [mac80211])
[   67.572462]  r10:00000000 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a6420 r5:db5a6a00
[   67.584507]  r4:db5a6a00
[   67.587806] [<bf2f82c4>] (ieee80211_restart_work [mac80211]) from [<c013f128>] (process_one_work+0x12c/0x374)
[   67.605215]  r7:dcb39400 r6:c0d0ea60 r5:db5a6c28 r4:dc031180
[   67.610986] [<c013effc>] (process_one_work) from [<c013f570>] (worker_thread+0x1c0/0x5b8)
[   67.629039]  r10:00000008 r9:c0d0ea60 r8:c0d16380 r7:dc031198 r6:c0d0ea74 r5:c0d0ea60
[   67.640701]  r4:dc031180
[   67.647253] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11c/0x154)
[   67.658699]  r10:c013f3b0 r9:dc04fe9c r8:dc031180 r7:dc030658 r6:dc030600 r5:00000000
[   67.670355]  r4:dc030640 r3:00000000
[   67.677815] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14/0x2c)
[   67.688918]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0145150
[   67.700531]  r4:dc030600 r3:ffffffff
[   69.429476] ------------[ cut here ]------------
[   69.434355] WARNING: CPU: 0 PID: 3 at drivers/net/wireless/ti/wlcore/sdio.c:145 wl12xx_sdio_raw_write+0xb4/0x138 [wlcore_sdio]
[   69.451344] Modules linked in: usb_f_acm u_serial arc4 pru_rproc pruss_intc wl18xx usb_f_ecm wlcore musb_dsps mac80211 musb_hdrc cfg80211 pruss phy_am335x usbcore phy_generic phy_am335x_control xfrm_user xfrm4_tunnel ipcomp xfrm_ipcomp esp4 ah4 af_key xfrm_algo g_multi usb_f_mass_storage usb_f_rndis u_ether libcomposite udc_core usb_common bluetooth ecdh_generic snd_soc_simple_card snd_soc_simple_card_utils wkup_m3_rproc pm33xx wkup_m3_ipc remoteproc omap_aes_driver crypto_engine omap_crypto omap_sham ti_emif_sram pruss_soc_bus wlcore_sdio rtc_omap musb_am335x omap_wdt sch_fq_codel
[   69.518879] CPU: 0 PID: 3 Comm: kworker/0:0 Tainted: G        W       4.14.40-01413-g36a61bea-dirty #105
[   69.532530] Hardware name: Generic AM33XX (Flattened Device Tree)
[   69.543540] Workqueue: events_freezable ieee80211_restart_work [mac80211]
[   69.550718] Backtrace:
[   69.558381] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+0x18/0x1c)
[   69.572307]  r6:00000000 r5:bf024b00 r4:00000000 r3:00000000
[   69.581846] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20/0x28)
[   69.593360] [<c0805db0>] (dump_stack) from [<c01287bc>] (__warn+0xdc/0x104)
[   69.600478] [<c01286e0>] (__warn) from [<c012880c>] (warn_slowpath_null+0x28/0x30)
[   69.612769]  r10:00000000 r8:00000004 r7:db7fc200 r6:db245810 r5:0001ffc4 r4:dc58ca00
[   69.626945] [<c01287e4>] (warn_slowpath_null) from [<bf023324>] (wl12xx_sdio_raw_write+0xb4/0x138 [wlcore_sdio])
[   69.641383] [<bf023270>] (wl12xx_sdio_raw_write [wlcore_sdio]) from [<bf39db0c>] (wlcore_set_partition+0xcc/0x50c [wlcore])
[   69.656809]  r10:00000000 r8:dc727bc8 r7:00000000 r6:bf3b3c40 r5:bf3dc064 r4:db5a6d00
[   69.668932] [<bf39da40>] (wlcore_set_partition [wlcore]) from [<bf39015c>] (wl12xx_set_power_on+0x90/0x164 [wlcore])
[   69.683503]  r7:bf3b3c40 r6:db5a6d38 r5:00000000 r4:db5a6d00
[   69.689907] [<bf3900cc>] (wl12xx_set_power_on [wlcore]) from [<bf397160>] (wl1271_op_add_interface+0x644/0x950 [wlcore])
[   69.706166]  r5:db5a6d00 r4:ffffff92
[   69.710781] [<bf396b1c>] (wl1271_op_add_interface [wlcore]) from [<bf2f9fe0>] (drv_add_interface+0x34/0x80 [mac80211])
[   69.731566]  r10:db5a6a00 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a6420 r5:dc7274e0
[   69.743519]  r4:dc7274e0
[   69.747317] [<bf2f9fac>] (drv_add_interface [mac80211]) from [<bf328f44>] (ieee80211_reconfig+0x164/0xc0c [mac80211])
[   69.763281]  r4:db5a6420 r3:00000001
[   69.767976] [<bf328de0>] (ieee80211_reconfig [mac80211]) from [<bf2f8354>] (ieee80211_restart_work+0x90/0xbc [mac80211])
[   69.788733]  r10:00000000 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a6420 r5:db5a6a00
[   69.800487]  r4:db5a6a00
[   69.807663] [<bf2f82c4>] (ieee80211_restart_work [mac80211]) from [<c013f128>] (process_one_work+0x12c/0x374)
[   69.821891]  r7:dcb39400 r6:c0d0ea60 r5:db5a6c28 r4:dc031180
[   69.831594] [<c013effc>] (process_one_work) from [<c013f570>] (worker_thread+0x1c0/0x5b8)
[   69.843909]  r10:00000008 r9:c0d0ea60 r8:c0d16380 r7:dc031198 r6:c0d0ea74 r5:c0d0ea60
[   69.851807]  r4:dc031180
[   69.859227] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11c/0x154)
[   69.872667]  r10:c013f3b0 r9:dc04fe9c r8:dc031180 r7:dc030658 r6:dc030600 r5:00000000
[   69.884690]  r4:dc030640 r3:00000000
[   69.888375] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14/0x2c)
[   69.900364]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0145150
[   69.914592]  r4:dc030600 r3:ffffffff
[   69.918222] ---[ end trace 06c90d424e072158 ]---
[   69.922897] wl1271_sdio mmc1:0001:2: sdio write failed (-110)
[   69.933405] mmc mmc1:0001: wl12xx_sdio_power_off: wlcore write did not yet complete?
[   69.941243] CPU: 0 PID: 3 Comm: kworker/0:0 Tainted: G        W       4.14.40-01413-g36a61bea-dirty #105
[   69.968249] Hardware name: Generic AM33XX (Flattened Device Tree)
[   69.979069] Workqueue: events_freezable ieee80211_restart_work [mac80211]
[   69.990223] Backtrace:
[   69.992794] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+0x18/0x1c)
[   70.005750]  r6:db5a6d38 r5:dc5ad008 r4:00000000 r3:00000000
[   70.011527] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20/0x28)
[   70.028035] [<c0805db0>] (dump_stack) from [<bf023258>] (wl12xx_sdio_set_power+0x140/0x158 [wlcore_sdio])
[   70.041927] [<bf023118>] (wl12xx_sdio_set_power [wlcore_sdio]) from [<bf390204>] (wl12xx_set_power_on+0x138/0x164 [wlcore])
[   70.057178]  r7:bf3b3c40 r6:db5a6d38 r5:ffffff92 r4:db5a6d00
[   70.063333] [<bf3900cc>] (wl12xx_set_power_on [wlcore]) from [<bf397160>] (wl1271_op_add_interface+0x644/0x950 [wlcore])
[   70.081996]  r5:db5a6d00 r4:ffffff92
[   70.090340] [<bf396b1c>] (wl1271_op_add_interface [wlcore]) from [<bf2f9fe0>] (drv_add_interface+0x34/0x80 [mac80211])
[   70.105745]  r10:db5a6a00 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a6420 r5:dc7274e0
[   70.117490]  r4:dc7274e0
[   70.121197] [<bf2f9fac>] (drv_add_interface [mac80211]) from [<bf328f44>] (ieee80211_reconfig+0x164/0xc0c [mac80211])
[   70.137336]  r4:db5a6420 r3:00000001
[   70.142045] [<bf328de0>] (ieee80211_reconfig [mac80211]) from [<bf2f8354>] (ieee80211_restart_work+0x90/0xbc [mac80211])
[   70.162550]  r10:00000000 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a6420 r5:db5a6a00
[   70.174625]  r4:db5a6a00
[   70.177923] [<bf2f82c4>] (ieee80211_restart_work [mac80211]) from [<c013f128>] (process_one_work+0x12c/0x374)
[   70.193199]  r7:dcb39400 r6:c0d0ea60 r5:db5a6c28 r4:dc031180
[   70.198959] [<c013effc>] (process_one_work) from [<c013f570>] (worker_thread+0x1c0/0x5b8)
[   70.217151]  r10:00000008 r9:c0d0ea60 r8:c0d16380 r7:dc031198 r6:c0d0ea74 r5:c0d0ea60
[   70.228862]  r4:dc031180
[   70.231489] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11c/0x154)
[   70.243312]  r10:c013f3b0 r9:dc04fe9c r8:dc031180 r7:dc030658 r6:dc030600 r5:00000000
[   70.251212]  r4:dc030640 r3:00000000
[   70.265017] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14/0x2c)
[   70.272321]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0145150
[   70.285370]  r4:dc030600 r3:ffffffff
[   70.289003] wlcore: ERROR firmware boot failed despite 3 retries
[   70.304327] ------------[ cut here ]------------
[   70.309755] WARNING: CPU: 0 PID: 3 at net/mac80211/util.c:1902 ieee80211_reconfig+0x17c/0xc0c [mac80211]
[   70.323490] Modules linked in: usb_f_acm u_serial arc4 pru_rproc pruss_intc wl18xx usb_f_ecm wlcore musb_dsps mac80211 musb_hdrc cfg80211 pruss phy_am335x usbcore phy_generic phy_am335x_control xfrm_user xfrm4_tunnel ipcomp xfrm_ipcomp esp4 ah4 af_key xfrm_algo g_multi usb_f_mass_storage usb_f_rndis u_ether libcomposite udc_core usb_common bluetooth ecdh_generic snd_soc_simple_card snd_soc_simple_card_utils wkup_m3_rproc pm33xx wkup_m3_ipc remoteproc omap_aes_driver crypto_engine omap_crypto omap_sham ti_emif_sram pruss_soc_bus wlcore_sdio rtc_omap musb_am335x omap_wdt sch_fq_codel
[   70.392540] CPU: 0 PID: 3 Comm: kworker/0:0 Tainted: G        W       4.14.40-01413-g36a61bea-dirty #105
[   70.406641] Hardware name: Generic AM33XX (Flattened Device Tree)
[   70.413537] Workqueue: events_freezable ieee80211_restart_work [mac80211]
[   70.424850] Backtrace:
[   70.427396] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+0x18/0x1c)
[   70.440543]  r6:00000000 r5:bf3494ac r4:00000000 r3:00000000
[   70.452546] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20/0x28)
[   70.466545] [<c0805db0>] (dump_stack) from [<c01287bc>] (__warn+0xdc/0x104)
[   70.477427] [<c01286e0>] (__warn) from [<c012880c>] (warn_slowpath_null+0x28/0x30)
[   70.488858]  r10:db5a6a00 r8:ffffff92 r7:db5a6420 r6:db5a6420 r5:dc7274e0 r4:db5a6420
[   70.501458] [<c01287e4>] (warn_slowpath_null) from [<bf328f5c>] (ieee80211_reconfig+0x17c/0xc0c [mac80211])
[   70.516702] [<bf328de0>] (ieee80211_reconfig [mac80211]) from [<bf2f8354>] (ieee80211_restart_work+0x90/0xbc [mac80211])
[   70.531935]  r10:00000000 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a6420 r5:db5a6a00
[   70.543840]  r4:db5a6a00
[   70.547122] [<bf2f82c4>] (ieee80211_restart_work [mac80211]) from [<c013f128>] (process_one_work+0x12c/0x374)
[   70.562592]  r7:dcb39400 r6:c0d0ea60 r5:db5a6c28 r4:dc031180
[   70.574711] [<c013effc>] (process_one_work) from [<c013f570>] (worker_thread+0x1c0/0x5b8)
[   70.586858]  r10:00000008 r9:c0d0ea60 r8:c0d16380 r7:dc031198 r6:c0d0ea74 r5:c0d0ea60
[   70.594931]  r4:dc031180
[   70.597541] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11c/0x154)
[   70.610248]  r10:c013f3b0 r9:dc04fe9c r8:dc031180 r7:dc030658 r6:dc030600 r5:00000000
[   70.627088]  r4:dc030640 r3:00000000
[   70.630774] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14/0x2c)
[   70.642831]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0145150
[   70.657197]  r4:dc030600 r3:ffffffff
[   70.660830] ---[ end trace 06c90d424e072159 ]---
[   70.677592] ------------[ cut here ]------------
[   70.683361] WARNING: CPU: 0 PID: 3 at net/mac80211/driver-ops.h:18 drv_remove_interface+0x64/0x70 [mac80211]
[   70.699764] wlan0:  Failed check-sdata-in-driver check, flags: 0x0
[   70.707634] Modules linked in: usb_f_acm u_serial arc4 pru_rproc pruss_intc wl18xx usb_f_ecm wlcore musb_dsps mac80211 musb_hdrc cfg80211 pruss phy_am335x usbcore phy_generic phy_am335x_control xfrm_user xfrm4_tunnel ipcomp xfrm_ipcomp esp4 ah4 af_key xfrm_algo g_multi usb_f_mass_storage usb_f_rndis u_ether libcomposite udc_core usb_common bluetooth ecdh_generic snd_soc_simple_card snd_soc_simple_card_utils wkup_m3_rproc pm33xx wkup_m3_ipc remoteproc omap_aes_driver crypto_engine omap_crypto omap_sham ti_emif_sram pruss_soc_bus wlcore_sdio rtc_omap musb_am335x omap_wdt sch_fq_codel
[   70.764973] CPU: 0 PID: 3 Comm: kworker/0:0 Tainted: G        W       4.14.40-01413-g36a61bea-dirty #105
[   70.776384] Hardware name: Generic AM33XX (Flattened Device Tree)
[   70.782902] Workqueue: events_freezable ieee80211_restart_work [mac80211]
[   70.792756] Backtrace:
[   70.796872] [<c010baf8>] (dump_backtrace) from [<c010bd5c>] (show_stack+0x18/0x1c)
[   70.806114]  r6:00000000 r5:bf348224 r4:dc05dd68 r3:00000000
[   70.811835] [<c010bd44>] (show_stack) from [<c0805dd0>] (dump_stack+0x20/0x28)
[   70.821797] [<c0805db0>] (dump_stack) from [<c01287bc>] (__warn+0xdc/0x104)
[   70.830440] [<c01286e0>] (__warn) from [<c012889c>] (warn_slowpath_fmt+0x40/0x48)
[   70.839599]  r10:db5a6420 r8:00000000 r7:00000000 r6:db5a6a28 r5:dc7274e0 r4:00000000
[   70.849459] [<c0128860>] (warn_slowpath_fmt) from [<bf2fa0f4>] (drv_remove_interface+0x64/0x70 [mac80211])
[   70.861026]  r3:dc727000 r2:bf348240
[   70.866248]  r4:dc7274e0
[   70.869282] [<bf2fa090>] (drv_remove_interface [mac80211]) from [<bf30c0dc>] (ieee80211_do_stop+0x7d4/0x8dc [mac80211])
[   70.883184]  r4:db5a698c
[   70.886246] [<bf30b908>] (ieee80211_do_stop [mac80211]) from [<bf30c1fc>] (ieee80211_stop+0x18/0x20 [mac80211])
[   70.899279]  r10:db5a6a00 r9:c0d0ea60 r8:dc05de58 r7:00000001 r6:db5a6000 r5:dc05de58
[   70.908837]  r4:dc727000
[   70.911754] [<bf30c1e4>] (ieee80211_stop [mac80211]) from [<c06e62f0>] (__dev_close_many+0x90/0xd0)
[   70.923892] [<c06e6260>] (__dev_close_many) from [<c06e63a4>] (dev_close_many+0x74/0xf0)
[   70.932029]  r5:db5a63e8 r4:dc7274e8
[   70.938308] [<c06e6330>] (dev_close_many) from [<c06e88c0>] (dev_close+0x44/0x5c)
[   70.947444]  r8:ffffff92 r7:db5a6420 r6:db5a6000 r5:db5a63e8 r4:dc7274e8 r3:dc727000
[   70.957120] [<c06e887c>] (dev_close) from [<bf26cb18>] (cfg80211_shutdown_all_interfaces+0x3c/0xc0 [cfg80211])
[   70.969490] [<bf26cadc>] (cfg80211_shutdown_all_interfaces [cfg80211]) from [<bf326c14>] (ieee80211_handle_reconfig_failure+0xcc/0xd0 [mac80211])
[   70.984618]  r6:db5a6420 r5:db5a6b10 r4:db5a6420 r3:db5a6b08
[   70.990774] [<bf326b48>] (ieee80211_handle_reconfig_failure [mac80211]) from [<bf329128>] (ieee80211_reconfig+0x348/0xc0c [mac80211])
[   71.005701]  r5:db5a6a00 r4:db5a6420
[   71.009760] [<bf328de0>] (ieee80211_reconfig [mac80211]) from [<bf2f8354>] (ieee80211_restart_work+0x90/0xbc [mac80211])
[   71.023910]  r10:00000000 r9:c0d0ea60 r8:00000000 r7:db5a6420 r6:db5a6420 r5:db5a6a00
[   71.031785]  r4:db5a6a00
[   71.037253] [<bf2f82c4>] (ieee80211_restart_work [mac80211]) from [<c013f128>] (process_one_work+0x12c/0x374)
[   71.049089]  r7:dcb39400 r6:c0d0ea60 r5:db5a6c28 r4:dc031180
[   71.056485] [<c013effc>] (process_one_work) from [<c013f570>] (worker_thread+0x1c0/0x5b8)
[   71.066280]  r10:00000008 r9:c0d0ea60 r8:c0d16380 r7:dc031198 r6:c0d0ea74 r5:c0d0ea60
[   71.075666]  r4:dc031180
[   71.078241] [<c013f3b0>] (worker_thread) from [<c014526c>] (kthread+0x11c/0x154)
[   71.088235]  r10:c013f3b0 r9:dc04fe9c r8:dc031180 r7:dc030658 r6:dc030600 r5:00000000
[   71.097655]  r4:dc030640 r3:00000000
[   71.101282] [<c0145150>] (kthread) from [<c0107f68>] (ret_from_fork+0x14/0x2c)
[   71.111064]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0145150
[   71.120527]  r4:dc030600 r3:ffffffff
[   71.125652] ---[ end trace 06c90d424e07215a ]---

root@am335x-evm:~# ifconfig wlan0 down
root@am335x-evm:~# ifconfig wlan0 up
[  590.896452] wlcore: PHY firmware version: Rev 8.2.0.0.242
[  591.017507] wlcore: firmware booted (Rev 8.9.0.0.78)
[  591.109143] IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
root@am335x-evm:~#

Regards,
Eyal

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-22  8:02       ` Kalle Valo
  0 siblings, 0 replies; 46+ messages in thread
From: Kalle Valo @ 2018-05-22  8:02 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Reizer, Eyal, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho,
	Hahn, Maital, Altshul, Maxim, Shahar Patury, linux-wireless,
	linux-omap, Loewy, Chen

Tony Lindgren <tony@atomide.com> writes:

> * Reizer, Eyal <eyalr@ti.com> [180521 07:31]:
>> > Here's a series of patches to add runtime PM support for wlcore. It does not
>> > yet implement autosuspend support, but let's get this tested first as the
>> > autosuspend can mask enable/disable issues easily.
>> 
>> Testing on BBB+WL1837 cape, scan, recovery, down/up and basic traffic seems ok now.
>> Of course we need to test some more.
>
> Thanks for testing. Yes let's do more testing, no rush with these.
> Hopefully they'll be ready for v4.19 merge window though.

So I can drop the patchset now and you will resend once it's ready?

-- 
Kalle Valo

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-22  8:02       ` Kalle Valo
  0 siblings, 0 replies; 46+ messages in thread
From: Kalle Valo @ 2018-05-22  8:02 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Reizer, Eyal, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho,
	Hahn, Maital, Altshul, Maxim, Shahar Patury,
	linux-wireless@vger.kernel.org, linux-omap@vger.kernel.org,
	Loewy, Chen

Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> writes:

> * Reizer, Eyal <eyalr-l0cyMroinI0@public.gmane.org> [180521 07:31]:
>> > Here's a series of patches to add runtime PM support for wlcore. It does not
>> > yet implement autosuspend support, but let's get this tested first as the
>> > autosuspend can mask enable/disable issues easily.
>> 
>> Testing on BBB+WL1837 cape, scan, recovery, down/up and basic traffic seems ok now.
>> Of course we need to test some more.
>
> Thanks for testing. Yes let's do more testing, no rush with these.
> Hopefully they'll be ready for v4.19 merge window though.

So I can drop the patchset now and you will resend once it's ready?

-- 
Kalle Valo

^ permalink raw reply	[flat|nested] 46+ messages in thread

* RE: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
  2018-05-21 22:43       ` Tony Lindgren
@ 2018-05-22 13:26         ` Reizer, Eyal
  -1 siblings, 0 replies; 46+ messages in thread
From: Reizer, Eyal @ 2018-05-22 13:26 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Kalle Valo, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn,
	Maital, Altshul, Maxim, Shahar Patury, linux-wireless,
	linux-omap, Loewy, Chen

> >
> > 8< ------------------------
> > 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
> > @@ -1867,8 +1867,6 @@ static int __maybe_unused
> > wl1271_op_resume(struct ieee80211_hw *hw)
> >  			if (ret)
> >  				wl12xx_queue_recovery_work(wl);
> >  		}
> > -
> > -		wlcore_enable_interrupts(wl);
> >  	}
> >
> >  	if (pending_recovery) {
> > @@ -1877,6 +1875,8 @@ static int __maybe_unused
> > wl1271_op_resume(struct ieee80211_hw *hw)
> >  		goto out_sleep;
> >  	}
> >
> > +	wlcore_enable_interrupts(wl);
> > +
> >  	ret =3D pm_runtime_get_sync(wl->dev);
> >  	if (ret < 0) {
> >  		pm_runtime_put_noidle(wl->dev);
>=20
> It still crash.
> The crash is different now.
> It also complains about:
> [   60.544224] Unbalanced enable for IRQ 65
> Need down/up of the interface to recover after it.
> Log below:
>=20

Actually the below patch removing the call to wlcore_fw_sleep() avoids this=
 error.
The downside is that the wl8 firmware remains fully active during supend, s=
o we
Would need to find the root cause why the last call allowing the wilink8 fi=
rmware=20
To go into ELP mode during suspend is only completing on resume and not dur=
ing
Suspend enter.

diff --git a/drivers/net/wireless/ti/wlcore/main.c
b/drivers/net/wireless/ti/wlcore/main.c
index 4c297aa..8df1ae6 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -1789,7 +1789,6 @@ static int 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) {
@@ -1821,15 +1820,7 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw=
,
         */
        cancel_delayed_work(&wl->tx_watchdog_work);

-       /*
-        * Use an immediate call for allowing the firmware to go into power
-        * save during suspend.
-        * Using a workque for this last write was only hapenning on resume
-        * leaving the firmware with power save disabled during suspend,
-        * while consuming full power during wowlan suspend.
-        */
-       wlcore_fw_sleep(wl);
-
+       pm_runtime_put_noidle(wl->dev);
        return 0;
 }

With this wowlan seems to work ok and suspend/resume is not crashing when=20
enabling wowlan. See below:

root@am335x-evm:/usr/share/wl18xx#
root@am335x-evm:/usr/share/wl18xx#
root@am335x-evm:/usr/share/wl18xx#
root@am335x-evm:/usr/share/wl18xx# iw phy0 wowlan enable any
root@am335x-evm:/usr/share/wl18xx#
root@am335x-evm:/usr/share/wl18xx# echo mem > /sys/power/state
[   63.794805] PM: suspend entry (deep)
[   63.798455] PM: Syncing filesystems ... done.
[   65.779673] Freezing user space processes ... (elapsed 0.001 seconds) do=
ne.
[   65.788878] OOM killer disabled.
[   65.792117] Freezing remaining freezable tasks ... (elapsed 0.001 second=
s) done.
[   65.801196] Suspending console(s) (use no_console_suspend to debug)
[   65.952459] pm33xx pm33xx: PM: Successfully put all powerdomains to targ=
et state
[   65.952459] PM: Wakeup source GPIO0
[   65.977028] net eth0: initializing cpsw version 1.12 (0)
[   66.074419] SMSC LAN8710/LAN8720 4a101000.mdio:00: attached PHY driver [=
SMSC LAN8710/LAN8720] (mii_bus:phy_addr=3D4a101000.mdio:00, irq=3DPOLL)
[   66.236312] OOM killer enabled.
[   66.239604] Restarting tasks ... done.
[   66.282501] PM: suspend exit
root@am335x-evm:/usr/share/wl18xx#

BR,
Eyal

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* RE: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-22 13:26         ` Reizer, Eyal
  0 siblings, 0 replies; 46+ messages in thread
From: Reizer, Eyal @ 2018-05-22 13:26 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Kalle Valo, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn,
	Maital, Altshul, Maxim, Shahar Patury,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Loewy, Chen

> >
> > 8< ------------------------
> > 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
> > @@ -1867,8 +1867,6 @@ static int __maybe_unused
> > wl1271_op_resume(struct ieee80211_hw *hw)
> >  			if (ret)
> >  				wl12xx_queue_recovery_work(wl);
> >  		}
> > -
> > -		wlcore_enable_interrupts(wl);
> >  	}
> >
> >  	if (pending_recovery) {
> > @@ -1877,6 +1875,8 @@ static int __maybe_unused
> > wl1271_op_resume(struct ieee80211_hw *hw)
> >  		goto out_sleep;
> >  	}
> >
> > +	wlcore_enable_interrupts(wl);
> > +
> >  	ret = pm_runtime_get_sync(wl->dev);
> >  	if (ret < 0) {
> >  		pm_runtime_put_noidle(wl->dev);
> 
> It still crash.
> The crash is different now.
> It also complains about:
> [   60.544224] Unbalanced enable for IRQ 65
> Need down/up of the interface to recover after it.
> Log below:
> 

Actually the below patch removing the call to wlcore_fw_sleep() avoids this error.
The downside is that the wl8 firmware remains fully active during supend, so we
Would need to find the root cause why the last call allowing the wilink8 firmware 
To go into ELP mode during suspend is only completing on resume and not during
Suspend enter.

diff --git a/drivers/net/wireless/ti/wlcore/main.c
b/drivers/net/wireless/ti/wlcore/main.c
index 4c297aa..8df1ae6 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -1789,7 +1789,6 @@ static int 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) {
@@ -1821,15 +1820,7 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
         */
        cancel_delayed_work(&wl->tx_watchdog_work);

-       /*
-        * Use an immediate call for allowing the firmware to go into power
-        * save during suspend.
-        * Using a workque for this last write was only hapenning on resume
-        * leaving the firmware with power save disabled during suspend,
-        * while consuming full power during wowlan suspend.
-        */
-       wlcore_fw_sleep(wl);
-
+       pm_runtime_put_noidle(wl->dev);
        return 0;
 }

With this wowlan seems to work ok and suspend/resume is not crashing when 
enabling wowlan. See below:

root@am335x-evm:/usr/share/wl18xx#
root@am335x-evm:/usr/share/wl18xx#
root@am335x-evm:/usr/share/wl18xx#
root@am335x-evm:/usr/share/wl18xx# iw phy0 wowlan enable any
root@am335x-evm:/usr/share/wl18xx#
root@am335x-evm:/usr/share/wl18xx# echo mem > /sys/power/state
[   63.794805] PM: suspend entry (deep)
[   63.798455] PM: Syncing filesystems ... done.
[   65.779673] Freezing user space processes ... (elapsed 0.001 seconds) done.
[   65.788878] OOM killer disabled.
[   65.792117] Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done.
[   65.801196] Suspending console(s) (use no_console_suspend to debug)
[   65.952459] pm33xx pm33xx: PM: Successfully put all powerdomains to target state
[   65.952459] PM: Wakeup source GPIO0
[   65.977028] net eth0: initializing cpsw version 1.12 (0)
[   66.074419] SMSC LAN8710/LAN8720 4a101000.mdio:00: attached PHY driver [SMSC LAN8710/LAN8720] (mii_bus:phy_addr=4a101000.mdio:00, irq=POLL)
[   66.236312] OOM killer enabled.
[   66.239604] Restarting tasks ... done.
[   66.282501] PM: suspend exit
root@am335x-evm:/usr/share/wl18xx#

BR,
Eyal

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* Re: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-22 13:31           ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-22 13:31 UTC (permalink / raw)
  To: Reizer, Eyal
  Cc: Kalle Valo, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn,
	Maital, Altshul, Maxim, Shahar Patury, linux-wireless,
	linux-omap, Loewy, Chen

* Reizer, Eyal <eyalr@ti.com> [180522 13:28]:
> Actually the below patch removing the call to wlcore_fw_sleep() avoids this error.
> The downside is that the wl8 firmware remains fully active during supend, so we
> Would need to find the root cause why the last call allowing the wilink8 firmware 
> To go into ELP mode during suspend is only completing on resume and not during
> Suspend enter.
> 
> diff --git a/drivers/net/wireless/ti/wlcore/main.c
> b/drivers/net/wireless/ti/wlcore/main.c
> index 4c297aa..8df1ae6 100644
> --- a/drivers/net/wireless/ti/wlcore/main.c
> +++ b/drivers/net/wireless/ti/wlcore/main.c
> @@ -1789,7 +1789,6 @@ static int 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) {
> @@ -1821,15 +1820,7 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
>          */
>         cancel_delayed_work(&wl->tx_watchdog_work);
> 
> -       /*
> -        * Use an immediate call for allowing the firmware to go into power
> -        * save during suspend.
> -        * Using a workque for this last write was only hapenning on resume
> -        * leaving the firmware with power save disabled during suspend,
> -        * while consuming full power during wowlan suspend.
> -        */
> -       wlcore_fw_sleep(wl);
> -
> +       pm_runtime_put_noidle(wl->dev);
>         return 0;
>  }

OK try replacing the pm_runtime_put_noidle() above with just
pm_runtime_put_sync(). The reason why I put noidle there was the
wlcore_fw_sleep() call, with that gone put_sync should do the trick.

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-22 13:31           ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-22 13:31 UTC (permalink / raw)
  To: Reizer, Eyal
  Cc: Kalle Valo, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn,
	Maital, Altshul, Maxim, Shahar Patury,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Loewy, Chen

* Reizer, Eyal <eyalr-l0cyMroinI0@public.gmane.org> [180522 13:28]:
> Actually the below patch removing the call to wlcore_fw_sleep() avoids this error.
> The downside is that the wl8 firmware remains fully active during supend, so we
> Would need to find the root cause why the last call allowing the wilink8 firmware 
> To go into ELP mode during suspend is only completing on resume and not during
> Suspend enter.
> 
> diff --git a/drivers/net/wireless/ti/wlcore/main.c
> b/drivers/net/wireless/ti/wlcore/main.c
> index 4c297aa..8df1ae6 100644
> --- a/drivers/net/wireless/ti/wlcore/main.c
> +++ b/drivers/net/wireless/ti/wlcore/main.c
> @@ -1789,7 +1789,6 @@ static int 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) {
> @@ -1821,15 +1820,7 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
>          */
>         cancel_delayed_work(&wl->tx_watchdog_work);
> 
> -       /*
> -        * Use an immediate call for allowing the firmware to go into power
> -        * save during suspend.
> -        * Using a workque for this last write was only hapenning on resume
> -        * leaving the firmware with power save disabled during suspend,
> -        * while consuming full power during wowlan suspend.
> -        */
> -       wlcore_fw_sleep(wl);
> -
> +       pm_runtime_put_noidle(wl->dev);
>         return 0;
>  }

OK try replacing the pm_runtime_put_noidle() above with just
pm_runtime_put_sync(). The reason why I put noidle there was the
wlcore_fw_sleep() call, with that gone put_sync should do the trick.

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-22 13:37         ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-22 13:37 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Reizer, Eyal, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho,
	Hahn, Maital, Altshul, Maxim, Shahar Patury, linux-wireless,
	linux-omap, Loewy, Chen

* Kalle Valo <kvalo@codeaurora.org> [180522 08:05]:
> Tony Lindgren <tony@atomide.com> writes:
> 
> > * Reizer, Eyal <eyalr@ti.com> [180521 07:31]:
> >> > Here's a series of patches to add runtime PM support for wlcore. It does not
> >> > yet implement autosuspend support, but let's get this tested first as the
> >> > autosuspend can mask enable/disable issues easily.
> >> 
> >> Testing on BBB+WL1837 cape, scan, recovery, down/up and basic traffic seems ok now.
> >> Of course we need to test some more.
> >
> > Thanks for testing. Yes let's do more testing, no rush with these.
> > Hopefully they'll be ready for v4.19 merge window though.
> 
> So I can drop the patchset now and you will resend once it's ready?

Yes thanks I will send at least one more version of this series.

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-22 13:37         ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-22 13:37 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Reizer, Eyal, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho,
	Hahn, Maital, Altshul, Maxim, Shahar Patury,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Loewy, Chen

* Kalle Valo <kvalo-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org> [180522 08:05]:
> Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> writes:
> 
> > * Reizer, Eyal <eyalr-l0cyMroinI0@public.gmane.org> [180521 07:31]:
> >> > Here's a series of patches to add runtime PM support for wlcore. It does not
> >> > yet implement autosuspend support, but let's get this tested first as the
> >> > autosuspend can mask enable/disable issues easily.
> >> 
> >> Testing on BBB+WL1837 cape, scan, recovery, down/up and basic traffic seems ok now.
> >> Of course we need to test some more.
> >
> > Thanks for testing. Yes let's do more testing, no rush with these.
> > Hopefully they'll be ready for v4.19 merge window though.
> 
> So I can drop the patchset now and you will resend once it's ready?

Yes thanks I will send at least one more version of this series.

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* RE: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-22 13:48             ` Reizer, Eyal
  0 siblings, 0 replies; 46+ messages in thread
From: Reizer, Eyal @ 2018-05-22 13:48 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Kalle Valo, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn,
	Maital, Altshul, Maxim, Shahar Patury, linux-wireless,
	linux-omap, Loewy, Chen

>=20
> * Reizer, Eyal <eyalr@ti.com> [180522 13:28]:
> > Actually the below patch removing the call to wlcore_fw_sleep() avoids =
this
> error.
> > The downside is that the wl8 firmware remains fully active during supen=
d, so
> we
> > Would need to find the root cause why the last call allowing the wilink=
8
> firmware
> > To go into ELP mode during suspend is only completing on resume and not
> during
> > Suspend enter.
> >
> > diff --git a/drivers/net/wireless/ti/wlcore/main.c
> > b/drivers/net/wireless/ti/wlcore/main.c
> > index 4c297aa..8df1ae6 100644
> > --- a/drivers/net/wireless/ti/wlcore/main.c
> > +++ b/drivers/net/wireless/ti/wlcore/main.c
> > @@ -1789,7 +1789,6 @@ static int 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) {
> > @@ -1821,15 +1820,7 @@ static int wl1271_op_suspend(struct
> ieee80211_hw *hw,
> >          */
> >         cancel_delayed_work(&wl->tx_watchdog_work);
> >
> > -       /*
> > -        * Use an immediate call for allowing the firmware to go into p=
ower
> > -        * save during suspend.
> > -        * Using a workque for this last write was only hapenning on re=
sume
> > -        * leaving the firmware with power save disabled during suspend=
,
> > -        * while consuming full power during wowlan suspend.
> > -        */
> > -       wlcore_fw_sleep(wl);
> > -
> > +       pm_runtime_put_noidle(wl->dev);
> >         return 0;
> >  }
>=20
> OK try replacing the pm_runtime_put_noidle() above with just
> pm_runtime_put_sync(). The reason why I put noidle there was the
> wlcore_fw_sleep() call, with that gone put_sync should do the trick.
>=20

I have tried that already. Same problem. The last call to:
ret =3D wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_SLEEP)

which allows the firmware to get into ELP state during wowlan suspend is=20
only completing after system resume for some unknown reason...

Best Regards,
Eyal

^ permalink raw reply	[flat|nested] 46+ messages in thread

* RE: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-22 13:48             ` Reizer, Eyal
  0 siblings, 0 replies; 46+ messages in thread
From: Reizer, Eyal @ 2018-05-22 13:48 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Kalle Valo, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn,
	Maital, Altshul, Maxim, Shahar Patury,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Loewy, Chen

> 
> * Reizer, Eyal <eyalr-l0cyMroinI0@public.gmane.org> [180522 13:28]:
> > Actually the below patch removing the call to wlcore_fw_sleep() avoids this
> error.
> > The downside is that the wl8 firmware remains fully active during supend, so
> we
> > Would need to find the root cause why the last call allowing the wilink8
> firmware
> > To go into ELP mode during suspend is only completing on resume and not
> during
> > Suspend enter.
> >
> > diff --git a/drivers/net/wireless/ti/wlcore/main.c
> > b/drivers/net/wireless/ti/wlcore/main.c
> > index 4c297aa..8df1ae6 100644
> > --- a/drivers/net/wireless/ti/wlcore/main.c
> > +++ b/drivers/net/wireless/ti/wlcore/main.c
> > @@ -1789,7 +1789,6 @@ static int 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) {
> > @@ -1821,15 +1820,7 @@ static int wl1271_op_suspend(struct
> ieee80211_hw *hw,
> >          */
> >         cancel_delayed_work(&wl->tx_watchdog_work);
> >
> > -       /*
> > -        * Use an immediate call for allowing the firmware to go into power
> > -        * save during suspend.
> > -        * Using a workque for this last write was only hapenning on resume
> > -        * leaving the firmware with power save disabled during suspend,
> > -        * while consuming full power during wowlan suspend.
> > -        */
> > -       wlcore_fw_sleep(wl);
> > -
> > +       pm_runtime_put_noidle(wl->dev);
> >         return 0;
> >  }
> 
> OK try replacing the pm_runtime_put_noidle() above with just
> pm_runtime_put_sync(). The reason why I put noidle there was the
> wlcore_fw_sleep() call, with that gone put_sync should do the trick.
> 

I have tried that already. Same problem. The last call to:
ret = wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_SLEEP)

which allows the firmware to get into ELP state during wowlan suspend is 
only completing after system resume for some unknown reason...

Best Regards,
Eyal

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-22 13:50           ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-22 13:50 UTC (permalink / raw)
  To: Reizer, Eyal
  Cc: Kalle Valo, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn,
	Maital, Altshul, Maxim, Shahar Patury, linux-wireless,
	linux-omap, Loewy, Chen

* Reizer, Eyal <eyalr@ti.com> [180522 06:42]:
> It still crash.
> The crash is different now.
> It also complains about:
> [   60.544224] Unbalanced enable for IRQ 65
> Need down/up of the interface to recover after it.

Oh OK so no need for this patch and interrupts are already
enabled at that point. Sounds like you found the real reason
with the patch you posted.

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-22 13:50           ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-22 13:50 UTC (permalink / raw)
  To: Reizer, Eyal
  Cc: Kalle Valo, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn,
	Maital, Altshul, Maxim, Shahar Patury,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Loewy, Chen

* Reizer, Eyal <eyalr-l0cyMroinI0@public.gmane.org> [180522 06:42]:
> It still crash.
> The crash is different now.
> It also complains about:
> [   60.544224] Unbalanced enable for IRQ 65
> Need down/up of the interface to recover after it.

Oh OK so no need for this patch and interrupts are already
enabled at that point. Sounds like you found the real reason
with the patch you posted.

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-22 13:55               ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-22 13:55 UTC (permalink / raw)
  To: Reizer, Eyal
  Cc: Kalle Valo, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn,
	Maital, Altshul, Maxim, Shahar Patury, linux-wireless,
	linux-omap, Loewy, Chen

* Reizer, Eyal <eyalr@ti.com> [180522 13:50]:
> > 
> > OK try replacing the pm_runtime_put_noidle() above with just
> > pm_runtime_put_sync(). The reason why I put noidle there was the
> > wlcore_fw_sleep() call, with that gone put_sync should do the trick.
> > 
> 
> I have tried that already. Same problem. The last call to:
> ret = wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_SLEEP)
> 
> which allows the firmware to get into ELP state during wowlan suspend is 
> only completing after system resume for some unknown reason...

Hmm maybe try also adding wl1271_power_off(wl) after put_sync()?

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-22 13:55               ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-22 13:55 UTC (permalink / raw)
  To: Reizer, Eyal
  Cc: Kalle Valo, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn,
	Maital, Altshul, Maxim, Shahar Patury,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Loewy, Chen

* Reizer, Eyal <eyalr-l0cyMroinI0@public.gmane.org> [180522 13:50]:
> > 
> > OK try replacing the pm_runtime_put_noidle() above with just
> > pm_runtime_put_sync(). The reason why I put noidle there was the
> > wlcore_fw_sleep() call, with that gone put_sync should do the trick.
> > 
> 
> I have tried that already. Same problem. The last call to:
> ret = wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_SLEEP)
> 
> which allows the firmware to get into ELP state during wowlan suspend is 
> only completing after system resume for some unknown reason...

Hmm maybe try also adding wl1271_power_off(wl) after put_sync()?

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* RE: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-22 14:05                 ` Reizer, Eyal
  0 siblings, 0 replies; 46+ messages in thread
From: Reizer, Eyal @ 2018-05-22 14:05 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Kalle Valo, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn,
	Maital, Altshul, Maxim, linux-wireless, linux-omap, Loewy, Chen

> > >
> > > OK try replacing the pm_runtime_put_noidle() above with just
> > > pm_runtime_put_sync(). The reason why I put noidle there was the
> > > wlcore_fw_sleep() call, with that gone put_sync should do the trick.
> > >
> >
> > I have tried that already. Same problem. The last call to:
> > ret =3D wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_SLEEP)
> >
> > which allows the firmware to get into ELP state during wowlan suspend i=
s
> > only completing after system resume for some unknown reason...
>=20
> Hmm maybe try also adding wl1271_power_off(wl) after put_sync()?
>=20

No, we don't want to power off the chip in wowlan mode.
We power it of only during standard suspend.

The trick is that it stays on during suspend and can be used=20
As a wakeup source to the host on specific packets received by
The firmware over the air.

BR,
Eyal

^ permalink raw reply	[flat|nested] 46+ messages in thread

* RE: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-22 14:05                 ` Reizer, Eyal
  0 siblings, 0 replies; 46+ messages in thread
From: Reizer, Eyal @ 2018-05-22 14:05 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Kalle Valo, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn,
	Maital, Altshul, Maxim, linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Loewy, Chen

> > >
> > > OK try replacing the pm_runtime_put_noidle() above with just
> > > pm_runtime_put_sync(). The reason why I put noidle there was the
> > > wlcore_fw_sleep() call, with that gone put_sync should do the trick.
> > >
> >
> > I have tried that already. Same problem. The last call to:
> > ret = wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_SLEEP)
> >
> > which allows the firmware to get into ELP state during wowlan suspend is
> > only completing after system resume for some unknown reason...
> 
> Hmm maybe try also adding wl1271_power_off(wl) after put_sync()?
> 

No, we don't want to power off the chip in wowlan mode.
We power it of only during standard suspend.

The trick is that it stays on during suspend and can be used 
As a wakeup source to the host on specific packets received by
The firmware over the air.

BR,
Eyal

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-22 15:01                   ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-22 15:01 UTC (permalink / raw)
  To: Reizer, Eyal
  Cc: Kalle Valo, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn,
	Maital, Altshul, Maxim, linux-wireless, linux-omap, Loewy, Chen

* Reizer, Eyal <eyalr@ti.com> [180522 14:07]:
> > > >
> > > > OK try replacing the pm_runtime_put_noidle() above with just
> > > > pm_runtime_put_sync(). The reason why I put noidle there was the
> > > > wlcore_fw_sleep() call, with that gone put_sync should do the trick.
> > > >
> > >
> > > I have tried that already. Same problem. The last call to:
> > > ret = wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_SLEEP)
> > >
> > > which allows the firmware to get into ELP state during wowlan suspend is
> > > only completing after system resume for some unknown reason...
> > 
> > Hmm maybe try also adding wl1271_power_off(wl) after put_sync()?
> > 
> 
> No, we don't want to power off the chip in wowlan mode.
> We power it of only during standard suspend.
> 
> The trick is that it stays on during suspend and can be used 
> As a wakeup source to the host on specific packets received by
> The firmware over the air.

Oh right, then in theory pm_runtime_put_sync() should do the
here.

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-22 15:01                   ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-22 15:01 UTC (permalink / raw)
  To: Reizer, Eyal
  Cc: Kalle Valo, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn,
	Maital, Altshul, Maxim, linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Loewy, Chen

* Reizer, Eyal <eyalr-l0cyMroinI0@public.gmane.org> [180522 14:07]:
> > > >
> > > > OK try replacing the pm_runtime_put_noidle() above with just
> > > > pm_runtime_put_sync(). The reason why I put noidle there was the
> > > > wlcore_fw_sleep() call, with that gone put_sync should do the trick.
> > > >
> > >
> > > I have tried that already. Same problem. The last call to:
> > > ret = wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_SLEEP)
> > >
> > > which allows the firmware to get into ELP state during wowlan suspend is
> > > only completing after system resume for some unknown reason...
> > 
> > Hmm maybe try also adding wl1271_power_off(wl) after put_sync()?
> > 
> 
> No, we don't want to power off the chip in wowlan mode.
> We power it of only during standard suspend.
> 
> The trick is that it stays on during suspend and can be used 
> As a wakeup source to the host on specific packets received by
> The firmware over the air.

Oh right, then in theory pm_runtime_put_sync() should do the
here.

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-22 17:23                     ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-22 17:23 UTC (permalink / raw)
  To: Reizer, Eyal
  Cc: Kalle Valo, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn,
	Maital, Altshul, Maxim, linux-wireless, linux-omap, Loewy, Chen

* Tony Lindgren <tony@atomide.com> [180522 15:03]:
> * Reizer, Eyal <eyalr@ti.com> [180522 14:07]:
> > > > >
> > > > > OK try replacing the pm_runtime_put_noidle() above with just
> > > > > pm_runtime_put_sync(). The reason why I put noidle there was the
> > > > > wlcore_fw_sleep() call, with that gone put_sync should do the trick.
> > > > >
> > > >
> > > > I have tried that already. Same problem. The last call to:
> > > > ret = wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_SLEEP)
> > > >
> > > > which allows the firmware to get into ELP state during wowlan suspend is
> > > > only completing after system resume for some unknown reason...
> > > 
> > > Hmm maybe try also adding wl1271_power_off(wl) after put_sync()?
> > > 
> > 
> > No, we don't want to power off the chip in wowlan mode.
> > We power it of only during standard suspend.
> > 
> > The trick is that it stays on during suspend and can be used 
> > As a wakeup source to the host on specific packets received by
> > The firmware over the air.
> 
> Oh right, then in theory pm_runtime_put_sync() should do the
> here.

OK got my beaglebone green wireless to wake from suspend to UART
after doing:

# echo N > /sys/module/printk/parameters/console_suspend

No idea why that is needed.. Not needed on beaglebone black here.

Here's a modified version of your patch, does that put wlcore to
idle with wowlan during suspend for you?

Regards,

Tony

8< ------------------------------
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
@@ -998,24 +998,6 @@ static int wlcore_fw_wakeup(struct wl1271 *wl)
 	return wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP);
 }
 
-static int wlcore_fw_sleep(struct wl1271 *wl)
-{
-	int ret;
-
-	mutex_lock(&wl->mutex);
-	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);
-	mdelay(WL1271_SUSPEND_SLEEP);
-
-	return 0;
-}
-
 static int wl1271_setup(struct wl1271 *wl)
 {
 	wl->raw_fw_status = kzalloc(wl->fw_status_len, GFP_KERNEL);
@@ -1738,6 +1720,7 @@ static int __maybe_unused wl1271_op_suspend(struct ieee80211_hw *hw,
 {
 	struct wl1271 *wl = hw->priv;
 	struct wl12xx_vif *wlvif;
+	unsigned long flags;
 	int ret;
 
 	wl1271_debug(DEBUG_MAC80211, "mac80211 suspend wow=%d", !!wow);
@@ -1785,7 +1768,6 @@ 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,20 +1777,6 @@ static int __maybe_unused wl1271_op_suspend(struct ieee80211_hw *hw,
 
 	/* flush any remaining work */
 	wl1271_debug(DEBUG_MAC80211, "flushing remaining works");
-
-	/*
-	 * disable and re-enable interrupts in order to flush
-	 * the threaded_irq
-	 */
-	wlcore_disable_interrupts(wl);
-
-	/*
-	 * set suspended flag to avoid triggering a new threaded_irq
-	 * work. no need for spinlock as interrupts are disabled.
-	 */
-	set_bit(WL1271_FLAG_SUSPENDED, &wl->flags);
-
-	wlcore_enable_interrupts(wl);
 	flush_work(&wl->tx_work);
 
 	/*
@@ -1817,14 +1785,16 @@ static int __maybe_unused wl1271_op_suspend(struct ieee80211_hw *hw,
 	 */
 	cancel_delayed_work(&wl->tx_watchdog_work);
 
+
 	/*
-	 * Use an immediate call for allowing the firmware to go into power
-	 * save during suspend.
-	 * Using a workque for this last write was only hapenning on resume
-	 * leaving the firmware with power save disabled during suspend,
-	 * while consuming full power during wowlan suspend.
+	 * set suspended flag to avoid triggering a new threaded_irq
+	 * work.
 	 */
-	wlcore_fw_sleep(wl);
+	spin_lock_irqsave(&wl->wl_lock, flags);
+	set_bit(WL1271_FLAG_SUSPENDED, &wl->flags);
+	spin_unlock_irqrestore(&wl->wl_lock, flags);
+
+	pm_runtime_put_sync(wl->dev);
 
 	return 0;
 }
-- 
2.17.0

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-22 17:23                     ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2018-05-22 17:23 UTC (permalink / raw)
  To: Reizer, Eyal
  Cc: Kalle Valo, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn,
	Maital, Altshul, Maxim, linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Loewy, Chen

* Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> [180522 15:03]:
> * Reizer, Eyal <eyalr-l0cyMroinI0@public.gmane.org> [180522 14:07]:
> > > > >
> > > > > OK try replacing the pm_runtime_put_noidle() above with just
> > > > > pm_runtime_put_sync(). The reason why I put noidle there was the
> > > > > wlcore_fw_sleep() call, with that gone put_sync should do the trick.
> > > > >
> > > >
> > > > I have tried that already. Same problem. The last call to:
> > > > ret = wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_SLEEP)
> > > >
> > > > which allows the firmware to get into ELP state during wowlan suspend is
> > > > only completing after system resume for some unknown reason...
> > > 
> > > Hmm maybe try also adding wl1271_power_off(wl) after put_sync()?
> > > 
> > 
> > No, we don't want to power off the chip in wowlan mode.
> > We power it of only during standard suspend.
> > 
> > The trick is that it stays on during suspend and can be used 
> > As a wakeup source to the host on specific packets received by
> > The firmware over the air.
> 
> Oh right, then in theory pm_runtime_put_sync() should do the
> here.

OK got my beaglebone green wireless to wake from suspend to UART
after doing:

# echo N > /sys/module/printk/parameters/console_suspend

No idea why that is needed.. Not needed on beaglebone black here.

Here's a modified version of your patch, does that put wlcore to
idle with wowlan during suspend for you?

Regards,

Tony

8< ------------------------------
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
@@ -998,24 +998,6 @@ static int wlcore_fw_wakeup(struct wl1271 *wl)
 	return wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP);
 }
 
-static int wlcore_fw_sleep(struct wl1271 *wl)
-{
-	int ret;
-
-	mutex_lock(&wl->mutex);
-	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);
-	mdelay(WL1271_SUSPEND_SLEEP);
-
-	return 0;
-}
-
 static int wl1271_setup(struct wl1271 *wl)
 {
 	wl->raw_fw_status = kzalloc(wl->fw_status_len, GFP_KERNEL);
@@ -1738,6 +1720,7 @@ static int __maybe_unused wl1271_op_suspend(struct ieee80211_hw *hw,
 {
 	struct wl1271 *wl = hw->priv;
 	struct wl12xx_vif *wlvif;
+	unsigned long flags;
 	int ret;
 
 	wl1271_debug(DEBUG_MAC80211, "mac80211 suspend wow=%d", !!wow);
@@ -1785,7 +1768,6 @@ 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,20 +1777,6 @@ static int __maybe_unused wl1271_op_suspend(struct ieee80211_hw *hw,
 
 	/* flush any remaining work */
 	wl1271_debug(DEBUG_MAC80211, "flushing remaining works");
-
-	/*
-	 * disable and re-enable interrupts in order to flush
-	 * the threaded_irq
-	 */
-	wlcore_disable_interrupts(wl);
-
-	/*
-	 * set suspended flag to avoid triggering a new threaded_irq
-	 * work. no need for spinlock as interrupts are disabled.
-	 */
-	set_bit(WL1271_FLAG_SUSPENDED, &wl->flags);
-
-	wlcore_enable_interrupts(wl);
 	flush_work(&wl->tx_work);
 
 	/*
@@ -1817,14 +1785,16 @@ static int __maybe_unused wl1271_op_suspend(struct ieee80211_hw *hw,
 	 */
 	cancel_delayed_work(&wl->tx_watchdog_work);
 
+
 	/*
-	 * Use an immediate call for allowing the firmware to go into power
-	 * save during suspend.
-	 * Using a workque for this last write was only hapenning on resume
-	 * leaving the firmware with power save disabled during suspend,
-	 * while consuming full power during wowlan suspend.
+	 * set suspended flag to avoid triggering a new threaded_irq
+	 * work.
 	 */
-	wlcore_fw_sleep(wl);
+	spin_lock_irqsave(&wl->wl_lock, flags);
+	set_bit(WL1271_FLAG_SUSPENDED, &wl->flags);
+	spin_unlock_irqrestore(&wl->wl_lock, flags);
+
+	pm_runtime_put_sync(wl->dev);
 
 	return 0;
 }
-- 
2.17.0

^ permalink raw reply	[flat|nested] 46+ messages in thread

* RE: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-23  7:04                       ` Reizer, Eyal
  0 siblings, 0 replies; 46+ messages in thread
From: Reizer, Eyal @ 2018-05-23  7:04 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Kalle Valo, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn,
	Maital, Altshul, Maxim, linux-wireless, linux-omap, Loewy, Chen

>=20
> Here's a modified version of your patch, does that put wlcore to
> idle with wowlan during suspend for you?
>=20

Still no joy.
It suspends/resumes ok but leaves the firmware disabled from entering ELP.
You can see the log below with some prints added to wlcore_runtime_suspend(=
)
And wlcore_runtime_resume().
What you can see is that normally after each transaction, such as scan belo=
w,
It ends where the firmware is allowed to enter ELP based on its internal lo=
gic.
You can see the print "chip allowed to entered elp" below.

root@am335x-evm:~#
root@am335x-evm:~#
root@am335x-evm:~# iw wlan0 scan | grep SSID
[  106.010879] disabling the FW from enering ELP
[  106.026780] wlcore_runtime_suspend -> enter
[  106.033331] allowing chip to entered elp
 [  106.037823] chip allowed to entered elp
...
...
 [  110.110140] disabling the FW from enering ELP
[  110.224902] wlcore_runtime_suspend -> enter
[  110.229208] allowing chip to entered elp
        SSID: IOTLP_521
        SSID: Reizer
        SSID: LinksysADSL
        SSID: RT2880_AP
        SSID: net4guest
[  110.252460] chip allowed to entered elp
        SSID: halekoa75
        SSID: externalhotspot84
        SSID: cpn84
        SSID: WPS_AP_5G
        SSID: MarvellAP95
[  110.266707] disabling the FW from enering ELP
[  110.279297] wlcore_runtime_suspend -> enter
        SSID:
        SSID:
[  110.292041] allowing chip to entered elp
        SSID: net4guest
[  110.303485] chip allowed to entered elp
        SSID: halekoa75
        SSID: externalhotspot84
        SSID: cpn84
        SSID: net4guest
        SSID: halekoa75
        SSID: externalhotspot84
        SSID: cpn84
root@am335x-evm:~#
root@am335x-evm:~#
root@am335x-evm:~#

This is not the case when suspending.
You can see below that the message " PM: Successfully put all powerdomains =
to target state"
Comes before the call to pm_runtime_suspend() was executed and the firmware
Remained in full active state consuming full power during the whole time th=
e system was=20
suspended.
The call to pm_runtime_suspend is only seen on resume:

[  124.153960] Restarting tasks ...=20
[  124.154702] wlcore_runtime_suspend -> enter

I have also verified that this is not just a print issue by using a firmwar=
e logger that=20
Shows the internal state of the firmware and can see that the call to allow=
 ELP
Actually comes only after resume.
This is what I am trying to chase now. Something is not right here with pm_=
runtime.
Any ideas here?

root@am335x-evm:~#
root@am335x-evm:~# echo mem > /sys/power/state
[  123.444472] PM: suspend entry (deep)
[  123.448119] PM: Syncing filesystems ... done.
[  123.467382] Freezing user space processes ... (elapsed 0.002 seconds) do=
ne.
[  123.477144] OOM killer disabled.
[  123.480424] Freezing remaining freezable tasks ... (elapsed 0.001 second=
s) done.
[  123.489880] Suspending console(s) (use no_console_suspend to debug)
[  123.505821] disabling the FW from enering ELP
[  123.861590] pm33xx pm33xx: PM: Successfully put all powerdomains to targ=
et state
[  123.861590] PM: Wakeup source UART
[  123.886091] net eth0: initializing cpsw version 1.12 (0)
[  123.984353] SMSC LAN8710/LAN8720 4a101000.mdio:00: attached PHY driver [=
SMSC LAN8710/LAN8720] (mii_bus:phy_addr=3D4a101000.mdio:00, irq=3DPOLL)
[  124.150623] OOM killer enabled.
[  124.153960] Restarting tasks ...
[  124.154702] wlcore_runtime_suspend -> enter
[  124.171414] done.
[  124.190085] allowing chip to entered elp
[  124.199877] chip allowed to entered elp
[  124.208633] PM: suspend exit
root@am335x-evm:~#

Best Regards,
Eyal

^ permalink raw reply	[flat|nested] 46+ messages in thread

* RE: [EXTERNAL] [PATCHv2 0/5] Runtime PM support for wlcore
@ 2018-05-23  7:04                       ` Reizer, Eyal
  0 siblings, 0 replies; 46+ messages in thread
From: Reizer, Eyal @ 2018-05-23  7:04 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Kalle Valo, KISHON VIJAY ABRAHAM, Mishol, Guy, Luca Coelho, Hahn,
	Maital, Altshul, Maxim, linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Loewy, Chen

> 
> Here's a modified version of your patch, does that put wlcore to
> idle with wowlan during suspend for you?
> 

Still no joy.
It suspends/resumes ok but leaves the firmware disabled from entering ELP.
You can see the log below with some prints added to wlcore_runtime_suspend()
And wlcore_runtime_resume().
What you can see is that normally after each transaction, such as scan below,
It ends where the firmware is allowed to enter ELP based on its internal logic.
You can see the print "chip allowed to entered elp" below.

root@am335x-evm:~#
root@am335x-evm:~#
root@am335x-evm:~# iw wlan0 scan | grep SSID
[  106.010879] disabling the FW from enering ELP
[  106.026780] wlcore_runtime_suspend -> enter
[  106.033331] allowing chip to entered elp
 [  106.037823] chip allowed to entered elp
...
...
 [  110.110140] disabling the FW from enering ELP
[  110.224902] wlcore_runtime_suspend -> enter
[  110.229208] allowing chip to entered elp
        SSID: IOTLP_521
        SSID: Reizer
        SSID: LinksysADSL
        SSID: RT2880_AP
        SSID: net4guest
[  110.252460] chip allowed to entered elp
        SSID: halekoa75
        SSID: externalhotspot84
        SSID: cpn84
        SSID: WPS_AP_5G
        SSID: MarvellAP95
[  110.266707] disabling the FW from enering ELP
[  110.279297] wlcore_runtime_suspend -> enter
        SSID:
        SSID:
[  110.292041] allowing chip to entered elp
        SSID: net4guest
[  110.303485] chip allowed to entered elp
        SSID: halekoa75
        SSID: externalhotspot84
        SSID: cpn84
        SSID: net4guest
        SSID: halekoa75
        SSID: externalhotspot84
        SSID: cpn84
root@am335x-evm:~#
root@am335x-evm:~#
root@am335x-evm:~#

This is not the case when suspending.
You can see below that the message " PM: Successfully put all powerdomains to target state"
Comes before the call to pm_runtime_suspend() was executed and the firmware
Remained in full active state consuming full power during the whole time the system was 
suspended.
The call to pm_runtime_suspend is only seen on resume:

[  124.153960] Restarting tasks ... 
[  124.154702] wlcore_runtime_suspend -> enter

I have also verified that this is not just a print issue by using a firmware logger that 
Shows the internal state of the firmware and can see that the call to allow ELP
Actually comes only after resume.
This is what I am trying to chase now. Something is not right here with pm_runtime.
Any ideas here?

root@am335x-evm:~#
root@am335x-evm:~# echo mem > /sys/power/state
[  123.444472] PM: suspend entry (deep)
[  123.448119] PM: Syncing filesystems ... done.
[  123.467382] Freezing user space processes ... (elapsed 0.002 seconds) done.
[  123.477144] OOM killer disabled.
[  123.480424] Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done.
[  123.489880] Suspending console(s) (use no_console_suspend to debug)
[  123.505821] disabling the FW from enering ELP
[  123.861590] pm33xx pm33xx: PM: Successfully put all powerdomains to target state
[  123.861590] PM: Wakeup source UART
[  123.886091] net eth0: initializing cpsw version 1.12 (0)
[  123.984353] SMSC LAN8710/LAN8720 4a101000.mdio:00: attached PHY driver [SMSC LAN8710/LAN8720] (mii_bus:phy_addr=4a101000.mdio:00, irq=POLL)
[  124.150623] OOM killer enabled.
[  124.153960] Restarting tasks ...
[  124.154702] wlcore_runtime_suspend -> enter
[  124.171414] done.
[  124.190085] allowing chip to entered elp
[  124.199877] chip allowed to entered elp
[  124.208633] PM: suspend exit
root@am335x-evm:~#

Best Regards,
Eyal

^ permalink raw reply	[flat|nested] 46+ messages in thread

end of thread, other threads:[~2018-05-23  7:04 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-17 18:50 [PATCHv2 0/5] Runtime PM support for wlcore Tony Lindgren
2018-05-17 18:50 ` Tony Lindgren
2018-05-17 18:50 ` [PATCH 1/5] wlcore: Add missing PM call for wlcore_cmd_wait_for_event_or_timeout() Tony Lindgren
2018-05-17 18:50   ` Tony Lindgren
2018-05-17 18:50 ` [PATCH 2/5] wlcore: Make sure PM calls are paired Tony Lindgren
2018-05-17 18:50   ` Tony Lindgren
2018-05-17 18:50 ` [PATCH 3/5] wlcore: Add support for runtime PM Tony Lindgren
2018-05-17 18:50   ` Tony Lindgren
2018-05-17 18:50 ` [PATCH 4/5] wlcore: Fix misplaced PM call for scan_complete_work() Tony Lindgren
2018-05-17 18:50   ` Tony Lindgren
2018-05-17 18:50 ` [PATCH 5/5] wlcore: sdio: Warn about runtime PM suspend errors Tony Lindgren
2018-05-17 18:50   ` Tony Lindgren
2018-05-21 22:32   ` Tony Lindgren
2018-05-21 22:32     ` Tony Lindgren
2018-05-17 18:59 ` [PATCHv2 0/5] Runtime PM support for wlcore Tony Lindgren
2018-05-17 18:59   ` Tony Lindgren
2018-05-21  7:29 ` [EXTERNAL] " Reizer, Eyal
2018-05-21  7:29   ` Reizer, Eyal
2018-05-21 16:38   ` Tony Lindgren
2018-05-21 16:38     ` Tony Lindgren
2018-05-21 22:43     ` Tony Lindgren
2018-05-21 22:43       ` Tony Lindgren
2018-05-22  6:40       ` Reizer, Eyal
2018-05-22  6:40         ` Reizer, Eyal
2018-05-22 13:50         ` Tony Lindgren
2018-05-22 13:50           ` Tony Lindgren
2018-05-22 13:26       ` Reizer, Eyal
2018-05-22 13:26         ` Reizer, Eyal
2018-05-22 13:31         ` Tony Lindgren
2018-05-22 13:31           ` Tony Lindgren
2018-05-22 13:48           ` Reizer, Eyal
2018-05-22 13:48             ` Reizer, Eyal
2018-05-22 13:55             ` Tony Lindgren
2018-05-22 13:55               ` Tony Lindgren
2018-05-22 14:05               ` Reizer, Eyal
2018-05-22 14:05                 ` Reizer, Eyal
2018-05-22 15:01                 ` Tony Lindgren
2018-05-22 15:01                   ` Tony Lindgren
2018-05-22 17:23                   ` Tony Lindgren
2018-05-22 17:23                     ` Tony Lindgren
2018-05-23  7:04                     ` Reizer, Eyal
2018-05-23  7:04                       ` Reizer, Eyal
2018-05-22  8:02     ` Kalle Valo
2018-05-22  8:02       ` Kalle Valo
2018-05-22 13:37       ` Tony Lindgren
2018-05-22 13:37         ` Tony Lindgren

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.