net: wireless: bcm4329: Fix HW_OOB interrupt processing
authorDmitry Shmidt <dimitrysh@google.com>
Sat, 28 Aug 2010 22:12:57 +0000 (15:12 -0700)
committerColin Cross <ccross@android.com>
Thu, 30 Sep 2010 00:49:46 +0000 (17:49 -0700)
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcm4329/Makefile
drivers/net/wireless/bcm4329/bcmsdh_linux.c
drivers/net/wireless/bcm4329/bcmsdh_sdmmc.c
drivers/net/wireless/bcm4329/dhd_sdio.c

index af6ca5c27c0db95f5ed5e719b8a53526b6934d82..594fa304754cfbd8343f09658421bb22e4036d70 100644 (file)
@@ -6,7 +6,7 @@ DHDCFLAGS = -DLINUX -DBCMDRIVER -DBCMDONGLEHOST -DDHDTHREAD -DBCMWPA2         \
        -Wall -Wstrict-prototypes -Werror -DOOB_INTR_ONLY -DCUSTOMER_HW2      \
        -DDHD_USE_STATIC_BUF -DMMC_SDIO_ABORT -DDHD_DEBUG_TRAP -DSOFTAP       \
        -DEMBEDDED_PLATFORM -DARP_OFFLOAD_SUPPORT                             \
-       -DGET_CUSTOM_MAC_ENABLE -DSET_RANDOM_MAC_SOFTAP -DCSCAN               \
+       -DGET_CUSTOM_MAC_ENABLE -DSET_RANDOM_MAC_SOFTAP -DCSCAN -DHW_OOB      \
        -Idrivers/net/wireless/bcm4329 -Idrivers/net/wireless/bcm4329/include
 
 DHDOFILES = dhd_linux.o linux_osl.o bcmutils.o dhd_common.o dhd_custom_gpio.o \
index 910b6d0afdcf949457b3cdd39085f1968701bb2a..644d6be577d68f5960d7ecd9aba635a5d0340607 100644 (file)
@@ -77,6 +77,9 @@ struct bcmsdh_hc {
        unsigned int oob_irq;
        unsigned long oob_flags; /* OOB Host specifiction as edge and etc */
        bool oob_irq_registered;
+#if defined(OOB_INTR_ONLY)
+       spinlock_t irq_lock;
+#endif
 };
 static bcmsdh_hc_t *sdhcinfo = NULL;
 
@@ -227,6 +230,9 @@ int bcmsdh_probe(struct device *dev)
        sdhc->oob_irq = irq;
        sdhc->oob_flags = irq_flags;
        sdhc->oob_irq_registered = FALSE;       /* to make sure.. */
+#if defined(OOB_INTR_ONLY)
+       spin_lock_init(&sdhc->irq_lock);
+#endif
 
        /* chain SDIO Host Controller info together */
        sdhc->next = sdhcinfo;
@@ -569,15 +575,34 @@ bcmsdh_unregister(void)
 #endif /* BCMPLATFORM_BUS */
 }
 
+
+
 #if defined(OOB_INTR_ONLY)
+void bcmsdh_oob_intr_set(bool enable)
+{
+       static bool curstate = 1;
+       unsigned long flags;
+
+       spin_lock_irqsave(&sdhcinfo->irq_lock, flags);
+       if (curstate != enable) {
+               if (enable)
+                       enable_irq(sdhcinfo->oob_irq);
+               else
+                       disable_irq_nosync(sdhcinfo->oob_irq);
+               curstate = enable;
+       }
+       spin_unlock_irqrestore(&sdhcinfo->irq_lock, flags);
+}
+
 static irqreturn_t wlan_oob_irq(int irq, void *dev_id)
 {
        dhd_pub_t *dhdp;
 
        dhdp = (dhd_pub_t *)dev_get_drvdata(sdhcinfo->dev);
 
+       bcmsdh_oob_intr_set(0);
+
        if (dhdp == NULL) {
-               disable_irq(sdhcinfo->oob_irq);
                SDLX_MSG(("Out of band GPIO interrupt fired way too early\n"));
                return IRQ_HANDLED;
        }
@@ -618,14 +643,6 @@ void bcmsdh_unregister_oob_intr(void)
        free_irq(sdhcinfo->oob_irq, NULL);
        sdhcinfo->oob_irq_registered = FALSE;
 }
-
-void bcmsdh_oob_intr_set(bool enable)
-{
-       if (enable)
-               enable_irq(sdhcinfo->oob_irq);
-       else
-               disable_irq(sdhcinfo->oob_irq);
-}
 #endif /* defined(OOB_INTR_ONLY) */
 /* Module parameters specific to each host-controller driver */
 
index 48d3f3775f0e276f3eb519028cad5dc192df072a..5a3ca3d118935c86c6707125adf1f86537cfc7b4 100644 (file)
@@ -676,6 +676,8 @@ sdioh_enable_hw_oob_intr(sdioh_info_t *sd, bool enable)
        else
                data = 4;       /* disable hw oob interrupt */
 
+       data |= 4;              /* Active HIGH */
+
        status = sdioh_request_byte(sd, SDIOH_WRITE, 0, 0xf2, &data);
        return status;
 }
index 94a17d713f792b23f43bd52e6ee88de8e1abf686..7b54f60e6f7243e462da722cd83661346c0fbbe5 100644 (file)
@@ -4218,6 +4218,11 @@ dhdsdio_dpc(dhd_bus_t *bus)
        bus->intstatus = intstatus;
 
 clkwait:
+
+#if defined(OOB_INTR_ONLY)
+       bcmsdh_oob_intr_set(1);
+#endif
+
        /* Re-enable interrupts to detect new device events (mailbox, rx frame)
         * or clock availability.  (Allows tx loop to check ipend if desired.)
         * (Unless register access seems hosed, as we may not be able to ACK...)