void cmc7xx_sdio_reset(struct work_struct *work) { struct net_adapter *adapter = container_of(work, struct net_adapter, wimax_reset); u8 data[100]; sdio_claim_host(adapter->func); sdio_release_irq(adapter->func); sdio_release_host(adapter->func); if (wimax_cmc7xx_sdio_reset_comm(adapter->func->card)) dump_debug("%s: cmc7xx_sdio_reset_comm fail", __func__); sdio_claim_host(adapter->func); if (sdio_enable_func(adapter->func)) dump_debug("%s: sdio_enable_func fail", __func__); if (sdio_claim_irq(adapter->func, adapter_interrupt)) dump_debug("%s: sdio_claim_irq fail", __func__); if (sdio_set_block_size(adapter->func, 512)) dump_debug("%s: sdio_set_block_size fail", __func__); sdio_memcpy_toio(adapter->func, SDIO_TX_BANK_ADDR + 4, data, 32); sdio_release_host(adapter->func); }
static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev) { int err_ret; u32 fbraddr; u8 func; brcmf_dbg(TRACE, "\n"); /* Get the Card's common CIS address */ sdiodev->func_cis_ptr[0] = brcmf_sdioh_get_cisaddr(sdiodev, SDIO_CCCR_CIS); brcmf_dbg(INFO, "Card's Common CIS Ptr = 0x%x\n", sdiodev->func_cis_ptr[0]); /* Get the Card's function CIS (for each function) */ for (fbraddr = SDIO_FBR_BASE(1), func = 1; func <= sdiodev->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) { sdiodev->func_cis_ptr[func] = brcmf_sdioh_get_cisaddr(sdiodev, SDIO_FBR_CIS + fbraddr); brcmf_dbg(INFO, "Function %d CIS Ptr = 0x%x\n", func, sdiodev->func_cis_ptr[func]); } /* Enable Function 1 */ sdio_claim_host(sdiodev->func[1]); err_ret = sdio_enable_func(sdiodev->func[1]); sdio_release_host(sdiodev->func[1]); if (err_ret) brcmf_dbg(ERROR, "Failed to enable F1 Err: 0x%08x\n", err_ret); return false; }
/*! * \brief hif_sdio probe function * * hif_sdio probe function called by mmc driver when any matched SDIO function * is detected by it. * * \param func * \param id * * \retval 0 register successfully * \retval < 0 list error code here */ static int sdio_detect_probe ( struct sdio_func *func, const struct sdio_device_id *id ) { int chipId = 0; WMT_DETECT_INFO_FUNC("vendor(0x%x) device(0x%x) num(0x%x)\n", func->vendor, func->device, func->num); chipId = hif_sdio_match_chipid_by_dev_id(id); if ((0x6630 == chipId) && (1 == func->num)) { int ret = 0; g_func = func; WMT_DETECT_INFO_FUNC("autok function detected, func:0x%p\n", g_func); sdio_claim_host(func); ret = sdio_enable_func(func); sdio_release_host(func); if (ret) { WMT_DETECT_ERR_FUNC("sdio_enable_func failed!\n"); } } return 0; }
extern unsigned int sd_dvobj_init(_adapter * padapter){ struct dvobj_priv *psddev=&padapter->dvobjpriv; struct sdio_func *func=psddev->func; int ret; _func_enter_; //_rtw_init_sema(&psddev->init_finish,0); sdio_claim_host(func); ret=sdio_enable_func(func); if(ret){ RT_TRACE(_module_hci_intfs_c_,_drv_err_,("sd_dvobj_init: sdio_enable_func fail!!!!!\n")); return _FAIL; } RT_TRACE(_module_hci_intfs_c_,_drv_err_,("sd_dvobj_init: sdio_enable_func success!!!!!\n")); padapter->EepromAddressSize = 6; psddev->tx_block_mode=1; psddev->rx_block_mode=1; sdio_set_block_size(func, 512); psddev->block_transfer_len=512; psddev->blk_shiftbits=9; ret=sdio_claim_irq(func,sd_sync_int_hdl); sdio_release_host(func); psddev->sdio_himr=0xff; if(ret) return _FAIL; _func_exit_; return _SUCCESS; }
static int sdioh_sdmmc_card_enablefuncs(sdioh_info_t *sd) { int err_ret; uint32 fbraddr; uint8 func; /* Get the Card's common CIS address */ sd->com_cis_ptr = sdioh_sdmmc_get_cisaddr(sd, SDIO_CCCR_CIS); sd->func_cis_ptr[0] = sd->com_cis_ptr;//901=0x00001070 /* Get the Card's function CIS (for each function) */ for (fbraddr = SDIOD_FBR_STARTADDR, func = 1; func <= sd->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) { sd->func_cis_ptr[func] = sdioh_sdmmc_get_cisaddr(sd, SDIOD_FBR_CISPTR_0 + fbraddr); //printf("func_cis_ptr[%d]=0x%08x\n", func, sd->func_cis_ptr[func]); //901 func_cis_ptr[1]=0x00001000 //901 func_cis_ptr[2]=0x00001038 } /* Enable Function 1 */ err_ret = sdio_enable_func(gInstance->func[1]); if (err_ret) { BCMDEBUG("bcmsdh_sdmmc: Failed to enable F1 Err: 0x%08x", err_ret); } return FALSE; }
static int wl12xx_sdio_power_on(struct wl12xx_sdio_glue *glue) { int ret; struct sdio_func *func = dev_to_sdio_func(glue->dev); struct mmc_card *card = func->card; ret = pm_runtime_get_sync(&card->dev); if (ret < 0) { pm_runtime_put_noidle(&card->dev); dev_err(glue->dev, "%s: failed to get_sync(%d)\n", __func__, ret); return ret; } sdio_claim_host(func); /* * To guarantee that the SDIO card is power cycled, as required to make * the FW programming to succeed, let's do a brute force HW reset. */ mmc_hw_reset(card->host); sdio_enable_func(func); sdio_release_host(func); return 0; }
static int esdio_power_on(struct esp_sdio_ctrl *sctrl) { int err = 0; if (sctrl->off == false) return err; sdio_claim_host(sctrl->func); err = sdio_enable_func(sctrl->func); if (err) { esp_dbg(ESP_DBG_ERROR, "Unable to enable sdio func: %d\n", err); sdio_release_host(sctrl->func); return err; } sdio_release_host(sctrl->func); /* ensure device is up */ msleep(5); sctrl->off = false; return err; }
/** @brief This function handles client driver probe. * * @param func A pointer to sdio_func structure. * @param id A pointer to sdio_device_id structure. * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE/error code */ int woal_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) { int ret = MLAN_STATUS_SUCCESS; struct sdio_mmc_card *card = NULL; ENTER(); PRINTM(MMSG, "vendor=0x%4.04X device=0x%4.04X class=%d function=%d\n", func->vendor, func->device, func->class, func->num); card = kzalloc(sizeof(struct sdio_mmc_card), GFP_KERNEL); if (!card) { PRINTM(MFATAL, "Failed to allocate memory in probe function!\n"); LEAVE(); return -ENOMEM; } card->func = func; #ifdef MMC_QUIRK_BLKSZ_FOR_BYTE_MODE /* The byte mode patch is available in kernel MMC driver which fixes one issue in MP-A transfer. bit1: use func->cur_blksize for byte mode */ func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) func->card->quirks |= MMC_QUIRK_LENIENT_FN0; #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) /* wait for chip fully wake up */ if (!func->enable_timeout) func->enable_timeout = 200; #endif sdio_claim_host(func); ret = sdio_enable_func(func); if (ret) { sdio_disable_func(func); sdio_release_host(func); kfree(card); PRINTM(MFATAL, "sdio_enable_func() failed: ret=%d\n", ret); LEAVE(); return -EIO; } sdio_release_host(func); if (NULL == woal_add_card(card)) { PRINTM(MERROR, "woal_add_card failed\n"); kfree(card); sdio_claim_host(func); sdio_disable_func(func); sdio_release_host(func); ret = MLAN_STATUS_FAILURE; } LEAVE(); return ret; }
static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable) { struct sdio_func *func = wl_to_func(wl); int ret; /* Let the SDIO stack handle wlan_enable control, so we * keep host claimed while wlan is in use to keep wl1271 * alive. */ if (enable) { /* Power up the card */ ret = pm_runtime_get_sync(&func->dev); if (ret < 0) goto out; sdio_claim_host(func); sdio_enable_func(func); sdio_release_host(func); } else { sdio_claim_host(func); sdio_disable_func(func); sdio_release_host(func); /* Power down the card */ ret = pm_runtime_put_sync(&func->dev); } out: return ret; }
/* Probe Function to be called by SDIO stack when device is discovered */ static int cw1200_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) { struct sbus_priv *self; int status; cw1200_dbg(CW1200_DBG_INIT, "Probe called\n"); self = kzalloc(sizeof(*self), GFP_KERNEL); if (!self) { cw1200_dbg(CW1200_DBG_ERROR, "Can't allocate SDIO sbus_priv."); return -ENOMEM; } spin_lock_init(&self->lock); self->pdata = cw1200_get_platform_data(); self->func = func; sdio_set_drvdata(func, self); sdio_claim_host(func); sdio_enable_func(func); sdio_release_host(func); status = cw1200_probe(&cw1200_sdio_sbus_ops, self, &func->dev, &self->core); if (status) { sdio_claim_host(func); sdio_disable_func(func); sdio_release_host(func); sdio_set_drvdata(func, NULL); kfree(self); } return status; }
static int wl1271_sdio_power_on(struct wl1271 *wl) { struct sdio_func *func = wl_to_func(wl); int ret; /* If enabled, tell runtime PM not to power off the card */ if (pm_runtime_enabled(&func->dev)) { ret = pm_runtime_get_sync(&func->dev); if (ret) { printk (KERN_ERR "%s:pm_runtime_get_sync: %d\n", __func__, ret ); goto out; } } else { /* Runtime PM is disabled: power up the card manually */ ret = mmc_power_restore_host(func->card->host); if (ret < 0) { printk (KERN_ERR "%s:mmc_power_restore_host: %d\n", __func__, ret ); goto out; } } sdio_claim_host(func); sdio_enable_func(func); out: return ret; }
static int wl12xx_sdio_power_on(struct wl12xx_sdio_glue *glue) { int ret; struct sdio_func *func = dev_to_sdio_func(glue->dev); struct mmc_card *card = func->card; ret = pm_runtime_get_sync(&card->dev); if (ret) { /* * Runtime PM might be temporarily disabled, or the device * might have a positive reference counter. Make sure it is * really powered on. */ ret = mmc_power_restore_host(card->host); if (ret < 0) { pm_runtime_put_sync(&card->dev); goto out; } } sdio_claim_host(func); sdio_enable_func(func); sdio_release_host(func); out: return ret; }
static int emapi_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) { int rc; emapi_setfunc(NULL); printk("emapi router - class 0x%x, Vendor 0x%x, Device 0x%x\n", func->class, func->vendor, func->device); if (func->vendor != VENDOR_ID || func->device != DEVICE_ID) return -ENODEV; sdio_claim_host(func); rc = sdio_enable_func(func); if (rc) goto sdio_err1; rc = sdio_claim_irq(func, emapi_sdio_irq); if (rc) goto sdio_err2; rc = sdio_set_block_size(func, 512); if (rc) goto sdio_err2; emapi_setfunc(func); return 0; sdio_err2: sdio_disable_func(func); sdio_err1: sdio_release_host(func); return rc; }
static int mtk_sdio_probe ( struct sdio_func *func, const struct sdio_device_id *id ) { int ret = 0; int i = 0; //printk(KERN_INFO DRV_NAME "mtk_sdio_probe()\n"); ASSERT(func); ASSERT(id); //printk(KERN_INFO DRV_NAME "Basic struct size checking...\n"); //printk(KERN_INFO DRV_NAME "sizeof(struct device) = %d\n", sizeof(struct device)); //printk(KERN_INFO DRV_NAME "sizeof(struct mmc_host) = %d\n", sizeof(struct mmc_host)); //printk(KERN_INFO DRV_NAME "sizeof(struct mmc_card) = %d\n", sizeof(struct mmc_card)); //printk(KERN_INFO DRV_NAME "sizeof(struct mmc_driver) = %d\n", sizeof(struct mmc_driver)); //printk(KERN_INFO DRV_NAME "sizeof(struct mmc_data) = %d\n", sizeof(struct mmc_data)); //printk(KERN_INFO DRV_NAME "sizeof(struct mmc_command) = %d\n", sizeof(struct mmc_command)); //printk(KERN_INFO DRV_NAME "sizeof(struct mmc_request) = %d\n", sizeof(struct mmc_request)); //printk(KERN_INFO DRV_NAME "sizeof(struct sdio_func) = %d\n", sizeof(struct sdio_func)); //printk(KERN_INFO DRV_NAME "Card information checking...\n"); //printk(KERN_INFO DRV_NAME "func = 0x%p\n", func); //printk(KERN_INFO DRV_NAME "Number of info = %d:\n", func->card->num_info); for (i = 0; i < func->card->num_info; i++) { //printk(KERN_INFO DRV_NAME "info[%d]: %s\n", i, func->card->info[i]); } sdio_claim_host(func); ret = sdio_enable_func(func); sdio_release_host(func); if (ret) { //printk(KERN_INFO DRV_NAME"sdio_enable_func failed!\n"); goto out; } //printk(KERN_INFO DRV_NAME"sdio_enable_func done!\n"); if (pfWlanProbe((PVOID)func) != WLAN_STATUS_SUCCESS) { //printk(KERN_WARNING DRV_NAME"pfWlanProbe fail!call pfWlanRemove()\n"); pfWlanRemove(); ret = -1; } else { #if CFG_DBG_GPIO_PINS //printk(KERN_INFO "[%s] init debug gpio, 20100815 \n", __FUNCTION__); /* Debug pins initialization */ debug_gpio_init(); #endif } out: //printk(KERN_INFO DRV_NAME"mtk_sdio_probe() done(%d)\n", ret); return ret; }
int sdioDrv_EnableFunction(unsigned int uFunc) { PDEBUG("%s: func %d\n", __func__, uFunc); /* currently only wlan sdio function is supported */ BUG_ON(uFunc != SDIO_WLAN_FUNC); BUG_ON(tiwlan_func[uFunc] == NULL); return sdio_enable_func(tiwlan_func[uFunc]); }
int wlan_setup() { int ret; scratch_reg = 0x34; ret = sdio_enable_func(1); if(ret) { bufferPrintf("wlan: cannot enable function\r\n"); return -1; } ret = sdio_claim_irq(1, wlan_interrupt, 0); if(ret) { bufferPrintf("wlan: cannot claim irq\r\n"); return -1; } ioport = sdio_readb(1, 0x0, &ret); if(ret) { bufferPrintf("wlan: cannot read ioport\r\n"); return -1; } ioport |= sdio_readb(1, 0x1, &ret) << 8; if(ret) { bufferPrintf("wlan: cannot read ioport\r\n"); return -1; } ioport |= sdio_readb(1, 0x2, &ret) << 16; if(ret) { bufferPrintf("wlan: cannot read ioport\r\n"); return -1; } bufferPrintf("wlan: ioport = 0x%x\r\n", ioport); uint16_t scratch = wlan_read_scratch(&ret); if(ret) { bufferPrintf("wlan: cannot read scratch register\r\n"); return -1; } bufferPrintf("wlan: firmware status = 0x%x\r\n", scratch); return 0; }
static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev, uint regaddr, u8 *byte) { struct sdio_func *sdfunc = sdiodev->func[0]; int err_ret; /* * Can only directly write to some F0 registers. * Handle F2 enable/disable and Abort command * as a special case. */ if (regaddr == SDIO_CCCR_IOEx) { sdfunc = sdiodev->func[2]; if (sdfunc) { sdio_claim_host(sdfunc); if (*byte & SDIO_FUNC_ENABLE_2) { /* Enable Function 2 */ err_ret = sdio_enable_func(sdfunc); if (err_ret) brcmf_dbg(ERROR, "enable F2 failed:%d\n", err_ret); } else { /* Disable Function 2 */ err_ret = sdio_disable_func(sdfunc); if (err_ret) brcmf_dbg(ERROR, "Disable F2 failed:%d\n", err_ret); } sdio_release_host(sdfunc); } } else if ((regaddr == SDIO_CCCR_ABORT) || (regaddr == SDIO_CCCR_IENx)) { sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func), GFP_KERNEL); if (!sdfunc) return -ENOMEM; sdfunc->num = 0; sdio_claim_host(sdfunc); sdio_writeb(sdfunc, *byte, regaddr, &err_ret); sdio_release_host(sdfunc); kfree(sdfunc); } else if (regaddr < 0xF0) { brcmf_dbg(ERROR, "F0 Wr:0x%02x: write disallowed\n", regaddr); err_ret = -EPERM; } else { sdio_claim_host(sdfunc); sdio_f0_writeb(sdfunc, *byte, regaddr, &err_ret); sdio_release_host(sdfunc); } return err_ret; }
/* * Enable the SDIO function * * Tries to enable the SDIO function; might fail if it is still not * ready (in some hardware, the SDIO WiMAX function is only enabled * when we ask it to explicitly doing). Tries until a timeout is * reached. * * The @maxtries argument indicates how many times (at most) it should * be tried to enable the function. 0 means forever. This acts along * with the timeout (ie: it'll stop trying as soon as the maximum * number of tries is reached _or_ as soon as the timeout is reached). * * The reverse of this is...sdio_disable_function() * * Returns: 0 if the SDIO function was enabled, < 0 errno code on * error (-ENODEV when it was unable to enable the function). */ static int i2400ms_enable_function(struct i2400ms *i2400ms, unsigned maxtries) { struct sdio_func *func = i2400ms->func; u64 timeout; int err; struct device *dev = &func->dev; unsigned tries = 0; d_fnstart(3, dev, "(func %p)\n", func); /* Setup timeout (FIXME: This needs to read the CIS table to * get a real timeout) and then wait for the device to signal * it is ready */ timeout = get_jiffies_64() + ioe_timeout * HZ; err = -ENODEV; while (err != 0 && time_before64(get_jiffies_64(), timeout)) { sdio_claim_host(func); /* * There is a sillicon bug on the IWMC3200, where the * IOE timeout will cause problems on Moorestown * platforms (system hang). We explicitly overwrite * func->enable_timeout here to work around the issue. */ if (i2400ms->iwmc3200) func->enable_timeout = IWMC3200_IOR_TIMEOUT; err = sdio_enable_func(func); if (0 == err) { sdio_release_host(func); d_printf(2, dev, "SDIO function enabled\n"); goto function_enabled; } d_printf(2, dev, "SDIO function failed to enable: %d\n", err); sdio_release_host(func); if (maxtries > 0 && ++tries >= maxtries) { err = -ETIME; break; } msleep(I2400MS_INIT_SLEEP_INTERVAL); } /* If timed out, device is not there yet -- get -ENODEV so * the device driver core will retry later on. */ if (err == -ETIME) { dev_err(dev, "Can't enable WiMAX function; " " has the function been enabled?\n"); err = -ENODEV; } function_enabled: d_fnend(3, dev, "(func %p) = %d\n", func, err); return err; }
static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev, uint regaddr, u8 *byte) { struct sdio_func *sdfunc = sdiodev->func[0]; int err_ret; if (regaddr == SDIO_CCCR_IOEx) { sdfunc = sdiodev->func[2]; if (sdfunc) { sdio_claim_host(sdfunc); if (*byte & SDIO_FUNC_ENABLE_2) { err_ret = sdio_enable_func(sdfunc); if (err_ret) brcmf_dbg(ERROR, "enable F2 failed:%d\n", err_ret); } else { err_ret = sdio_disable_func(sdfunc); if (err_ret) brcmf_dbg(ERROR, "Disable F2 failed:%d\n", err_ret); } sdio_release_host(sdfunc); } } else if (regaddr == SDIO_CCCR_ABORT) { sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func), GFP_KERNEL); if (!sdfunc) return -ENOMEM; sdfunc->num = 0; sdio_claim_host(sdfunc); sdio_writeb(sdfunc, *byte, regaddr, &err_ret); sdio_release_host(sdfunc); kfree(sdfunc); } else if (regaddr < 0xF0) { brcmf_dbg(ERROR, "F0 Wr:0x%02x: write disallowed\n", regaddr); err_ret = -EPERM; } else { sdio_claim_host(sdfunc); sdio_f0_writeb(sdfunc, *byte, regaddr, &err_ret); sdio_release_host(sdfunc); } return err_ret; }
static void wl1271_sdio_set_power(struct wl1271 *wl, bool enable) { struct sdio_func *func = wl_to_func(wl); /* Let the SDIO stack handle wlan_enable control, so we * keep host claimed while wlan is in use to keep wl1271 * alive. */ if (enable) { sdio_claim_host(func); sdio_enable_func(func); } else { sdio_disable_func(func); sdio_release_host(func); } }
static u32 sdio_init(PADAPTER padapter) { struct dvobj_priv *psddev; PSDIO_DATA psdio_data; struct sdio_func *func; int err; _func_enter_; RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("+sdio_init\n")); if (padapter == NULL) { DBG_871X(KERN_ERR "%s: padapter is NULL!\n", __func__); err = -1; goto exit; } psddev = &padapter->dvobjpriv; psdio_data = &psddev->intf_data; func = psdio_data->func; //3 1. init SDIO bus sdio_claim_host(func); err = sdio_enable_func(func); if (err) { DBG_871X(KERN_CRIT "%s: sdio_enable_func FAIL(%d)!\n", __func__, err); goto release; } err = sdio_set_block_size(func, 512); if (err) { DBG_871X(KERN_CRIT "%s: sdio_set_block_size FAIL(%d)!\n", __func__, err); goto release; } psdio_data->block_transfer_len = 512; psdio_data->tx_block_mode = 1; psdio_data->rx_block_mode = 1; release: sdio_release_host(func); exit: _func_exit_; if (err) return _FAIL; return _SUCCESS; }
static int bcmsdio_probe(struct sdio_func *func, const struct sdio_device_id *id) { struct bcmsdio_data *data; int ret = 0; bcmsdio_mmc_host = func->card->host; BCM_DEBUG_PRINT(debuglevel, KERN_ALERT " WIMAX SDIO PROBE: NUM:x%x VID:x%x PID:x%x\n", func->num, func->vendor, func->device); if (func_data[func->num]) { BCM_DEBUG_PRINT(debuglevel, KERN_ALERT "Can not handle function-%d\n", func->num); ret = -ENXIO; goto end; } data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) { ret = -ENOMEM; goto end; } data->func = func; func_data[func->num] = data; /* Enable the function */ sdio_claim_host(func); sdio_enable_func(func); sdio_release_host(func); sdio_set_drvdata(func, data); ret = probe_notifier(func->num, &data->wimax_data,func->vendor, func->device); if (ret < 0) { BCM_DEBUG_PRINT(ERROR_LEVEL, KERN_ALERT "Probe notifier failed\n"); goto free_data; } return 0; free_data: func_data[func->num] = NULL; kfree(data); sdio_claim_host(func); sdio_disable_func(func); sdio_release_host(func); sdio_set_drvdata(func, NULL); end: return ret; }
static int wl1271_sdio_power_on(struct wl1271 *wl) { struct sdio_func *func = wl_to_func(wl); int ret; /* Power up the card */ ret = pm_runtime_get_sync(&func->dev); if (ret < 0) goto out; sdio_claim_host(func); sdio_enable_func(func); sdio_release_host(func); out: return ret; }
static int wl1251_sdio_set_power(struct wl1251 *wl, bool enable) { int ret = 0; struct sdio_func *func = wl_to_func(wl); wl1251_enter(); if (enable) { if (wl->set_power) wl->set_power(true); ret = mmc_power_restore_host(func->card->host); if (ret) { wl1251_error("failed to restore host power"); goto out; } wl1251_debug(DEBUG_PSM, "sdio_claim_host"); sdio_claim_host(func); wl1251_debug(DEBUG_PSM, "sdio_enable_func"); sdio_enable_func(func); wl1251_debug(DEBUG_PSM, "sdio_release_host"); sdio_release_host(func); wl1251_debug(DEBUG_PSM, "sdio_done"); } else { wl1251_debug(DEBUG_PSM, "sdio_claim_host"); sdio_claim_host(func); wl1251_debug(DEBUG_PSM, "sdio_disable_func"); sdio_disable_func(func); wl1251_debug(DEBUG_PSM, "sdio_release_host"); sdio_release_host(func); wl1251_debug(DEBUG_PSM, "power_save_host"); ret = mmc_power_save_host(func->card->host); if (ret) { wl1251_error("failed to disable host power"); goto out; } wl1251_debug(DEBUG_PSM, "power_save done"); if (wl->set_power) wl->set_power(false); } out: wl1251_leave(); return ret; }
/* Probe Function to be called by SDIO stack when device is discovered */ static int cw1200_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) { struct hwbus_priv *self; int status; pr_info("cw1200_wlan_sdio: Probe called\n"); /* We are only able to handle the wlan function */ if (func->num != 0x01) return -ENODEV; self = kzalloc(sizeof(*self), GFP_KERNEL); if (!self) { pr_err("Can't allocate SDIO hwbus_priv.\n"); return -ENOMEM; } func->card->quirks |= MMC_QUIRK_LENIENT_FN0; self->pdata = global_plat_data; /* FIXME */ self->func = func; sdio_set_drvdata(func, self); sdio_claim_host(func); sdio_enable_func(func); sdio_release_host(func); status = cw1200_sdio_irq_subscribe(self); status = cw1200_core_probe(&cw1200_sdio_hwbus_ops, self, &func->dev, &self->core, self->pdata->ref_clk, self->pdata->macaddr, self->pdata->sdd_file, self->pdata->have_5ghz); if (status) { cw1200_sdio_irq_unsubscribe(self); sdio_claim_host(func); sdio_disable_func(func); sdio_release_host(func); sdio_set_drvdata(func, NULL); kfree(self); } return status; }
/** * @brief This function probe the card * * @param func A pointer to sdio_func structure. * @param id A pointer to structure sd_device_id * @return BT_STATUS_SUCCESS or BT_STATUS_FAILURE */ static int sd_probe_card(struct sdio_func *func, const struct sdio_device_id *id) { int ret = BT_STATUS_SUCCESS; bt_private *priv = NULL; struct sdio_mmc_card *card = NULL; ENTER(); PRINTM(INFO, "vendor=0x%x,device=0x%x,class=%d,fn=%d\n", id->vendor, id->device, id->class, func->num); card = kzalloc(sizeof(struct sdio_mmc_card), GFP_KERNEL); if (!card) { ret = -ENOMEM; goto done; } card->func = func; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) /* wait for chip fully wake up */ if (!func->enable_timeout) func->enable_timeout = 200; #endif sdio_claim_host(func); ret = sdio_enable_func(func); if (ret) { sdio_disable_func(func); sdio_release_host(func); PRINTM(FATAL, "sdio_enable_func() failed: ret=%d\n", ret); kfree(card); LEAVE(); return -EIO; } sdio_release_host(func); priv = bt_add_card(card); if (!priv) { sdio_claim_host(func); sdio_disable_func(func); sdio_release_host(func); ret = BT_STATUS_FAILURE; kfree(card); } done: LEAVE(); return ret; }
/* * SDIO probe. * * This function probes an mwifiex device and registers it. It allocates * the card structure, enables SDIO function number and initiates the * device registration and initialization procedure by adding a logical * interface. */ static int mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) { int ret; struct sdio_mmc_card *card = NULL; pr_debug("info: vendor=0x%4.04X device=0x%4.04X class=%d function=%d\n", func->vendor, func->device, func->class, func->num); card = kzalloc(sizeof(struct sdio_mmc_card), GFP_KERNEL); if (!card) { pr_err("%s: failed to alloc memory\n", __func__); return -ENOMEM; } card->func = func; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; #endif sdio_claim_host(func); ret = sdio_enable_func(func); sdio_release_host(func); if (ret) { pr_err("%s: failed to enable function\n", __func__); kfree(card); return -EIO; } if (mwifiex_add_card(card, &add_remove_card_sem, &sdio_ops, MWIFIEX_SDIO)) { pr_err("%s: add card failed\n", __func__); kfree(card); sdio_claim_host(func); ret = sdio_disable_func(func); sdio_release_host(func); ret = -1; } return ret; }
/* Bus ops */ static int if_sdio_enable(struct iwm_priv *iwm) { struct iwm_sdio_priv *hw = iwm_to_if_sdio(iwm); int ret; sdio_claim_host(hw->func); ret = sdio_enable_func(hw->func); if (ret) { IWM_ERR(iwm, "Couldn't enable the device: is TOP driver " "loaded and functional?\n"); goto release_host; } iwm_reset(iwm); ret = sdio_claim_irq(hw->func, iwm_sdio_isr); if (ret) { IWM_ERR(iwm, "Failed to claim irq: %d\n", ret); goto release_host; } sdio_writeb(hw->func, 1, IWM_SDIO_INTR_ENABLE_ADDR, &ret); if (ret < 0) { IWM_ERR(iwm, "Couldn't enable INTR: %d\n", ret); goto release_irq; } sdio_release_host(hw->func); IWM_DBG_SDIO(iwm, INFO, "IWM SDIO enable\n"); return 0; release_irq: sdio_release_irq(hw->func); release_host: sdio_release_host(hw->func); return ret; }
void bcmsdio_enable_func(int func, int benable) { struct sdio_func *function = func_data[func]->func; if (function == NULL) { BCM_DEBUG_PRINT(ERROR_LEVEL, KERN_ALERT " ***Error: %s %d ***\n", __func__, __LINE__); return; } sdio_claim_host(function); if (benable) { sdio_enable_func(function); } else { sdio_disable_func(function); } sdio_release_host(function); return; }
static int wl1271_sdio_power_on(struct wl1271 *wl) { struct sdio_func *func = wl_to_func(wl); int ret; /* Make sure the card will not be powered off by runtime PM */ ret = pm_runtime_get_sync(&func->dev); if (ret < 0) goto out; /* Runtime PM might be disabled, so power up the card manually */ ret = mmc_power_restore_host(func->card->host); if (ret < 0) goto out; sdio_claim_host(func); sdio_enable_func(func); out: return ret; }