Skip to contentSkip to conversation

iwlwifi: add basic runtime PM support

RFC PATCH Superseded Yan, Zheng 6 participants 12 messages Jan 6, 2012 – Jan 9, 2012 2 messages not in the archive

Subsystems (3)

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore

Yan, Zheng

author
#0 lore raw

RFC PATCH 1/1 iwlwifi: add basic runtime PM support

This simple patch adds open/close based runtime PM support to the iwlwifi driver. Namely, make the driver suspend the device after shutting down the interface and resume the device when activating the interface. In my test, suspending the device can save about 0.4 watt power. The shortcoming is that the device no longer generate rfkill changes interrupt.

---

drivers/net/wireless/iwlwifi/iwl-agn.c +15 -3
index e0e9a3d..c0b7b85 100644
@@ -38,6 +38,7 @@
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
+#include <linux/pm_runtime.h>
 
 #include <net/mac80211.h>
 
@@ -1755,6 +1756,8 @@ static int iwlagn_mac_start(struct ieee80211_hw *hw)
 	struct iwl_priv *priv = hw->priv;
 	int ret;
 
+	pm_runtime_get_sync(bus(priv)->dev);
+
 	IWL_DEBUG_MAC80211(priv, "enter\n");
 
 	/* we should be verifying the device is ready to be opened */
@@ -1762,19 +1765,24 @@ static int iwlagn_mac_start(struct ieee80211_hw *hw)
 	ret = __iwl_up(priv);
 	mutex_unlock(&priv->shrd->mutex);
 	if (ret)
-		return ret;
+		goto out;
 
 	IWL_DEBUG_INFO(priv, "Start UP work done.\n");
 
 	/* Now we should be done, and the READY bit should be set. */
-	if (WARN_ON(!test_bit(STATUS_READY, &priv->shrd->status)))
+	if (WARN_ON(!test_bit(STATUS_READY, &priv->shrd->status))) {
 		ret = -EIO;
+		goto out;
+	}
 
 	iwlagn_led_enable(priv);
 
 	priv->is_open = 1;
 	IWL_DEBUG_MAC80211(priv, "leave\n");
-	return 0;
+	ret = 0;
+out:
+	pm_runtime_put(bus(priv)->dev);
+	return ret;
 }
 
 static void iwlagn_mac_stop(struct ieee80211_hw *hw)
@@ -1786,6 +1794,8 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw)
 	if (!priv->is_open)
 		return;
 
+	pm_runtime_get_sync(bus(priv)->dev);
+
 	priv->is_open = 0;
 
 	iwl_down(priv);
@@ -1798,6 +1808,8 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw)
 	iwl_enable_rfkill_int(priv);
 
 	IWL_DEBUG_MAC80211(priv, "leave\n");
+
+	pm_runtime_put(bus(priv)->dev);
 }
 
 #ifdef CONFIG_PM_SLEEP
drivers/net/wireless/iwlwifi/iwl-pci.c +20 -1
index 1800029..d3f39b2 100644
@@ -63,6 +63,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/pci-aspm.h>
+#include <linux/pm_runtime.h>
 
 #include "iwl-bus.h"
 #include "iwl-io.h"
@@ -465,6 +466,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	err = iwl_probe(bus, &trans_ops_pcie, cfg);
 	if (err)
 		goto out_disable_msi;
+
+	pm_runtime_put_noidle(&pdev->dev);
 	return 0;
 
 out_disable_msi:
@@ -487,6 +490,8 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
 	struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus);
 	struct iwl_shared *shrd = bus->shrd;
 
+	pm_runtime_get_noresume(&pdev->dev);
+
 	iwl_remove(shrd->priv);
 
 	pci_disable_msi(pci_dev);
@@ -534,7 +539,21 @@ static int iwl_pci_resume(struct device *device)
 	return iwl_trans_resume(shrd->trans);
 }
 
-static SIMPLE_DEV_PM_OPS(iwl_dev_pm_ops, iwl_pci_suspend, iwl_pci_resume);
+
+static int iwl_pci_runtime_idle(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct iwl_bus *bus = pci_get_drvdata(pdev);
+	struct iwl_shared *shrd = bus->shrd;
+
+	if (!test_bit(STATUS_ALIVE, &shrd->status))
+		return 0;
+
+	return -EBUSY;
+}
+
+static UNIVERSAL_DEV_PM_OPS(iwl_dev_pm_ops, iwl_pci_suspend,
+			iwl_pci_resume, iwl_pci_runtime_idle);
 
 #define IWL_PM_OPS	(&iwl_dev_pm_ops)
 

