iwlwifi: pcie: forbid RTPM on device removal

The pci driver keeps any unbound device in active state and forbids
runtime PM.  When our driver gets probed, we take control of the
state.  When the device is released (i.e. during unbind or module
removal), we should return the state to what it was before.  To do so,
we need to forbid RTPM in the driver remove op.

Additionally, remove an unnecessary pm_runtime_disable() call, move
the initial ref_count setting to a better place and add some comments
explaining what is going on.

Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
This commit is contained in:
Luca Coelho 2016-02-08 11:18:46 +02:00 committed by Emmanuel Grumbach
parent 53f09e742b
commit 4479a899f7
2 changed files with 28 additions and 6 deletions

View File

@ -631,13 +631,31 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* if RTPM is in use, enable it in our device */
if (iwl_trans->runtime_pm_mode != IWL_PLAT_PM_MODE_DISABLED) {
/* We explicitly set the device to active here to
* clear contingent errors.
*/
pm_runtime_set_active(&pdev->dev);
pm_runtime_set_autosuspend_delay(&pdev->dev,
iwlwifi_mod_params.d0i3_entry_delay);
pm_runtime_use_autosuspend(&pdev->dev);
/* We are not supposed to call pm_runtime_allow() by
* ourselves, but let userspace enable runtime PM via
* sysfs. However, since we don't enable this from
* userspace yet, we need to allow/forbid() ourselves.
*/
pm_runtime_allow(&pdev->dev);
}
/* The PCI device starts with a reference taken and we are
* supposed to release it here. But to simplify the
* interaction with the opmode, we don't do it now, but let
* the opmode release it when it's ready. To account for this
* reference, we start with ref_count set to 1.
*/
trans_pcie->ref_count = 1;
return 0;
out_free_drv:
@ -652,7 +670,17 @@ static void iwl_pci_remove(struct pci_dev *pdev)
struct iwl_trans *trans = pci_get_drvdata(pdev);
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
/* if RTPM was in use, restore it to the state before probe */
if (trans->runtime_pm_mode != IWL_PLAT_PM_MODE_DISABLED) {
/* We should not call forbid here, but we do for now.
* Check the comment to pm_runtime_allow() in
* iwl_pci_probe().
*/
pm_runtime_forbid(trans->dev);
}
iwl_drv_stop(trans_pcie->drv);
iwl_trans_pcie_free(trans);
}

View File

@ -1646,9 +1646,6 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans,
trans->command_groups = trans_cfg->command_groups;
trans->command_groups_size = trans_cfg->command_groups_size;
/* init ref_count to 1 (should be cleared when ucode is loaded) */
trans_pcie->ref_count = 1;
/* Initialize NAPI here - it should be before registering to mac80211
* in the opmode but after the HW struct is allocated.
* As this function may be called again in some corner cases don't
@ -1663,9 +1660,6 @@ void iwl_trans_pcie_free(struct iwl_trans *trans)
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
int i;
/* TODO: check if this is really needed */
pm_runtime_disable(trans->dev);
iwl_pcie_synchronize_irqs(trans);
iwl_pcie_tx_free(trans);