summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/iwlwifi/iwl-io.c
diff options
context:
space:
mode:
authorStanislaw Gruszka <sgruszka@redhat.com>2012-03-07 21:52:25 +0400
committerJohn W. Linville <linville@tuxdriver.com>2012-03-08 22:59:50 +0400
commit3a73a30049f20a0ff3ef1c5c10170a9c5539e042 (patch)
treeb14185ec9195512e1372d861f6b3382551ad6b7f /drivers/net/wireless/iwlwifi/iwl-io.c
parentbfe4b80e9f7385f34986736cdc094be56782109a (diff)
downloadlinux-3a73a30049f20a0ff3ef1c5c10170a9c5539e042.tar.xz
iwlwifi: cleanup/fix memory barriers
wmb(), rmb() are not needed when writel(), readl() are used as accessors for MMIO. We use them indirectly via iowrite32(), ioread32(). What is needed mmiowb(), for synchronizing writes coming from different CPUs on PCIe bridge (see in patch comments). This fortunately is not needed on x86, where mmiowb() is just defined as compiler barrier. As iwlwifi devices are most likely not used on anything other than x86, this is not so important fix. Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-io.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c
index fa69845954cf..081dd34d2387 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.c
+++ b/drivers/net/wireless/iwlwifi/iwl-io.c
@@ -136,6 +136,13 @@ void iwl_release_nic_access(struct iwl_trans *trans)
lockdep_assert_held(&trans->reg_lock);
__iwl_clear_bit(trans, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+ /*
+ * Above we read the CSR_GP_CNTRL register, which will flush
+ * any previous writes, but we need the write that clears the
+ * MAC_ACCESS_REQ bit to be performed before any other writes
+ * scheduled on different CPUs (after we drop reg_lock).
+ */
+ mmiowb();
}
u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg)
@@ -182,7 +189,6 @@ int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask,
static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 reg)
{
iwl_write32(trans, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
- rmb();
return iwl_read32(trans, HBUS_TARG_PRPH_RDAT);
}
@@ -190,7 +196,6 @@ static inline void __iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val)
{
iwl_write32(trans, HBUS_TARG_PRPH_WADDR,
((addr & 0x0000FFFF) | (3 << 24)));
- wmb();
iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val);
}
@@ -270,7 +275,6 @@ void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr,
spin_lock_irqsave(&trans->reg_lock, flags);
if (likely(iwl_grab_nic_access(trans))) {
iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr);
- rmb();
for (offs = 0; offs < words; offs++)
vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
iwl_release_nic_access(trans);
@@ -297,8 +301,6 @@ int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr,
spin_lock_irqsave(&trans->reg_lock, flags);
if (likely(iwl_grab_nic_access(trans))) {
iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr);
- wmb();
-
for (offs = 0; offs < words; offs++)
iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]);
iwl_release_nic_access(trans);