iwlwifi: fix suspend/resume and its usage of pci saved state

Here we do two things:

First, revert "iwlwifi: save PCI state before suspend, restore after
resume".  That misguided patch led to being unable to use iwlwifi
devices after resume.

Next, indicate to PCI driver that the saved PCI state is valid during suspend.

We restore PCI state and enable the device when network interface is created,
similarly PCI state is saved and the device is disabled when network interface
is removed. Thus, when .suspend is called the PCI state is saved and device
is disabled. This is the case even if an interface is never created as PCI
state is saved and device disabled during .probe.

PCI driver assumes PCI state is saved in .suspend. Saving the state at this
time will save state of disabled device and thus cause problems during
resume (resuming a disabled device). We thus indicate directly to PCI
driver that current PCI saved state is valid.

Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Tested-by: Alex Riesen <fork0@users.sf.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Reinette Chatre 2009-02-10 12:02:49 -08:00 committed by John W. Linville
parent efb43f4b2c
commit 89c581b3fb
2 changed files with 26 additions and 4 deletions

View File

@ -4042,7 +4042,19 @@ static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
priv->is_open = 1;
}
pci_save_state(pdev);
/* pci driver assumes state will be saved in this function.
* pci state is saved and device disabled when interface is
* stopped, so at this time pci device will always be disabled -
* whether interface was started or not. saving pci state now will
* cause saved state be that of a disabled device, which will cause
* problems during resume in that we will end up with a disabled device.
*
* indicate that the current saved state (from when interface was
* stopped) is valid. if interface was never up at time of suspend
* then the saved state will still be valid as it was saved during
* .probe. */
pdev->state_saved = true;
pci_set_power_state(pdev, PCI_D3hot);
return 0;
@ -4053,7 +4065,6 @@ static int iwl_pci_resume(struct pci_dev *pdev)
struct iwl_priv *priv = pci_get_drvdata(pdev);
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
if (priv->is_open)
iwl_mac_start(priv->hw);

View File

@ -8143,7 +8143,19 @@ static int iwl3945_pci_suspend(struct pci_dev *pdev, pm_message_t state)
priv->is_open = 1;
}
pci_save_state(pdev);
/* pci driver assumes state will be saved in this function.
* pci state is saved and device disabled when interface is
* stopped, so at this time pci device will always be disabled -
* whether interface was started or not. saving pci state now will
* cause saved state be that of a disabled device, which will cause
* problems during resume in that we will end up with a disabled device.
*
* indicate that the current saved state (from when interface was
* stopped) is valid. if interface was never up at time of suspend
* then the saved state will still be valid as it was saved during
* .probe. */
pdev->state_saved = true;
pci_set_power_state(pdev, PCI_D3hot);
return 0;
@ -8154,7 +8166,6 @@ static int iwl3945_pci_resume(struct pci_dev *pdev)
struct iwl3945_priv *priv = pci_get_drvdata(pdev);
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
if (priv->is_open)
iwl3945_mac_start(priv->hw);