A message that is not in the archive (sent off-list or not yet received): [email protected]

#2 lore raw

[add linux-wireless]

Quoted 5 lines · Zheng

This simple patch adds open/close based runtime PM support to the iwlwifi driver. Namely, make the driver suspend the device after shutting down the interface and resume the device when activating the interface. In my test, suspending the device can save about 0.4 watt power. The shortcoming is that the device no longer generate rfkill changes interrupt.

NACK due to that last sentence. There's no way we can live with that in the general case -- and your patch isn't even configurable afaict. And I'm sure polling the rfkill flag would use just as much energy.

There might be some value in this in a system that doesn't have a hard rfkill line, but that means this needs to be configurable since the device can't know whether there's a button or not [1].

johannes

[1] actually in theory it might be possible to determine whether or not the pin is floating or not? I doubt even that is possible with the HW we have though

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

author
#3 lore raw
Quoted 9 lines · Johannes Berg

[add linux-wireless]

Quoted 5 lines · Zheng

This simple patch adds open/close based runtime PM support to the iwlwifi driver. Namely, make the driver suspend the device after shutting down the interface and resume the device when activating the interface. In my test, suspending the device can save about 0.4 watt power. The shortcoming is that the device no longer generate rfkill changes interrupt.

Quoted 4 lines

NACK due to that last sentence. There's no way we can live with that in the general case -- and your patch isn't even configurable afaict. And I'm sure polling the rfkill flag would use just as much energy.

It's configurable, runtime PM is disabled by default.

Quoted 4 lines

There might be some value in this in a system that doesn't have a hard rfkill line, but that means this needs to be configurable since the device can't know whether there's a button or not [1].

The patch targets system that only use software rfkill

Regards
Yan, Zheng

Quoted 6 lines

johannes

[1] actually in theory it might be possible to determine whether or not the pin is floating or not? I doubt even that is possible with the HW we have though

#4 lore raw
Quoted 10 lines · Zheng
Quoted 9 lines · Johannes Berg

[add linux-wireless]

Quoted 5 lines · Zheng

This simple patch adds open/close based runtime PM support to the iwlwifi driver. Namely, make the driver suspend the device after shutting down the interface and resume the device when activating the interface. In my test, suspending the device can save about 0.4 watt power. The shortcoming is that the device no longer generate rfkill changes interrupt.

Quoted 5 lines
Quoted 4 lines

NACK due to that last sentence. There's no way we can live with that in the general case -- and your patch isn't even configurable afaict. And I'm sure polling the rfkill flag would use just as much energy.

It's configurable, runtime PM is disabled by default.

Somehow I miss it, how you configure it?

Quoted 6 lines
Quoted 5 lines

There might be some value in this in a system that doesn't have a hard rfkill line, but that means this needs to be configurable since the device can't know whether there's a button or not [1].

The patch targets system that only use software rfkill

How you control that?

Wey

Quoted 1 line
#5 lore raw
Quoted 11 lines · Wey-Yi
Quoted 10 lines · Zheng
Quoted 9 lines · Johannes Berg

[add linux-wireless]

Quoted 5 lines · Zheng

This simple patch adds open/close based runtime PM support to the iwlwifi driver. Namely, make the driver suspend the device after shutting down the interface and resume the device when activating the interface. In my test, suspending the device can save about 0.4 watt power. The shortcoming is that the device no longer generate rfkill changes interrupt.

Quoted 8 lines
Quoted 5 lines
Quoted 4 lines

NACK due to that last sentence. There's no way we can live with that in the general case -- and your patch isn't even configurable afaict. And I'm sure polling the rfkill flag would use just as much energy.

It's configurable, runtime PM is disabled by default.

Somehow I miss it, how you configure it?

change the value of /sys/devices/.../power/control to auto to enable the runtime PM. (e.g echo auto > /sys/devices/pci0000:00/0000:00:1c.3/0000:02:00.0/power/control)

Quoted 8 lines
Quoted 6 lines
Quoted 5 lines

