diff options
Diffstat (limited to 'bcm4329/src/bcmsdio/sys/bcmsdh_linux.c')
-rw-r--r-- | bcm4329/src/bcmsdio/sys/bcmsdh_linux.c | 88 |
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 */ |