diff mbox

[EXTERNAL,PATCHv2,0/5] Runtime PM support for wlcore

Message ID 20180522172343.GK98604@atomide.com (mailing list archive)
State RFC
Delegated to: Kalle Valo
Headers show

Commit Message

Tony Lindgren May 22, 2018, 5:23 p.m. UTC
* 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< ------------------------------

Comments

Reizer, Eyal May 23, 2018, 7:04 a.m. UTC | #1
> 
> 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
diff mbox

Patch

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;
 }