There might be some value in this in a system that doesn't have a hard rfkill line, but that means this needs to be configurable since the device can't know whether there's a button or not [1].

The patch targets system that only use software rfkill

How you control that?

I can't. Our team is working on runtime PM project, the purpose of the patch is more or less to demonstrate how much power can be saved.

Regards
Yan, Zheng

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#6 lore raw
Quoted 16 lines · Zheng
Quoted 15 lines · Wey-Yi
Quoted 14 lines · Zheng
Quoted 13 lines · Johannes Berg

[add linux-wireless]

Quoted 5 lines · Zheng

This simple patch adds open/close based runtime PM support to the iwlwifi driver. Namely, make the driver suspend the device after shutting down the interface and resume the device when activating the interface. In my test, suspending the device can save about 0.4 watt power. The shortcoming is that the device no longer generate rfkill changes interrupt.

NACK due to that last sentence. There's no way we can live with that in the general case -- and your patch isn't even configurable afaict. And I'm sure polling the rfkill flag would use just as much energy.

Quoted 6 lines
Quoted 4 lines
Quoted 1 line

It's configurable, runtime PM is disabled by default.

Somehow I miss it, how you configure it?

change the value of /sys/devices/.../power/control to auto to enable the runtime PM. (e.g echo auto > /sys/devices/pci0000:00/0000:00:1c.3/0000:02:00.0/power/control)

I am not sure it is acceptable, how you expect user figure out the pci space especially the NIC can be in any of the PCI slots.

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines

There might be some value in this in a system that doesn't have a hard rfkill line, but that means this needs to be configurable since the device can't know whether there's a button or not [1].

Quoted 6 lines
Quoted 3 lines
Quoted 1 line

The patch targets system that only use software rfkill

How you control that?

I can't. Our team is working on runtime PM project, the purpose of the patch is more or less to demonstrate how much power can be saved.

I understand, but unless we figure out either make rkill interrupt works in runtime PM, or figure out the platform does not has HW RFKILL automatically, I don't see how this patch can upstream without generate a lot of issues and bug reports.

Thanks
Wey

Quoted 1 line
author
#7 lore raw
Quoted 35 lines · Wey-Yi
Quoted 16 lines · Zheng
Quoted 15 lines · Wey-Yi
Quoted 14 lines · Zheng
Quoted 13 lines · Johannes Berg

[add linux-wireless]

Quoted 5 lines · Zheng

This simple patch adds open/close based runtime PM support to the iwlwifi driver. Namely, make the driver suspend the device after shutting down the interface and resume the device when activating the interface. In my test, suspending the device can save about 0.4 watt power. The shortcoming is that the device no longer generate rfkill changes interrupt.

NACK due to that last sentence. There's no way we can live with that in the general case -- and your patch isn't even configurable afaict. And I'm sure polling the rfkill flag would use just as much energy.

Quoted 6 lines
Quoted 4 lines
Quoted 1 line

It's configurable, runtime PM is disabled by default.

Somehow I miss it, how you configure it?

change the value of /sys/devices/.../power/control to auto to enable the runtime PM. (e.g echo auto > /sys/devices/pci0000:00/0000:00:1c.3/0000:02:00.0/power/control)

I am not sure it is acceptable, how you expect user figure out the pci space especially the NIC can be in any of the PCI slots.

Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
Quoted 6 lines

There might be some value in this in a system that doesn't have a hard rfkill line, but that means this needs to be configurable since the device can't know whether there's a button or not [1].

The patch targets system that only use software rfkill

Quoted 9 lines
Quoted 4 lines
Quoted 1 line

How you control that?

I can't. Our team is working on runtime PM project, the purpose of the patch is more or less to demonstrate how much power can be saved.

I understand, but unless we figure out either make rkill interrupt works in runtime PM, or figure out the platform does not has HW RFKILL automatically, I don't see how this patch can upstream without generate a lot of issues and bug reports.

Thank you for the suggestion.

Yan, Zheng

maintainer
#8 lore raw
In reply to Guy, Wey-Yi
Quoted 4 lines · Wey-Yi

I understand, but unless we figure out either make rkill interrupt works in runtime PM, or figure out the platform does not has HW RFKILL automatically, I don't see how this patch can upstream without generate a lot of issues and bug reports.

I suppose the question is -- will any tools/users enable it and then scream about their rfkill?

