diff options
author | Lilach Edelstein <lilach.edelstein@intel.com> | 2013-01-16 04:34:49 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-02-01 05:27:22 -0500 |
commit | e56b04efc1f795da42cf1d9651b52a4a5bebd730 (patch) | |
tree | a9740ffd4d47ffb7b90507691a0a066c20f42a2d /drivers/net/wireless/iwlwifi/pcie/trans.c | |
parent | e139dc4aebf52a9c88552963b9794fd1dff036f1 (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.c | 47 |
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 | ||
809 | static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent) | 809 | static 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 | ||
856 | static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans) | 863 | static 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 | ||
870 | static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr, | 888 | static 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) | |||
982 | static void iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans, u32 reg, | 996 | static 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 | ||
992 | static const char *get_fh_string(int cmd) | 1007 | static 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)); |