iwlagn: refactor down path
authorJohannes Berg <johannes.berg@intel.com>
Wed, 13 Apr 2011 10:14:45 +0000 (03:14 -0700)
committerWey-Yi Guy <wey-yi.w.guy@intel.com>
Fri, 22 Apr 2011 17:02:34 +0000 (10:02 -0700)
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>
drivers/net/wireless/iwlwifi/iwl-agn-lib.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-agn.h

index e741128842bb25fb629ab416ed3ab5d58b26b7b2..5c7eeac74846e901baedff330c217bba88c5f1fd 100644 (file)
@@ -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);
+}
index 2845f63721102215ce2829a1dfbcc7f5bbaf642b..f3d905551298358c65055a52738fc26595a29082 100644 (file)
@@ -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;
index 078a23e5d99decfd05cd0a0081fcebe5a507a1a8..1211f457ee4cb521f810032a0ba0fe6b22d7b85c 100644 (file)
@@ -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);