Maybe we can use pm_runtime_forbid() to disable it completely, and add a module parameter or something to enable it -- just so people are aware of the tradeoffs?

johannes

A message that is not in the archive (sent off-list or not yet received): 1326100270.3451.5.camel-8upI4CBIZJIJvtFkdXX2HixXY32XiHfO@public.gmane.org

#10 lore raw
Quoted 8 lines · Johannes Berg
Quoted 4 lines · Wey-Yi

I understand, but unless we figure out either make rkill interrupt works in runtime PM, or figure out the platform does not has HW RFKILL automatically, I don't see how this patch can upstream without generate a lot of issues and bug reports.

Quoted 6 lines

I suppose the question is -- will any tools/users enable it and then scream about their rfkill?

Maybe we can use pm_runtime_forbid() to disable it completely, and add a module parameter or something to enable it -- just so people are aware of the tradeoffs?

module parameter shall works, we just need a clear and easy way to allow user enable/disable this runtime PM feature and not making mistake

Wey

Quoted 1 line

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

maintainer
#11 lore raw
In reply to Yan, Zheng
Quoted 5 lines · Zheng
Quoted 4 lines

NACK due to that last sentence. There's no way we can live with that in the general case -- and your patch isn't even configurable afaict. And I'm sure polling the rfkill flag would use just as much energy.

It's configurable, runtime PM is disabled by default.

Oh ok, that's not so bad then -- we just need the default case to continue working I think.

johannes

#12 lore raw
In reply to Yan, Zheng

Hi Zheng,

Quoted 21 lines · Zheng

This simple patch adds open/close based runtime PM support to the iwlwifi driver. Namely, make the driver suspend the device after shutting down the interface and resume the device when activating the interface. In my test, suspending the device can save about 0.4 watt power. The shortcoming is that the device no longer generate rfkill changes interrupt.

---

drivers/net/wireless/iwlwifi/iwl-agn.c +1 -0
index e0e9a3d..c0b7b85 100644
@@ -38,6 +38,7 @@
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
+#include <linux/pm_runtime.h>
 
 #include <net/mac80211.h>
 

drivers/net/wireless/iwlwifi/iwl-agn.c static int iwlagn_mac_start(struct ieee80211_hw *hw) · line 1757

Quoted 2 lines
drivers/net/wireless/iwlwifi/iwl-agn.c +0 -0
@@ -1755,6 +1756,8 @@ static int iwlagn_mac_start(struct ieee80211_hw *hw)
 	struct iwl_priv *priv = hw->priv;
 	int ret;

why not just set the ret = 0 here and save eht work later

Quoted 18 lines
drivers/net/wireless/iwlwifi/iwl-agn.c +4 -2
+	pm_runtime_get_sync(bus(priv)->dev);
+
 	IWL_DEBUG_MAC80211(priv, "enter\n");
 
 	/* we should be verifying the device is ready to be opened */
@@ -1762,19 +1765,24 @@ static int iwlagn_mac_start(struct ieee80211_hw *hw)
 	ret = __iwl_up(priv);
 	mutex_unlock(&priv->shrd->mutex);
 	if (ret)
-		return ret;
+		goto out;
 
 	IWL_DEBUG_INFO(priv, "Start UP work done.\n");
 
 	/* Now we should be done, and the READY bit should be set. */
-	if (WARN_ON(!test_bit(STATUS_READY, &priv->shrd->status)))
+	if (WARN_ON(!test_bit(STATUS_READY, &priv->shrd->status))) {

drivers/net/wireless/iwlwifi/iwl-agn.c static int iwlagn_mac_start(struct ieee80211_hw *hw) · line 1782

Quoted 10 lines
drivers/net/wireless/iwlwifi/iwl-agn.c +3 -1
 		ret = -EIO;
+		goto out;
+	}
 
 	iwlagn_led_enable(priv);
 
 	priv->is_open = 1;
 	IWL_DEBUG_MAC80211(priv, "leave\n");
-	return 0;
+	ret = 0;

if set it earlier, do have to do this

Quoted 67 lines
drivers/net/wireless/iwlwifi/iwl-agn.c +7 -0
+out:
+	pm_runtime_put(bus(priv)->dev);
+	return ret;
 }
 
 static void iwlagn_mac_stop(struct ieee80211_hw *hw)
