summaryrefslogtreecommitdiffstats
path: root/bcm4329/src/bcmsdio/sys/bcmsdh_linux.c
diff options
context:
space:
mode:
Diffstat (limited to 'bcm4329/src/bcmsdio/sys/bcmsdh_linux.c')
-rw-r--r--bcm4329/src/bcmsdio/sys/bcmsdh_linux.c88
1 files changed, 80 insertions, 8 deletions
diff --git a/bcm4329/src/bcmsdio/sys/bcmsdh_linux.c b/bcm4329/src/bcmsdio/sys/bcmsdh_linux.c
index 81b15b6..8ddffc6 100644
--- a/bcm4329/src/bcmsdio/sys/bcmsdh_linux.c
+++ b/bcm4329/src/bcmsdio/sys/bcmsdh_linux.c
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bcmsdh_linux.c,v 1.42.10.10.2.6 2009/04/10 19:13:00 Exp $
+ * $Id: bcmsdh_linux.c,v 1.42.10.10.2.8 2009/10/15 22:48:28 Exp $
*/
/**
@@ -41,6 +41,13 @@
#include <bcmdefs.h>
#include <bcmdevs.h>
+#if defined(OOB_INTR_ONLY)
+#include <linux/irq.h>
+extern void dhdsdio_isr(void * args);
+#include <bcmutils.h>
+#include <dngl_stats.h>
+#include <dhd.h>
+#endif /* defined(OOB_INTR_ONLY) */
#if defined(CONFIG_MACH_SANDGATE2G) || defined(CONFIG_MACH_LOGICPD_PXA270)
#if !defined(BCMPLATFORM_BUS)
#define BCMPLATFORM_BUS
@@ -67,6 +74,7 @@ struct bcmsdh_hc {
void *regs; /* SDIO Host Controller address */
bcmsdh_info_t *sdh; /* SDIO Host Controller handle */
void *ch;
+ unsigned int oob_irq;
};
static bcmsdh_hc_t *sdhcinfo = NULL;
@@ -176,6 +184,13 @@ int bcmsdh_probe(struct device *dev)
return -ENXIO;
#endif /* BCMLXSDMMC */
+#if defined(OOB_INTR_ONLY)
+ irq = dhd_customer_oob_irq_map();
+ if (irq < 0) {
+ SDLX_MSG(("%s: Host irq is not defined\n", __FUNCTION__));
+ return 1;
+ }
+#endif /* defined(OOB_INTR_ONLY) */
/* allocate SDIO Host Controller state info */
if (!(osh = osl_attach(dev, PCI_BUS, FALSE))) {
SDLX_MSG(("%s: osl_attach failed\n", __FUNCTION__));
@@ -206,7 +221,11 @@ int bcmsdh_probe(struct device *dev)
}
#endif /* BCMLXSDMMC */
sdhc->sdh = sdh;
+ sdhc->oob_irq = irq;
+ /* chain SDIO Host Controller info together */
+ sdhc->next = sdhcinfo;
+ sdhcinfo = sdhc;
/* Read the vendor/device ID from the CIS */
vendevid = bcmsdh_query_device(sdh);
@@ -218,10 +237,6 @@ int bcmsdh_probe(struct device *dev)
goto err;
}
- /* chain SDIO Host Controller info together */
- sdhc->next = sdhcinfo;
- sdhcinfo = sdhc;
-
return 0;
/* error handling */
@@ -244,6 +259,9 @@ int bcmsdh_remove(struct device *dev)
bcmsdh_hc_t *sdhc, *prev;
osl_t *osh;
+ sdhc = sdhcinfo;
+ drvinfo.detach(sdhc->ch);
+ bcmsdh_detach(sdhc->osh, sdhc->sdh);
/* find the SDIO Host Controller state for this pdev and take it out from the list */
for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) {
if (sdhc->dev == (void *)dev) {
@@ -260,9 +278,6 @@ int bcmsdh_remove(struct device *dev)
return 0;
}
- drvinfo.detach(sdhc->ch);
-
- bcmsdh_detach(sdhc->osh, sdhc->sdh);
/* release SDIO Host Controller info */
osh = sdhc->osh;
@@ -516,6 +531,63 @@ bcmsdh_unregister(void)
#endif /* BCMPLATFORM_BUS */
}
+#if defined(OOB_INTR_ONLY)
+static irqreturn_t wlan_oob_irq(int irq, void *dev_id)
+{
+ dhd_pub_t *dhdp;
+
+ dhdp = (dhd_pub_t *)sdhcinfo->dev->driver_data;
+
+ if (dhdp == NULL) {
+ disable_irq(sdhcinfo->oob_irq);
+ SDLX_MSG(("Out of band GPIO interrupt fired way too early\n"));
+ return IRQ_HANDLED;
+ }
+
+ WAKE_LOCK_TIMEOUT(dhdp, WAKE_LOCK_TMOUT, 25);
+
+ dhdsdio_isr((void *)dhdp->bus);
+
+ return IRQ_HANDLED;
+}
+
+int bcmsdh_register_oob_intr(void * dhdp)
+{
+ int error = 0;
+
+ SDLX_MSG(("%s Enter\n", __FUNCTION__));
+
+ sdhcinfo->dev->driver_data = dhdp;
+
+ set_irq_wake(sdhcinfo->oob_irq, 1);
+
+ /* Refer to customer Host IRQ docs about proper irqflags definition */
+ error = request_irq(sdhcinfo->oob_irq, wlan_oob_irq, IRQF_TRIGGER_FALLING,
+ "bcmsdh_sdmmc", NULL);
+
+ if (error)
+ return -ENODEV;
+
+ return 0;
+}
+
+void bcmsdh_unregister_oob_intr(void)
+{
+ SDLX_MSG(("%s: Enter\n", __FUNCTION__));
+
+ set_irq_wake(sdhcinfo->oob_irq, 0);
+ disable_irq(sdhcinfo->oob_irq); /* just in case.. */
+ free_irq(sdhcinfo->oob_irq, NULL);
+}
+
+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 */
extern uint sd_msglevel; /* Debug message level */