aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/pcie/trans.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-12-27 15:43:48 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-02-05 08:39:12 -0500
commit2bfb50924c7e92362ac937aef2ab56bc7bd3ca52 (patch)
tree26518070c19eb9cfb38ab48cda31fe16c1235433 /drivers/net/wireless/iwlwifi/pcie/trans.c
parentc9f7a8ab7792b48259af6e94706a5d02dd74caef (diff)
iwlwifi: use threaded interrupt handler
With new transports coming up, move to threaded interrupt handling now. This has the advantage that we can use the same locking scheme with all different transports we may need to implement. Note that the TX path obviously still runs in a tasklet, so some spin_lock() calls need to change to spin_lock_bh() calls to properly lock out the TX path. In my test on a Calpella platform this has no impact on throughput or latency. Also add lockdep annotations to avoid lockups due to catch sending synchronous commands or using locks that connect with them from the irq thread. Reviewed-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.c11
1 files changed, 4 insertions, 7 deletions
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 56d4f72500bc..17bedc50e753 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -760,7 +760,6 @@ void iwl_trans_pcie_free(struct iwl_trans *trans)
760 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 760 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
761 761
762 synchronize_irq(trans_pcie->pci_dev->irq); 762 synchronize_irq(trans_pcie->pci_dev->irq);
763 tasklet_kill(&trans_pcie->irq_tasklet);
764 763
765 iwl_pcie_tx_free(trans); 764 iwl_pcie_tx_free(trans);
766 iwl_pcie_rx_free(trans); 765 iwl_pcie_rx_free(trans);
@@ -1480,6 +1479,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
1480 1479
1481 trans->ops = &trans_ops_pcie; 1480 trans->ops = &trans_ops_pcie;
1482 trans->cfg = cfg; 1481 trans->cfg = cfg;
1482 trans_lockdep_init(trans);
1483 trans_pcie->trans = trans; 1483 trans_pcie->trans = trans;
1484 spin_lock_init(&trans_pcie->irq_lock); 1484 spin_lock_init(&trans_pcie->irq_lock);
1485 spin_lock_init(&trans_pcie->reg_lock); 1485 spin_lock_init(&trans_pcie->reg_lock);
@@ -1567,15 +1567,12 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
1567 1567
1568 trans_pcie->inta_mask = CSR_INI_SET_MASK; 1568 trans_pcie->inta_mask = CSR_INI_SET_MASK;
1569 1569
1570 tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long))
1571 iwl_pcie_tasklet, (unsigned long)trans);
1572
1573 if (iwl_pcie_alloc_ict(trans)) 1570 if (iwl_pcie_alloc_ict(trans))
1574 goto out_free_cmd_pool; 1571 goto out_free_cmd_pool;
1575 1572
1576 err = request_irq(pdev->irq, iwl_pcie_isr_ict, 1573 if (request_threaded_irq(pdev->irq, iwl_pcie_isr_ict,
1577 IRQF_SHARED, DRV_NAME, trans); 1574 iwl_pcie_irq_handler,
1578 if (err) { 1575 IRQF_SHARED, DRV_NAME, trans)) {
1579 IWL_ERR(trans, "Error allocating IRQ %d\n", pdev->irq); 1576 IWL_ERR(trans, "Error allocating IRQ %d\n", pdev->irq);
1580 goto out_free_ict; 1577 goto out_free_ict;
1581 } 1578 }