@@ -1786,6 +1794,8 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw)
 	if (!priv->is_open)
 		return;
 
+	pm_runtime_get_sync(bus(priv)->dev);
+
 	priv->is_open = 0;
 
 	iwl_down(priv);
@@ -1798,6 +1808,8 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw)
 	iwl_enable_rfkill_int(priv);
 
 	IWL_DEBUG_MAC80211(priv, "leave\n");
+
+	pm_runtime_put(bus(priv)->dev);
 }
 
 #ifdef CONFIG_PM_SLEEP
drivers/net/wireless/iwlwifi/iwl-pci.c +13 -1
index 1800029..d3f39b2 100644
@@ -63,6 +63,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/pci-aspm.h>
+#include <linux/pm_runtime.h>
 
 #include "iwl-bus.h"
 #include "iwl-io.h"
@@ -465,6 +466,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	err = iwl_probe(bus, &trans_ops_pcie, cfg);
 	if (err)
 		goto out_disable_msi;
+
+	pm_runtime_put_noidle(&pdev->dev);
 	return 0;
 
 out_disable_msi:
@@ -487,6 +490,8 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
 	struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus);
 	struct iwl_shared *shrd = bus->shrd;
 
+	pm_runtime_get_noresume(&pdev->dev);
+
 	iwl_remove(shrd->priv);
 
 	pci_disable_msi(pci_dev);
@@ -534,7 +539,21 @@ static int iwl_pci_resume(struct device *device)
 	return iwl_trans_resume(shrd->trans);
 }
 
-static SIMPLE_DEV_PM_OPS(iwl_dev_pm_ops, iwl_pci_suspend, iwl_pci_resume);
+
+static int iwl_pci_runtime_idle(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct iwl_bus *bus = pci_get_drvdata(pdev);
+	struct iwl_shared *shrd = bus->shrd;
+
+	if (!test_bit(STATUS_ALIVE, &shrd->status))

drivers/net/wireless/iwlwifi/iwl-pci.c static int iwl_pci_resume(struct device *device) · line 559

Quoted 10 lines
drivers/net/wireless/iwlwifi/iwl-pci.c +7 -0
+		return 0;
+
+	return -EBUSY;
+}
+
+static UNIVERSAL_DEV_PM_OPS(iwl_dev_pm_ops, iwl_pci_suspend,
+			iwl_pci_resume, iwl_pci_runtime_idle);
 
 #define IWL_PM_OPS	(&iwl_dev_pm_ops)
 

it looks good, what NIC and system you test with?
also you mention it no longer generate rfkill changes interrupt, could you elaborate?

btw, could you send the patch to <[email protected]> first if ok for you.

Thanks
Wey

author
#13 lore raw
Quoted 132 lines · wwguy

Hi Zheng,

Quoted 21 lines · Zheng

This simple patch adds open/close based runtime PM support to the iwlwifi driver. Namely, make the driver suspend the device after shutting down the interface and resume the device when activating the interface. In my test, suspending the device can save about 0.4 watt power. The shortcoming is that the device no longer generate rfkill changes interrupt.

---

drivers/net/wireless/iwlwifi/iwl-agn.c +1 -0
index e0e9a3d..c0b7b85 100644
@@ -38,6 +38,7 @@
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
+#include <linux/pm_runtime.h>
 
 #include <net/mac80211.h>
 

drivers/net/wireless/iwlwifi/iwl-agn.c static int iwlagn_mac_start(struct ieee80211_hw *hw) · line 1757

Quoted 2 lines
drivers/net/wireless/iwlwifi/iwl-agn.c +0 -0
@@ -1755,6 +1756,8 @@ static int iwlagn_mac_start(struct ieee80211_hw *hw)
 	struct iwl_priv *priv = hw->priv;
 	int ret;

why not just set the ret = 0 here and save eht work later

Quoted 18 lines
drivers/net/wireless/iwlwifi/iwl-agn.c +4 -2
+	pm_runtime_get_sync(bus(priv)->dev);
+
 	IWL_DEBUG_MAC80211(priv, "enter\n");
 
 	/* we should be verifying the device is ready to be opened */
@@ -1762,19 +1765,24 @@ static int iwlagn_mac_start(struct ieee80211_hw *hw)
 	ret = __iwl_up(priv);
 	mutex_unlock(&priv->shrd->mutex);
 	if (ret)
