Commit 4479a899 authored by Luca Coelho's avatar Luca Coelho Committed by Emmanuel Grumbach

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: default avatarLuca Coelho <luciano.coelho@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent 53f09e74
...@@ -631,13 +631,31 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -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 RTPM is in use, enable it in our device */
if (iwl_trans->runtime_pm_mode != IWL_PLAT_PM_MODE_DISABLED) { 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_active(&pdev->dev);
pm_runtime_set_autosuspend_delay(&pdev->dev, pm_runtime_set_autosuspend_delay(&pdev->dev,
iwlwifi_mod_params.d0i3_entry_delay); iwlwifi_mod_params.d0i3_entry_delay);
pm_runtime_use_autosuspend(&pdev->dev); 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); 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; return 0;
out_free_drv: out_free_drv:
...@@ -652,7 +670,17 @@ static void iwl_pci_remove(struct pci_dev *pdev) ...@@ -652,7 +670,17 @@ static void iwl_pci_remove(struct pci_dev *pdev)
struct iwl_trans *trans = pci_get_drvdata(pdev); struct iwl_trans *trans = pci_get_drvdata(pdev);
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 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_drv_stop(trans_pcie->drv);
iwl_trans_pcie_free(trans); iwl_trans_pcie_free(trans);
} }
......
...@@ -1646,9 +1646,6 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans, ...@@ -1646,9 +1646,6 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans,
trans->command_groups = trans_cfg->command_groups; trans->command_groups = trans_cfg->command_groups;
trans->command_groups_size = trans_cfg->command_groups_size; 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 /* Initialize NAPI here - it should be before registering to mac80211
* in the opmode but after the HW struct is allocated. * in the opmode but after the HW struct is allocated.
* As this function may be called again in some corner cases don't * 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) ...@@ -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); struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
int i; int i;
/* TODO: check if this is really needed */
pm_runtime_disable(trans->dev);
iwl_pcie_synchronize_irqs(trans); iwl_pcie_synchronize_irqs(trans);
iwl_pcie_tx_free(trans); iwl_pcie_tx_free(trans);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment