void* bcmsdh_probe(osl_t *osh, void *dev, void *sdioh, void *adapter_info, uint bus_type, uint bus_num, uint slot_num) { uint32 regs; bcmsdh_info_t *bcmsdh; uint32 vendevid; bcmsdh_os_info_t *bcmsdh_osinfo = NULL; bcmsdh = bcmsdh_attach(osh, sdioh, ®s); if (bcmsdh == NULL) { SDLX_MSG(("%s: bcmsdh_attach failed\n", __FUNCTION__)); goto err; } bcmsdh_osinfo = MALLOC(osh, sizeof(bcmsdh_os_info_t)); if (bcmsdh_osinfo == NULL) { SDLX_MSG(("%s: failed to allocate bcmsdh_os_info_t\n", __FUNCTION__)); goto err; } bzero((char *)bcmsdh_osinfo, sizeof(bcmsdh_os_info_t)); bcmsdh->os_cxt = bcmsdh_osinfo; bcmsdh_osinfo->sdioh = sdioh; bcmsdh_osinfo->dev = dev; osl_set_bus_handle(osh, bcmsdh); #if !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) if (dev && device_init_wakeup(dev, true) == 0) bcmsdh_osinfo->dev_wake_enabled = TRUE; #endif /* !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) */ #if defined(OOB_INTR_ONLY) spin_lock_init(&bcmsdh_osinfo->oob_irq_spinlock); /* Get customer specific OOB IRQ parametres: IRQ number as IRQ type */ bcmsdh_osinfo->oob_irq_num = wifi_platform_get_irq_number(adapter_info, &bcmsdh_osinfo->oob_irq_flags); if (bcmsdh_osinfo->oob_irq_num < 0) { SDLX_MSG(("%s: Host OOB irq is not defined\n", __FUNCTION__)); goto err; } #endif /* defined(BCMLXSDMMC) */ /* Read the vendor/device ID from the CIS */ vendevid = bcmsdh_query_device(bcmsdh); /* try to attach to the target device */ bcmsdh_osinfo->context = drvinfo.probe((vendevid >> 16), (vendevid & 0xFFFF), bus_num, slot_num, 0, bus_type, (void *)regs, osh, bcmsdh); if (bcmsdh_osinfo->context == NULL) { SDLX_MSG(("%s: device attach failed\n", __FUNCTION__)); goto err; } return bcmsdh; /* error handling */ err: if (bcmsdh != NULL) bcmsdh_detach(osh, bcmsdh); if (bcmsdh_osinfo != NULL) MFREE(osh, bcmsdh_osinfo, sizeof(bcmsdh_os_info_t)); return NULL; }
int bcmsdh_remove(bcmsdh_info_t *bcmsdh) { bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt; #if !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) if (bcmsdh_osinfo->dev) device_init_wakeup(bcmsdh_osinfo->dev, false); bcmsdh_osinfo->dev_wake_enabled = FALSE; #endif /* !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) */ drvinfo.remove(bcmsdh_osinfo->context); MFREE(bcmsdh->osh, bcmsdh->os_cxt, sizeof(bcmsdh_os_info_t)); bcmsdh_detach(bcmsdh->osh, bcmsdh); return 0; }
static #endif /* BCMLXSDMMC */ int bcmsdh_remove(struct device *dev) { bcmsdh_hc_t *sdhc, *prev; struct osl_info *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) { if (prev) prev->next = sdhc->next; else sdhcinfo = NULL; break; } prev = sdhc; } if (!sdhc) { SDLX_MSG(("%s: failed\n", __func__)); return 0; } /* release SDIO Host Controller info */ osh = sdhc->osh; kfree(sdhc); osl_detach(osh); #if !defined(BCMLXSDMMC) dev_set_drvdata(dev, NULL); #endif /* !defined(BCMLXSDMMC) */ return 0; }
static #endif /* BCMLXSDMMC */ int bcmsdh_probe(struct device *dev) { struct osl_info *osh = NULL; bcmsdh_hc_t *sdhc = NULL; unsigned long regs = 0; bcmsdh_info_t *sdh = NULL; #if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS) struct platform_device *pdev; struct resource *r; #endif /* BCMLXSDMMC */ int irq = 0; u32 vendevid; unsigned long irq_flags = 0; #if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS) pdev = to_platform_device(dev); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); if (!r || irq == NO_IRQ) return -ENXIO; #endif /* BCMLXSDMMC */ #if defined(OOB_INTR_ONLY) #ifdef HW_OOB irq_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE; #else irq_flags = IRQF_TRIGGER_FALLING; #endif /* HW_OOB */ irq = dhd_customer_oob_irq_map(&irq_flags); if (irq < 0) { SDLX_MSG(("%s: Host irq is not defined\n", __func__)); return 1; } #endif /* defined(OOB_INTR_ONLY) */ /* allocate SDIO Host Controller state info */ osh = osl_attach(dev, PCI_BUS); if (!osh) { SDLX_MSG(("%s: osl_attach failed\n", __func__)); goto err; } sdhc = kzalloc(sizeof(bcmsdh_hc_t), GFP_ATOMIC); if (!sdhc) { SDLX_MSG(("%s: out of memory\n", __func__)); goto err; } sdhc->osh = osh; sdhc->dev = (void *)dev; #ifdef BCMLXSDMMC sdh = bcmsdh_attach(osh, (void *)0, (void **)®s, irq); if (!sdh) { SDLX_MSG(("%s: bcmsdh_attach failed\n", __func__)); goto err; } #else sdh = bcmsdh_attach(osh, (void *)r->start, (void **)®s, irq); if (!sdh) { SDLX_MSG(("%s: bcmsdh_attach failed\n", __func__)); goto err; } #endif /* BCMLXSDMMC */ sdhc->sdh = sdh; 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; sdhcinfo = sdhc; /* Read the vendor/device ID from the CIS */ vendevid = bcmsdh_query_device(sdh); /* try to attach to the target device */ sdhc->ch = drvinfo.attach((vendevid >> 16), (vendevid & 0xFFFF), 0, 0, 0, 0, (void *)regs, NULL, sdh); if (!sdhc->ch) { SDLX_MSG(("%s: device attach failed\n", __func__)); goto err; } return 0; /* error handling */ err: if (sdhc) { if (sdhc->sdh) bcmsdh_detach(sdhc->osh, sdhc->sdh); kfree(sdhc); } if (osh) osl_detach(osh); return -ENODEV; }