Skip to content

Commit 0df36b9

Browse files
lucacoelhoKalle Valo
authored andcommitted
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: 9a47cb9 ("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>
1 parent db5cce1 commit 0df36b9

File tree

2 files changed

+30
-25
lines changed

2 files changed

+30
-25
lines changed

drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -57,24 +57,6 @@
5757
#include "internal.h"
5858
#include "fw/dbg.h"
5959

60-
static int iwl_pcie_gen2_force_power_gating(struct iwl_trans *trans)
61-
{
62-
iwl_set_bits_prph(trans, HPM_HIPM_GEN_CFG,
63-
HPM_HIPM_GEN_CFG_CR_FORCE_ACTIVE);
64-
udelay(20);
65-
iwl_set_bits_prph(trans, HPM_HIPM_GEN_CFG,
66-
HPM_HIPM_GEN_CFG_CR_PG_EN |
67-
HPM_HIPM_GEN_CFG_CR_SLP_EN);
68-
udelay(20);
69-
iwl_clear_bits_prph(trans, HPM_HIPM_GEN_CFG,
70-
HPM_HIPM_GEN_CFG_CR_FORCE_ACTIVE);
71-
72-
iwl_trans_sw_reset(trans);
73-
iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
74-
75-
return 0;
76-
}
77-
7860
/*
7961
* Start up NIC's basic functionality after it has been reset
8062
* (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)
11092

11193
iwl_pcie_apm_config(trans);
11294

113-
if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000 &&
114-
trans->cfg->integrated) {
115-
ret = iwl_pcie_gen2_force_power_gating(trans);
116-
if (ret)
117-
return ret;
118-
}
119-
12095
ret = iwl_finish_nic_init(trans, trans->trans_cfg);
12196
if (ret)
12297
return ret;

drivers/net/wireless/intel/iwlwifi/pcie/trans.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1783,6 +1783,29 @@ static int iwl_trans_pcie_clear_persistence_bit(struct iwl_trans *trans)
17831783
return 0;
17841784
}
17851785

1786+
static int iwl_pcie_gen2_force_power_gating(struct iwl_trans *trans)
1787+
{
1788+
int ret;
1789+
1790+
ret = iwl_finish_nic_init(trans, trans->trans_cfg);
1791+
if (ret < 0)
1792+
return ret;
1793+
1794+
iwl_set_bits_prph(trans, HPM_HIPM_GEN_CFG,
1795+
HPM_HIPM_GEN_CFG_CR_FORCE_ACTIVE);
1796+
udelay(20);
1797+
iwl_set_bits_prph(trans, HPM_HIPM_GEN_CFG,
1798+
HPM_HIPM_GEN_CFG_CR_PG_EN |
1799+
HPM_HIPM_GEN_CFG_CR_SLP_EN);
1800+
udelay(20);
1801+
iwl_clear_bits_prph(trans, HPM_HIPM_GEN_CFG,
1802+
HPM_HIPM_GEN_CFG_CR_FORCE_ACTIVE);
1803+
1804+
iwl_trans_pcie_sw_reset(trans);
1805+
1806+
return 0;
1807+
}
1808+
17861809
static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans)
17871810
{
17881811
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)
18021825

18031826
iwl_trans_pcie_sw_reset(trans);
18041827

1828+
if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000 &&
1829+
trans->cfg->integrated) {
1830+
err = iwl_pcie_gen2_force_power_gating(trans);
1831+
if (err)
1832+
return err;
1833+
}
1834+
18051835
err = iwl_pcie_apm_init(trans);
18061836
if (err)
18071837
return err;

0 commit comments

Comments
 (0)