wl1271: Fix event handling mechanism
authorJuuso Oikarinen <juuso.oikarinen@nokia.com>
Tue, 13 Oct 2009 09:47:54 +0000 (12:47 +0300)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 27 Oct 2009 20:48:11 +0000 (16:48 -0400)
The event handling mechanism could miss events if multiple events would
occur simultaneously. Fix event handling mechanism to process all
events.

Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Reviewed-by: Luciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/wl12xx/wl1271_event.c
drivers/net/wireless/wl12xx/wl1271_event.h
drivers/net/wireless/wl12xx/wl1271_main.c

index e2d7758ba1c940665bc3fb21776e36f006d6f4fb..a4b11e43f0db11603f7849321b87f8f8c1e1df1c 100644 (file)
@@ -126,7 +126,7 @@ void wl1271_event_mbox_config(struct wl1271 *wl)
                     wl->mbox_ptr[0], wl->mbox_ptr[1]);
 }
 
-int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num)
+int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num, bool do_ack)
 {
        struct event_mailbox mbox;
        int ret;
@@ -146,7 +146,9 @@ int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num)
                return ret;
 
        /* then we let the firmware know it can go on...*/
-       wl1271_spi_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK);
+       if (do_ack)
+               wl1271_spi_write32(wl, ACX_REG_INTERRUPT_TRIG,
+                                  INTR_TRIG_EVENT_ACK);
 
        return 0;
 }
index 2cdce7c34bf0ef449254975df28c13e969164b79..adc4653b2616fa1bf670650d418e25f0c17bc739 100644 (file)
@@ -105,6 +105,6 @@ struct event_mailbox {
 
 int wl1271_event_unmask(struct wl1271 *wl);
 void wl1271_event_mbox_config(struct wl1271 *wl);
-int wl1271_event_handle(struct wl1271 *wl, u8 mbox);
+int wl1271_event_handle(struct wl1271 *wl, u8 mbox, bool do_ack);
 
 #endif
index 19dbdb1b38abe5ecfbe42031a0813be30d3883bb..d6d1a4c1b11464cd45fc9fecc0d3ab992f44453d 100644 (file)
@@ -437,14 +437,15 @@ static void wl1271_irq_work(struct work_struct *work)
 
        intr &= WL1271_INTR_MASK;
 
-       if (intr & (WL1271_ACX_INTR_EVENT_A |
-                   WL1271_ACX_INTR_EVENT_B)) {
-               wl1271_debug(DEBUG_IRQ,
-                            "WL1271_ACX_INTR_EVENT (0x%x)", intr);
-               if (intr & WL1271_ACX_INTR_EVENT_A)
-                       wl1271_event_handle(wl, 0);
-               else
-                       wl1271_event_handle(wl, 1);
+       if (intr & WL1271_ACX_INTR_EVENT_A) {
+               bool do_ack = (intr & WL1271_ACX_INTR_EVENT_B) ? false : true;
+               wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_A");
+               wl1271_event_handle(wl, 0, do_ack);
+       }
+
+       if (intr & WL1271_ACX_INTR_EVENT_B) {
+               wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_B");
+               wl1271_event_handle(wl, 1, true);
        }
 
        if (intr & WL1271_ACX_INTR_INIT_COMPLETE)