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);
|
list_del(&wait_entry->list);
|
||||||
spin_unlock_bh(&priv->_agn.notif_wait_lock);
|
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);
|
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 */
|
/* tasklet for iwlagn interrupt */
|
||||||
static void iwl_irq_tasklet(struct iwl_priv *priv)
|
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)
|
static void __iwl_down(struct iwl_priv *priv)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
int exit_pending;
|
int exit_pending;
|
||||||
|
|
||||||
IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
|
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)
|
if (!exit_pending)
|
||||||
clear_bit(STATUS_EXIT_PENDING, &priv->status);
|
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)
|
if (priv->mac80211_registered)
|
||||||
ieee80211_stop_queues(priv->hw);
|
ieee80211_stop_queues(priv->hw);
|
||||||
|
|
||||||
|
@ -2392,21 +2374,7 @@ static void __iwl_down(struct iwl_priv *priv)
|
||||||
test_bit(STATUS_EXIT_PENDING, &priv->status) <<
|
test_bit(STATUS_EXIT_PENDING, &priv->status) <<
|
||||||
STATUS_EXIT_PENDING;
|
STATUS_EXIT_PENDING;
|
||||||
|
|
||||||
/* device going down, Stop using ICT table */
|
iwlagn_stop_device(priv);
|
||||||
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);
|
|
||||||
|
|
||||||
dev_kfree_skb(priv->beacon_skb);
|
dev_kfree_skb(priv->beacon_skb);
|
||||||
priv->beacon_skb = NULL;
|
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);
|
void iwl_free_isr_ict(struct iwl_priv *priv);
|
||||||
irqreturn_t iwl_isr_ict(int irq, void *data);
|
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 */
|
/* tx queue */
|
||||||
void iwlagn_set_wr_ptrs(struct iwl_priv *priv,
|
void iwlagn_set_wr_ptrs(struct iwl_priv *priv,
|
||||||
int txq_id, u32 index);
|
int txq_id, u32 index);
|
||||||
|
|
Loading…
Reference in New Issue