diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 6c33e898b300..4d2b75d0212e 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -281,7 +281,6 @@ struct ath9k_htc_rxbuf { struct ath9k_htc_rx { struct list_head rxbuf; spinlock_t rxbuflock; - bool initialized; }; #define ATH9K_HTC_TX_CLEANUP_INTERVAL 50 /* ms */ diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 6de78ae85726..911eaa4f776a 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -910,6 +910,9 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, ath9k_init_leds(priv); ath9k_start_rfkill_poll(priv); + /* signal completion to ath9k_htc_rxep() and ath9k_wmi_event_tasklet() */ + smp_store_release(&priv->initialized, true); + return 0; err_world: @@ -966,10 +969,6 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, htc_handle->drv_priv = priv; - /* Allow ath9k_wmi_event_tasklet() to operate. */ - smp_wmb(); - priv->initialized = true; - return 0; err_init: diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index bed7ea2425a0..95f48c7dca15 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -1141,8 +1141,8 @@ void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb, struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL; unsigned long flags; - /* Check if ath9k_rx_init() completed. */ - if (!data_race(priv->rx.initialized)) + /* Check if ath9k_init_device() completed. */ + if (!smp_load_acquire(&priv->initialized)) goto err; spin_lock_irqsave(&priv->rx.rxbuflock, flags); @@ -1200,10 +1200,6 @@ int ath9k_rx_init(struct ath9k_htc_priv *priv) list_add_tail(&rxbuf->list, &priv->rx.rxbuf); } - /* Allow ath9k_htc_rxep() to operate. */ - smp_wmb(); - priv->rx.initialized = true; - return 0; err: diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 284e8c13b043..44e91815a159 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -146,6 +146,12 @@ void ath9k_wmi_event_tasklet(struct tasklet_struct *t) unsigned long flags; u16 cmd_id; + /* Check if ath9k_init_device() completed. */ + if (!smp_load_acquire(&priv->initialized)) { + tasklet_schedule(t); + return; + } + do { spin_lock_irqsave(&wmi->wmi_lock, flags); skb = __skb_dequeue(&wmi->wmi_event_queue); @@ -155,12 +161,6 @@ void ath9k_wmi_event_tasklet(struct tasklet_struct *t) } spin_unlock_irqrestore(&wmi->wmi_lock, flags); - /* Check if ath9k_htc_probe_device() completed. */ - if (!data_race(priv->initialized)) { - kfree_skb(skb); - continue; - } - hdr = (struct wmi_cmd_hdr *) skb->data; cmd_id = be16_to_cpu(hdr->command_id); wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr));