|
@@ -811,6 +811,45 @@ static int iwl_pci_runtime_resume(struct device *device)
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
+
|
|
|
+static int iwl_pci_system_prepare(struct device *device)
|
|
|
+{
|
|
|
+ struct pci_dev *pdev = to_pci_dev(device);
|
|
|
+ struct iwl_trans *trans = pci_get_drvdata(pdev);
|
|
|
+
|
|
|
+ IWL_DEBUG_RPM(trans, "preparing for system suspend\n");
|
|
|
+
|
|
|
+ /* This is called before entering system suspend and before
|
|
|
+ * the runtime resume is called. Set the suspending flag to
|
|
|
+ * prevent the wakelock from being taken.
|
|
|
+ */
|
|
|
+ trans->suspending = true;
|
|
|
+
|
|
|
+ /* Wake the device up from runtime suspend before going to
|
|
|
+ * platform suspend. This is needed because we don't know
|
|
|
+ * whether wowlan any is set and, if it's not, mac80211 will
|
|
|
+ * disconnect (in which case, we can't be in D0i3).
|
|
|
+ */
|
|
|
+ pm_runtime_resume(device);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static void iwl_pci_system_complete(struct device *device)
|
|
|
+{
|
|
|
+ struct pci_dev *pdev = to_pci_dev(device);
|
|
|
+ struct iwl_trans *trans = pci_get_drvdata(pdev);
|
|
|
+
|
|
|
+ IWL_DEBUG_RPM(trans, "completing system suspend\n");
|
|
|
+
|
|
|
+ /* This is called as a counterpart to the prepare op. It is
|
|
|
+ * called either when suspending fails or when suspend
|
|
|
+ * completed successfully. Now there's no risk of grabbing
|
|
|
+ * the wakelock anymore, so we can release the suspending
|
|
|
+ * flag.
|
|
|
+ */
|
|
|
+ trans->suspending = false;
|
|
|
+}
|
|
|
#endif /* CONFIG_IWLWIFI_PCIE_RTPM */
|
|
|
|
|
|
static const struct dev_pm_ops iwl_dev_pm_ops = {
|
|
@@ -820,6 +859,8 @@ static const struct dev_pm_ops iwl_dev_pm_ops = {
|
|
|
SET_RUNTIME_PM_OPS(iwl_pci_runtime_suspend,
|
|
|
iwl_pci_runtime_resume,
|
|
|
NULL)
|
|
|
+ .prepare = iwl_pci_system_prepare,
|
|
|
+ .complete = iwl_pci_system_complete,
|
|
|
#endif /* CONFIG_IWLWIFI_PCIE_RTPM */
|
|
|
};
|
|
|
|