aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/pcie/trans.c
diff options
context:
space:
mode:
authorLilach Edelstein <lilach.edelstein@intel.com>2013-01-16 04:34:49 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-02-01 05:27:22 -0500
commite56b04efc1f795da42cf1d9651b52a4a5bebd730 (patch)
treea9740ffd4d47ffb7b90507691a0a066c20f42a2d /drivers/net/wireless/iwlwifi/pcie/trans.c
parente139dc4aebf52a9c88552963b9794fd1dff036f1 (diff)
iwlwifi: move register access lock into transport
Move the reg_lock that protects HW register access into the transport implementation. Locking is no longer exposed, but handled internally in grab and release NIC access. This simplifies the users. Signed-off-by: Lilach Edelstein <lilach.edelstein@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/pcie/trans.c')
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c47
1 files changed, 31 insertions, 16 deletions
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 8692494c1c48..56d4f72500bc 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -806,11 +806,12 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans)
806} 806}
807#endif /* CONFIG_PM_SLEEP */ 807#endif /* CONFIG_PM_SLEEP */
808 808
809static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent) 809static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent,
810 unsigned long *flags)
810{ 811{
811 int ret; 812 int ret;
812 813 struct iwl_trans_pcie *pcie_trans = IWL_TRANS_GET_PCIE_TRANS(trans);
813 lockdep_assert_held(&trans->reg_lock); 814 spin_lock_irqsave(&pcie_trans->reg_lock, *flags);
814 815
815 /* this bit wakes up the NIC */ 816 /* this bit wakes up the NIC */
816 __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, 817 __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
@@ -846,16 +847,32 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent)
846 WARN_ONCE(1, 847 WARN_ONCE(1,
847 "Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)\n", 848 "Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)\n",
848 val); 849 val);
850 spin_unlock_irqrestore(&pcie_trans->reg_lock, *flags);
849 return false; 851 return false;
850 } 852 }
851 } 853 }
852 854
855 /*
856 * Fool sparse by faking we release the lock - sparse will
857 * track nic_access anyway.
858 */
859 __release(&pcie_trans->reg_lock);
853 return true; 860 return true;
854} 861}
855 862
856static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans) 863static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans,
864 unsigned long *flags)
857{ 865{
858 lockdep_assert_held(&trans->reg_lock); 866 struct iwl_trans_pcie *pcie_trans = IWL_TRANS_GET_PCIE_TRANS(trans);
867
868 lockdep_assert_held(&pcie_trans->reg_lock);
869
870 /*
871 * Fool sparse by faking we acquiring the lock - sparse will
872 * track nic_access anyway.
873 */
874 __acquire(&pcie_trans->reg_lock);
875
859 __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, 876 __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
860 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 877 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
861 /* 878 /*
@@ -865,6 +882,7 @@ static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans)
865 * scheduled on different CPUs (after we drop reg_lock). 882 * scheduled on different CPUs (after we drop reg_lock).
866 */ 883 */
867 mmiowb(); 884 mmiowb();
885 spin_unlock_irqrestore(&pcie_trans->reg_lock, *flags);
868} 886}
869 887
870static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr, 888static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr,
@@ -874,16 +892,14 @@ static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr,
874 int offs, ret = 0; 892 int offs, ret = 0;
875 u32 *vals = buf; 893 u32 *vals = buf;
876 894
877 spin_lock_irqsave(&trans->reg_lock, flags); 895 if (iwl_trans_grab_nic_access(trans, false, &flags)) {
878 if (iwl_trans_grab_nic_access(trans, false)) {
879 iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); 896 iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr);
880 for (offs = 0; offs < dwords; offs++) 897 for (offs = 0; offs < dwords; offs++)
881 vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); 898 vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
882 iwl_trans_release_nic_access(trans); 899 iwl_trans_release_nic_access(trans, &flags);
883 } else { 900 } else {
884 ret = -EBUSY; 901 ret = -EBUSY;
885 } 902 }
886 spin_unlock_irqrestore(&trans->reg_lock, flags);
887 return ret; 903 return ret;
888} 904}
889 905
@@ -894,17 +910,15 @@ static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr,
894 int offs, ret = 0; 910 int offs, ret = 0;
895 u32 *vals = buf; 911 u32 *vals = buf;
896 912
897 spin_lock_irqsave(&trans->reg_lock, flags); 913 if (iwl_trans_grab_nic_access(trans, false, &flags)) {
898 if (iwl_trans_grab_nic_access(trans, false)) {
899 iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); 914 iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr);
900 for (offs = 0; offs < dwords; offs++) 915 for (offs = 0; offs < dwords; offs++)
901 iwl_write32(trans, HBUS_TARG_MEM_WDAT, 916 iwl_write32(trans, HBUS_TARG_MEM_WDAT,
902 vals ? vals[offs] : 0); 917 vals ? vals[offs] : 0);
903 iwl_trans_release_nic_access(trans); 918 iwl_trans_release_nic_access(trans, &flags);
904 } else { 919 } else {
905 ret = -EBUSY; 920 ret = -EBUSY;
906 } 921 }
907 spin_unlock_irqrestore(&trans->reg_lock, flags);
908 return ret; 922 return ret;
909} 923}
910 924
@@ -982,11 +996,12 @@ static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans)
982static void iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans, u32 reg, 996static void iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans, u32 reg,
983 u32 mask, u32 value) 997 u32 mask, u32 value)
984{ 998{
999 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
985 unsigned long flags; 1000 unsigned long flags;
986 1001
987 spin_lock_irqsave(&trans->reg_lock, flags); 1002 spin_lock_irqsave(&trans_pcie->reg_lock, flags);
988 __iwl_trans_pcie_set_bits_mask(trans, reg, mask, value); 1003 __iwl_trans_pcie_set_bits_mask(trans, reg, mask, value);
989 spin_unlock_irqrestore(&trans->reg_lock, flags); 1004 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
990} 1005}
991 1006
992static const char *get_fh_string(int cmd) 1007static const char *get_fh_string(int cmd)
@@ -1467,6 +1482,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
1467 trans->cfg = cfg; 1482 trans->cfg = cfg;
1468 trans_pcie->trans = trans; 1483 trans_pcie->trans = trans;
1469 spin_lock_init(&trans_pcie->irq_lock); 1484 spin_lock_init(&trans_pcie->irq_lock);
1485 spin_lock_init(&trans_pcie->reg_lock);
1470 init_waitqueue_head(&trans_pcie->ucode_write_waitq); 1486 init_waitqueue_head(&trans_pcie->ucode_write_waitq);
1471 1487
1472 /* W/A - seems to solve weird behavior. We need to remove this if we 1488 /* W/A - seems to solve weird behavior. We need to remove this if we
@@ -1533,7 +1549,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
1533 1549
1534 /* Initialize the wait queue for commands */ 1550 /* Initialize the wait queue for commands */
1535 init_waitqueue_head(&trans_pcie->wait_command_queue); 1551 init_waitqueue_head(&trans_pcie->wait_command_queue);
1536 spin_lock_init(&trans->reg_lock);
1537 1552
1538 snprintf(trans->dev_cmd_pool_name, sizeof(trans->dev_cmd_pool_name), 1553 snprintf(trans->dev_cmd_pool_name, sizeof(trans->dev_cmd_pool_name),
1539 "iwl_cmd_pool:%s", dev_name(trans->dev)); 1554 "iwl_cmd_pool:%s", dev_name(trans->dev));