diff options
Diffstat (limited to '0011-iwlwifi-pcie-move-power-gating-workaround-earlier-in-the-flow.patch')
-rw-r--r-- | 0011-iwlwifi-pcie-move-power-gating-workaround-earlier-in-the-flow.patch | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/0011-iwlwifi-pcie-move-power-gating-workaround-earlier-in-the-flow.patch b/0011-iwlwifi-pcie-move-power-gating-workaround-earlier-in-the-flow.patch new file mode 100644 index 0000000..457542b --- /dev/null +++ b/0011-iwlwifi-pcie-move-power-gating-workaround-earlier-in-the-flow.patch @@ -0,0 +1,119 @@ +From 9894b27702c2e6090213f84db3e3d47f191253cd Mon Sep 17 00:00:00 2001 +From: Luca Coelho <luciano.coelho@intel.com> +Date: Thu, 5 Dec 2019 09:03:54 +0200 +Subject: iwlwifi: pcie: move power gating workaround earlier in the flow + +We need to reset the NIC after setting the bits to enable power +gating and that cannot be done too late in the flow otherwise it +cleans other registers and things that were already configured, +causing initialization to fail. + +In order to fix this, move the function to the common code in trans.c +so it can be called directly from there at an earlier point, just +after the reset we already do during initialization. + +Fixes: 9a47cb988338 ("iwlwifi: pcie: add workaround for power gating in integrated 22000") +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=205719 +Cc: stable@ver.kernel.org # 5.4+ +Reported-by: Anders Kaseorg <andersk@mit.edu> +Signed-off-by: Luca Coelho <luciano.coelho@intel.com> +Signed-off-by: Kalle Valo <kvalo@codeaurora.org> +--- + .../net/wireless/intel/iwlwifi/pcie/trans-gen2.c | 25 ------------------ + drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 30 ++++++++++++++++++++++ + 2 files changed, 30 insertions(+), 25 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +index ca3bb4d65b00..df8455f14e4d 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +@@ -57,24 +57,6 @@ + #include "internal.h" + #include "fw/dbg.h" + +-static int iwl_pcie_gen2_force_power_gating(struct iwl_trans *trans) +-{ +- iwl_set_bits_prph(trans, HPM_HIPM_GEN_CFG, +- HPM_HIPM_GEN_CFG_CR_FORCE_ACTIVE); +- udelay(20); +- iwl_set_bits_prph(trans, HPM_HIPM_GEN_CFG, +- HPM_HIPM_GEN_CFG_CR_PG_EN | +- HPM_HIPM_GEN_CFG_CR_SLP_EN); +- udelay(20); +- iwl_clear_bits_prph(trans, HPM_HIPM_GEN_CFG, +- HPM_HIPM_GEN_CFG_CR_FORCE_ACTIVE); +- +- iwl_trans_sw_reset(trans); +- iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); +- +- return 0; +-} +- + /* + * Start up NIC's basic functionality after it has been reset + * (e.g. after platform boot, or shutdown via iwl_pcie_apm_stop()) +@@ -110,13 +92,6 @@ int iwl_pcie_gen2_apm_init(struct iwl_trans *trans) + + iwl_pcie_apm_config(trans); + +- if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000 && +- trans->cfg->integrated) { +- ret = iwl_pcie_gen2_force_power_gating(trans); +- if (ret) +- return ret; +- } +- + ret = iwl_finish_nic_init(trans, trans->trans_cfg); + if (ret) + return ret; +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +index 6961f00ff812..d3db38c3095b 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +@@ -1783,6 +1783,29 @@ static int iwl_trans_pcie_clear_persistence_bit(struct iwl_trans *trans) + return 0; + } + ++static int iwl_pcie_gen2_force_power_gating(struct iwl_trans *trans) ++{ ++ int ret; ++ ++ ret = iwl_finish_nic_init(trans, trans->trans_cfg); ++ if (ret < 0) ++ return ret; ++ ++ iwl_set_bits_prph(trans, HPM_HIPM_GEN_CFG, ++ HPM_HIPM_GEN_CFG_CR_FORCE_ACTIVE); ++ udelay(20); ++ iwl_set_bits_prph(trans, HPM_HIPM_GEN_CFG, ++ HPM_HIPM_GEN_CFG_CR_PG_EN | ++ HPM_HIPM_GEN_CFG_CR_SLP_EN); ++ udelay(20); ++ iwl_clear_bits_prph(trans, HPM_HIPM_GEN_CFG, ++ HPM_HIPM_GEN_CFG_CR_FORCE_ACTIVE); ++ ++ iwl_trans_pcie_sw_reset(trans); ++ ++ return 0; ++} ++ + static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans) + { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); +@@ -1802,6 +1825,13 @@ static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans) + + iwl_trans_pcie_sw_reset(trans); + ++ if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000 && ++ trans->cfg->integrated) { ++ err = iwl_pcie_gen2_force_power_gating(trans); ++ if (err) ++ return err; ++ } ++ + err = iwl_pcie_apm_init(trans); + if (err) + return err; +-- +cgit v1.2.1-1-g437b + |