mirror of https://gitee.com/openkylin/linux.git
iwlagn: refactor down path
The iwl_down path really consists of multiple things, refactor out the hardware resetting (including, of course, related software state like irqs). Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
This commit is contained in:
parent
1a10f43313
commit
bc4f8adac6
|
@ -2293,3 +2293,33 @@ void iwlagn_remove_notification(struct iwl_priv *priv,
|
|||
list_del(&wait_entry->list);
|
||||
spin_unlock_bh(&priv->_agn.notif_wait_lock);
|
||||
}
|
||||
|
||||
void iwlagn_stop_device(struct iwl_priv *priv)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
/* stop and reset the on-board processor */
|
||||
iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
|
||||
|
||||
/* tell the device to stop sending interrupts */
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
iwl_disable_interrupts(priv);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
iwl_synchronize_irq(priv);
|
||||
|
||||
/* device going down, Stop using ICT table */
|
||||
iwl_disable_ict(priv);
|
||||
|
||||
iwlagn_txq_ctx_stop(priv);
|
||||
iwlagn_rxq_stop(priv);
|
||||
|
||||
/* Power-down device's busmaster DMA clocks */
|
||||
iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
|
||||
udelay(5);
|
||||
|
||||
/* Make sure (redundant) we've released our request to stay awake */
|
||||
iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
|
||||
|
||||
/* Stop the device, and put it in low power state */
|
||||
iwl_apm_stop(priv);
|
||||
}
|
||||
|
|
|
@ -846,14 +846,6 @@ static void iwl_rx_handle(struct iwl_priv *priv)
|
|||
iwlagn_rx_queue_restock(priv);
|
||||
}
|
||||
|
||||
/* call this function to flush any scheduled tasklet */
|
||||
static inline void iwl_synchronize_irq(struct iwl_priv *priv)
|
||||
{
|
||||
/* wait to make sure we flush pending tasklet*/
|
||||
synchronize_irq(priv->pci_dev->irq);
|
||||
tasklet_kill(&priv->irq_tasklet);
|
||||
}
|
||||
|
||||
/* tasklet for iwlagn interrupt */
|
||||
static void iwl_irq_tasklet(struct iwl_priv *priv)
|
||||
{
|
||||
|
@ -2338,7 +2330,6 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv);
|
|||
|
||||
static void __iwl_down(struct iwl_priv *priv)
|
||||
{
|
||||
unsigned long flags;
|
||||
int exit_pending;
|
||||
|
||||
IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
|
||||
|
@ -2370,15 +2361,6 @@ static void __iwl_down(struct iwl_priv *priv)
|
|||
if (!exit_pending)
|
||||
clear_bit(STATUS_EXIT_PENDING, &priv->status);
|
||||
|
||||
/* stop and reset the on-board processor */
|
||||
iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
|
||||
|
||||
/* tell the device to stop sending interrupts */
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
iwl_disable_interrupts(priv);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
iwl_synchronize_irq(priv);
|
||||
|
||||
if (priv->mac80211_registered)
|
||||
ieee80211_stop_queues(priv->hw);
|
||||
|
||||
|
@ -2392,21 +2374,7 @@ static void __iwl_down(struct iwl_priv *priv)
|
|||
test_bit(STATUS_EXIT_PENDING, &priv->status) <<
|
||||
STATUS_EXIT_PENDING;
|
||||
|
||||
/* device going down, Stop using ICT table */
|
||||
iwl_disable_ict(priv);
|
||||
|
||||
iwlagn_txq_ctx_stop(priv);
|
||||
iwlagn_rxq_stop(priv);
|
||||
|
||||
/* Power-down device's busmaster DMA clocks */
|
||||
iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
|
||||
udelay(5);
|
||||
|
||||
/* Make sure (redundant) we've released our request to stay awake */
|
||||
iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
|
||||
|
||||
/* Stop the device, and put it in low power state */
|
||||
iwl_apm_stop(priv);
|
||||
iwlagn_stop_device(priv);
|
||||
|
||||
dev_kfree_skb(priv->beacon_skb);
|
||||
priv->beacon_skb = NULL;
|
||||
|
|
|
@ -120,6 +120,17 @@ int iwl_alloc_isr_ict(struct iwl_priv *priv);
|
|||
void iwl_free_isr_ict(struct iwl_priv *priv);
|
||||
irqreturn_t iwl_isr_ict(int irq, void *data);
|
||||
|
||||
/* call this function to flush any scheduled tasklet */
|
||||
static inline void iwl_synchronize_irq(struct iwl_priv *priv)
|
||||
{
|
||||
/* wait to make sure we flush pending tasklet*/
|
||||
synchronize_irq(priv->pci_dev->irq);
|
||||
tasklet_kill(&priv->irq_tasklet);
|
||||
}
|
||||
|
||||
|
||||
void iwlagn_stop_device(struct iwl_priv *priv);
|
||||
|
||||
/* tx queue */
|
||||
void iwlagn_set_wr_ptrs(struct iwl_priv *priv,
|
||||
int txq_id, u32 index);
|
||||
|
|
Loading…
Reference in New Issue