-		return ret;
+		goto out;
 
 	IWL_DEBUG_INFO(priv, "Start UP work done.\n");
 
 	/* Now we should be done, and the READY bit should be set. */
-	if (WARN_ON(!test_bit(STATUS_READY, &priv->shrd->status)))
+	if (WARN_ON(!test_bit(STATUS_READY, &priv->shrd->status))) {

drivers/net/wireless/iwlwifi/iwl-agn.c static int iwlagn_mac_start(struct ieee80211_hw *hw) · line 1782

Quoted 10 lines
drivers/net/wireless/iwlwifi/iwl-agn.c +3 -1
 		ret = -EIO;
+		goto out;
+	}
 
 	iwlagn_led_enable(priv);
 
 	priv->is_open = 1;
 	IWL_DEBUG_MAC80211(priv, "leave\n");
-	return 0;
+	ret = 0;

if set it earlier, do have to do this

Quoted 75 lines
drivers/net/wireless/iwlwifi/iwl-agn.c +7 -0
+out:
+	pm_runtime_put(bus(priv)->dev);
+	return ret;
 }
 
 static void iwlagn_mac_stop(struct ieee80211_hw *hw)
@@ -1786,6 +1794,8 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw)
 	if (!priv->is_open)
 		return;
 
+	pm_runtime_get_sync(bus(priv)->dev);
+
 	priv->is_open = 0;
 
 	iwl_down(priv);
@@ -1798,6 +1808,8 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw)
 	iwl_enable_rfkill_int(priv);
 
 	IWL_DEBUG_MAC80211(priv, "leave\n");
+
+	pm_runtime_put(bus(priv)->dev);
 }
 
 #ifdef CONFIG_PM_SLEEP
drivers/net/wireless/iwlwifi/iwl-pci.c +20 -1
index 1800029..d3f39b2 100644
@@ -63,6 +63,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/pci-aspm.h>
+#include <linux/pm_runtime.h>
 
 #include "iwl-bus.h"
 #include "iwl-io.h"
@@ -465,6 +466,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	err = iwl_probe(bus, &trans_ops_pcie, cfg);
 	if (err)
 		goto out_disable_msi;
+
+	pm_runtime_put_noidle(&pdev->dev);
 	return 0;
 
 out_disable_msi:
@@ -487,6 +490,8 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
 	struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus);
 	struct iwl_shared *shrd = bus->shrd;
 
+	pm_runtime_get_noresume(&pdev->dev);
+
 	iwl_remove(shrd->priv);
 
 	pci_disable_msi(pci_dev);
@@ -534,7 +539,21 @@ static int iwl_pci_resume(struct device *device)
 	return iwl_trans_resume(shrd->trans);
 }
 
-static SIMPLE_DEV_PM_OPS(iwl_dev_pm_ops, iwl_pci_suspend, iwl_pci_resume);
+
+static int iwl_pci_runtime_idle(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct iwl_bus *bus = pci_get_drvdata(pdev);
+	struct iwl_shared *shrd = bus->shrd;
+
+	if (!test_bit(STATUS_ALIVE, &shrd->status))
+		return 0;
+
+	return -EBUSY;
+}
+
+static UNIVERSAL_DEV_PM_OPS(iwl_dev_pm_ops, iwl_pci_suspend,
+			iwl_pci_resume, iwl_pci_runtime_idle);
 
Quoted 4 lines

drivers/net/wireless/iwlwifi/iwl-pci.c static int iwl_pci_resume(struct device *device) · line 559

Quoted 2 lines
drivers/net/wireless/iwlwifi/iwl-pci.c +0 -0
 #define IWL_PM_OPS	(&iwl_dev_pm_ops)
 

it looks good, what NIC and system you test with?

Intel Centrino Advanced-N 6230

Quoted 2 lines

also you mention it no longer generate rfkill changes interrupt, could you elaborate?

After putting the device into D3hot, the device doesn't generate rfkill changes interrupt. I also tried check CSR_GP_CNTRL register when the device is suspended, it doesn't reflect rfkill changes neither.

Quoted 4 lines

btw, could you send the patch to <[email protected]> first if ok for you.

Ok

Regards
Yan, Zheng

Quoted 3 lines

Thanks
Wey