Commit a27367d2 authored by Emmanuel Grumbach's avatar Emmanuel Grumbach Committed by Wey-Yi Guy

iwlagn: move sync_irq to transport layer

Since all the irq / tasklet is now handled in the transport layer, it should
give an API to ensure that all the irq / tasklet have finished running. This
will allow the upper layer to release all its resources.
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
parent 34c1b7ba
...@@ -2399,7 +2399,7 @@ void iwlagn_stop_device(struct iwl_priv *priv) ...@@ -2399,7 +2399,7 @@ void iwlagn_stop_device(struct iwl_priv *priv)
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
iwl_disable_interrupts(priv); iwl_disable_interrupts(priv);
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
iwl_synchronize_irq(priv); trans_sync_irq(priv);
/* device going down, Stop using ICT table */ /* device going down, Stop using ICT table */
iwl_disable_ict(priv); iwl_disable_ict(priv);
......
...@@ -3734,7 +3734,7 @@ void __devexit iwl_remove(struct iwl_priv * priv) ...@@ -3734,7 +3734,7 @@ void __devexit iwl_remove(struct iwl_priv * priv)
iwl_disable_interrupts(priv); iwl_disable_interrupts(priv);
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
iwl_synchronize_irq(priv); trans_sync_irq(priv);
iwl_dealloc_ucode(priv); iwl_dealloc_ucode(priv);
......
...@@ -118,14 +118,6 @@ int iwl_alloc_isr_ict(struct iwl_priv *priv); ...@@ -118,14 +118,6 @@ 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->bus.irq);
tasklet_kill(&priv->irq_tasklet);
}
static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd) static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd)
{ {
hdr->op_code = cmd; hdr->op_code = cmd;
......
...@@ -1243,6 +1243,10 @@ struct iwl_trans; ...@@ -1243,6 +1243,10 @@ struct iwl_trans;
* @tx_free: frees the tx memory * @tx_free: frees the tx memory
* @send_cmd:send a host command * @send_cmd:send a host command
* @send_cmd_pdu:send a host command: flags can be CMD_* * @send_cmd_pdu:send a host command: flags can be CMD_*
* @sync_irq: the upper layer will typically disable interrupt and call this
* handler. After this handler returns, it is guaranteed that all
* the ISR / tasklet etc... have finished running and the transport
* layer shall not pass any Rx.
* @free: release all the ressource for the transport layer itself such as * @free: release all the ressource for the transport layer itself such as
* irq, tasklet etc... * irq, tasklet etc...
*/ */
...@@ -1264,6 +1268,7 @@ struct iwl_trans_ops { ...@@ -1264,6 +1268,7 @@ struct iwl_trans_ops {
struct iwl_tx_cmd *tx_cmd, int txq_id, __le16 fc, bool ampdu, struct iwl_tx_cmd *tx_cmd, int txq_id, __le16 fc, bool ampdu,
struct iwl_rxon_context *ctx); struct iwl_rxon_context *ctx);
void (*sync_irq)(struct iwl_priv *priv);
void (*free)(struct iwl_priv *priv); void (*free)(struct iwl_priv *priv);
}; };
......
...@@ -705,6 +705,13 @@ static int iwl_trans_tx(struct iwl_priv *priv, struct sk_buff *skb, ...@@ -705,6 +705,13 @@ static int iwl_trans_tx(struct iwl_priv *priv, struct sk_buff *skb,
return 0; return 0;
} }
static void iwl_trans_sync_irq(struct iwl_priv *priv)
{
/* wait to make sure we flush pending tasklet*/
synchronize_irq(priv->bus.irq);
tasklet_kill(&priv->irq_tasklet);
}
static void iwl_trans_free(struct iwl_priv *priv) static void iwl_trans_free(struct iwl_priv *priv)
{ {
free_irq(priv->bus.irq, priv); free_irq(priv->bus.irq, priv);
...@@ -726,6 +733,7 @@ static const struct iwl_trans_ops trans_ops = { ...@@ -726,6 +733,7 @@ static const struct iwl_trans_ops trans_ops = {
.get_tx_cmd = iwl_trans_get_tx_cmd, .get_tx_cmd = iwl_trans_get_tx_cmd,
.tx = iwl_trans_tx, .tx = iwl_trans_tx,
.sync_irq = iwl_trans_sync_irq,
.free = iwl_trans_free, .free = iwl_trans_free,
}; };
......
...@@ -115,6 +115,11 @@ static inline int trans_tx(struct iwl_priv *priv, struct sk_buff *skb, ...@@ -115,6 +115,11 @@ static inline int trans_tx(struct iwl_priv *priv, struct sk_buff *skb,
return priv->trans.ops->tx(priv, skb, tx_cmd, txq_id, fc, ampdu, ctx); return priv->trans.ops->tx(priv, skb, tx_cmd, txq_id, fc, ampdu, ctx);
} }
static inline void trans_sync_irq(struct iwl_priv *priv)
{
priv->trans.ops->sync_irq(priv);
}
static inline void trans_free(struct iwl_priv *priv) static inline void trans_free(struct iwl_priv *priv)
{ {
priv->trans.ops->free(priv); priv->trans.ops->free(priv);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment