/* * Public entry points & extern's */ int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev) { int err_ret = 0; brcmf_dbg(TRACE, "\n"); sdiodev->num_funcs = 2; sdio_claim_host(sdiodev->func[1]); err_ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE); sdio_release_host(sdiodev->func[1]); if (err_ret) { brcmf_dbg(ERROR, "Failed to set F1 blocksize\n"); goto out; } sdio_claim_host(sdiodev->func[2]); err_ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE); sdio_release_host(sdiodev->func[2]); if (err_ret) { brcmf_dbg(ERROR, "Failed to set F2 blocksize\n"); goto out; } brcmf_sdioh_enablefuncs(sdiodev); out: brcmf_dbg(TRACE, "Done\n"); return err_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; }
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; }
/*----------------------------------------------------------------------------*/ BOOL glBusInit(PVOID pvData) { #if (MTK_WCN_HIF_SDIO == 0) int ret = 0; struct sdio_func *func = NULL; ASSERT(pvData); func = (struct sdio_func *)pvData; sdio_claim_host(func); ret = sdio_set_block_size(func, 512); sdio_release_host(func); if (ret) { /* printk(KERN_INFO DRV_NAME"sdio_set_block_size 512 failed!\n"); */ } else { /* printk(KERN_INFO DRV_NAME"sdio_set_block_size 512 done!\n"); */ } /* printk(KERN_INFO DRV_NAME"param: func->cur_blksize(%d)\n", func->cur_blksize); */ /* printk(KERN_INFO DRV_NAME"param: func->max_blksize(%d)\n", func->max_blksize); */ /* printk(KERN_INFO DRV_NAME"param: func->card->host->max_blk_size(%d)\n", func->card->host->max_blk_size); */ /* printk(KERN_INFO DRV_NAME"param: func->card->host->max_blk_count(%d)\n", func->card->host->max_blk_count); */ #endif return TRUE; } /* end of glBusInit() */
int bcmsdio_set_blk_size(int func, unsigned int blk_size) { struct sdio_func *function = func_data[BCM_SDIO_FN1]->func; int ret = 0; if (function == NULL) { BCM_DEBUG_PRINT(ERROR_LEVEL, KERN_ALERT " ***Error: %s %d ***\n", __func__, __LINE__); return -ENON_INTF_ERR; } sdio_claim_host(function); if(func != BCM_SDIO_FN0) ret = sdio_set_block_size(function, blk_size); else { BCM_SDIO_FN0_BLK_SIZE = blk_size; sdio_f0_writeb(function,BCM_SDIO_FN0_BLK_SIZE & 0xFF, 0x10, &ret); if(ret < 0) { BCM_DEBUG_PRINT(debuglevel, KERN_ALERT "failed to set the f0 block size"); } sdio_f0_writeb(function,(BCM_SDIO_FN0_BLK_SIZE >> 8) &0xFF , 0x11, &ret); if(ret < 0) { BCM_DEBUG_PRINT(debuglevel, KERN_ALERT "failed to set the f0 block size"); } } sdio_release_host(function); return ret; }
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 void wl1271_sdio_set_block_size(struct wl1271 *wl) { wl->block_size = TX_PAD_SDIO_BLK_SIZE; sdio_claim_host(wl->if_priv); sdio_set_block_size(wl->if_priv, TX_PAD_SDIO_BLK_SIZE); sdio_release_host(wl->if_priv); }
int sdioDrv_SetBlockSize(unsigned int uFunc, unsigned int blksz) { 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_set_block_size(tiwlan_func[uFunc], blksz); }
static void wl1271_sdio_set_block_size(struct device *child, unsigned int blksz) { struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent); struct sdio_func *func = dev_to_sdio_func(glue->dev); sdio_claim_host(func); sdio_set_block_size(func, blksz); sdio_release_host(func); }
/* * This function registers the SDIO device. * * SDIO IRQ is claimed, block size is set and driver data is initialized. */ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) { int ret = 0; struct sdio_mmc_card *card = adapter->card; struct sdio_func *func = card->func; /* save adapter pointer in card */ card->adapter = adapter; sdio_claim_host(func); /* Request the SDIO IRQ */ ret = sdio_claim_irq(func, mwifiex_sdio_interrupt); if (ret) { pr_err("claim irq failed: ret=%d\n", ret); goto disable_func; } /* Set block size */ ret = sdio_set_block_size(card->func, MWIFIEX_SDIO_BLOCK_SIZE); if (ret) { pr_err("cannot set SDIO block size\n"); ret = -1; goto release_irq; } sdio_release_host(func); sdio_set_drvdata(func, card); adapter->dev = &func->dev; switch (func->device) { case SDIO_DEVICE_ID_MARVELL_8786: strcpy(adapter->fw_name, SD8786_DEFAULT_FW_NAME); break; case SDIO_DEVICE_ID_MARVELL_8797: strcpy(adapter->fw_name, SD8797_DEFAULT_FW_NAME); break; case SDIO_DEVICE_ID_MARVELL_8787: default: strcpy(adapter->fw_name, SD8787_DEFAULT_FW_NAME); break; } return 0; release_irq: sdio_release_irq(func); disable_func: sdio_disable_func(func); sdio_release_host(func); adapter->card = NULL; return -1; }
/* * Public entry points & extern's */ extern sdioh_info_t * sdioh_attach(void *bar0, uint irq) { sdioh_info_t *sd; int err_ret; if (gInstance == NULL) return NULL; memset(&g_sdioh_info_t, 0, sizeof(sdioh_info_t)); sd = &g_sdioh_info_t; if (sd == NULL) return NULL; sd->num_funcs = 2; sd->sd_blockmode = TRUE; sd->use_client_ints = TRUE; sd->client_block_size[0] = 64; sd->client_block_size[1] = 64; err_ret = sdio_set_block_size(gInstance->func[1], 64); if (err_ret) { BCMDEBUG("bcmsdh_sdmmc: Failed to set F1 blocksize\n"); } if (gInstance->func[2]) { sd->client_block_size[2] = sd_f2_blocksize; err_ret = sdio_set_block_size(gInstance->func[2], sd_f2_blocksize); if (err_ret) { BCMDEBUG("bcmsdh_sdmmc: Failed to set F2 blocksize\n"); } } sdioh_sdmmc_card_enablefuncs(sd); gInstance->sd = sd; return sd; }
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; }
/* * Setup minimal device communication infrastructure needed to at * least be able to update the firmware. * * Note the ugly trick: if we are in the probe path * (i2400ms->debugfs_dentry == NULL), we only retry function * enablement one, to avoid racing with the iwmc3200 top controller. */ static int i2400ms_bus_setup(struct i2400m *i2400m) { int result; struct i2400ms *i2400ms = container_of(i2400m, struct i2400ms, i2400m); struct device *dev = i2400m_dev(i2400m); struct sdio_func *func = i2400ms->func; int retries; sdio_claim_host(func); result = sdio_set_block_size(func, I2400MS_BLK_SIZE); sdio_release_host(func); if (result < 0) { dev_err(dev, "Failed to set block size: %d\n", result); goto error_set_blk_size; } if (i2400ms->iwmc3200 && i2400ms->debugfs_dentry == NULL) retries = 1; else retries = 0; result = i2400ms_enable_function(i2400ms, retries); if (result < 0) { dev_err(dev, "Cannot enable SDIO function: %d\n", result); goto error_func_enable; } result = i2400ms_tx_setup(i2400ms); if (result < 0) goto error_tx_setup; result = i2400ms_rx_setup(i2400ms); if (result < 0) goto error_rx_setup; return 0; error_rx_setup: i2400ms_tx_release(i2400ms); error_tx_setup: sdio_claim_host(func); sdio_disable_func(func); sdio_release_host(func); error_func_enable: error_set_blk_size: return result; }
/** * @brief This function registers the device * * @param handle A pointer to moal_handle structure * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ mlan_status woal_register_dev(moal_handle *handle) { int ret = MLAN_STATUS_SUCCESS; struct sdio_mmc_card *card = handle->card; struct sdio_func *func; ENTER(); func = card->func; sdio_claim_host(func); /* Request the SDIO IRQ */ ret = sdio_claim_irq(func, woal_sdio_interrupt); if (ret) { PRINTM(MFATAL, "sdio_claim_irq failed: ret=%d\n", ret); goto release_host; } /* Set block size */ ret = sdio_set_block_size(card->func, MLAN_SDIO_BLOCK_SIZE); if (ret) { PRINTM(MERROR, "sdio_set_block_seize(): cannot set SDIO block size\n"); ret = MLAN_STATUS_FAILURE; goto release_irq; } sdio_release_host(func); sdio_set_drvdata(func, card); handle->hotplug_device = &func->dev; LEAVE(); return MLAN_STATUS_SUCCESS; release_irq: sdio_release_irq(func); release_host: sdio_release_host(func); handle->card = NULL; LEAVE(); return MLAN_STATUS_FAILURE; }
static void sd_intf_start(PADAPTER padapter) { struct dvobj_priv *psddev; struct sdio_func *func; int err; if (padapter == NULL) goto exit; psddev = &padapter->dvobjpriv; func = psddev->intf_data.func; //os/intf dep if (func) { sdio_claim_host(func); //according to practice, this is needed... 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_host; } err = sdio_claim_irq(func, &sd_sync_int_hdl); if (err) { DBG_871X(KERN_CRIT "%s: sdio_claim_irq FAIL(%d)!\n", __func__, err); goto release_host; } release_host: sdio_release_host(func); } //hal dep if (padapter->HalFunc.enable_interrupt) padapter->HalFunc.enable_interrupt(padapter); else { DBG_871X("%s HalFunc.enable_interrupt is %p\n", __FUNCTION__, padapter->HalFunc.enable_interrupt); goto exit; } exit: return; }
/* * This function registers the SDIO device. * * SDIO IRQ is claimed, block size is set and driver data is initialized. */ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) { int ret = 0; struct sdio_mmc_card *card = adapter->card; struct sdio_func *func = card->func; /* save adapter pointer in card */ card->adapter = adapter; sdio_claim_host(func); /* Request the SDIO IRQ */ ret = sdio_claim_irq(func, mwifiex_sdio_interrupt); if (ret) { pr_err("claim irq failed: ret=%d\n", ret); goto disable_func; } /* Set block size */ ret = sdio_set_block_size(card->func, MWIFIEX_SDIO_BLOCK_SIZE); if (ret) { pr_err("cannot set SDIO block size\n"); ret = -1; goto release_irq; } sdio_release_host(func); sdio_set_drvdata(func, card); adapter->dev = &func->dev; return 0; release_irq: sdio_release_irq(func); disable_func: sdio_disable_func(func); sdio_release_host(func); adapter->card = NULL; return -1; }
static int wl1271_sdio_power_on(struct wl1271 *wl) { struct sdio_func *func = wl_to_func(wl); int ret; printk("%s: function entered \n", __FUNCTION__); #if 1 /* Make sure the card will not be powered off by runtime PM */ #if 0 // Added Michael Carrier printk("%s: Calling pm_runtime_get_sync\n", __FUNCTION__); ret = pm_runtime_get_sync(&func->dev); printk("%s: pm_runtime_get_sync returned %d\n", __FUNCTION__, ret); if (ret < 0) goto out; /* Runtime PM might be disabled, so power up the card manually */ #endif printk("%s: Calling mmc_power_restore_host\n", __FUNCTION__); ret = mmc_power_restore_host(func->card->host); printk("%s: mmc_power_restore_host() returned %d\n", __FUNCTION__, ret); if (ret < 0) goto out; #else //wl1271_setpower(1); #endif /* if the power is already on (WHY?) ret == 1 */ ret = 0; sdio_claim_host(func); sdio_enable_func(func); /* Set the default block size in case it was modified */ sdio_set_block_size(func, 0); out: return ret; }
static u32 sdio_init(struct dvobj_priv *dvobj) { PSDIO_DATA psdio_data; struct sdio_func *func; int err; _func_enter_; psdio_data = &dvobj->intf_data; func = psdio_data->func; // 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); _func_exit_; if (err) return _FAIL; return _SUCCESS; }
static int hifDeviceResume(struct device *dev) { struct task_struct* pTask; const char *taskName; int (*taskFunc)(void *); struct sdio_func *func = dev_to_sdio_func(dev); A_STATUS ret = A_OK; HIF_DEVICE *device; device = getHifDevice(func); if (device->is_suspend) { /* enable the SDIO function */ sdio_claim_host(func); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) /* give us some time to enable, in ms */ func->enable_timeout = 100; #endif ret = sdio_enable_func(func); if (ret) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to enable AR6K: 0x%X\n", __FUNCTION__, ret)); sdio_release_host(func); return ret; } ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE); sdio_release_host(func); if (ret) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to set block size 0x%x AR6K: 0x%X\n", __FUNCTION__, HIF_MBOX_BLOCK_SIZE, ret)); return ret; } device->is_suspend = FALSE; /* create async I/O thread */ if (!device->async_task) { device->async_shutdown = 0; device->async_task = kthread_create(async_task, (void *)device, "AR6K Async"); if (IS_ERR(device->async_task)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create async task\n", __FUNCTION__)); return A_ERROR; } AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start async task\n")); wake_up_process(device->async_task ); } } if (!device->claimedContext) { printk("WARNING!!! No claimedContext during resume wlan\n"); taskFunc = startup_task; taskName = "AR6K startup"; } else { taskFunc = resume_task; taskName = "AR6K resume"; } /* create resume thread */ pTask = kthread_create(taskFunc, (void *)device, taskName); if (IS_ERR(pTask)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create resume task\n", __FUNCTION__)); return A_ERROR; } AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start resume task\n")); wake_up_process(pTask); return A_SUCCESS(ret) ? 0 : ret; }
static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id *id) { int ret; HIF_DEVICE * device; int count; struct task_struct* startup_task_struct; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: hifDeviceInserted, Function: 0x%X, Vendor ID: 0x%X, Device ID: 0x%X, block size: 0x%X/0x%X\n", func->num, func->vendor, func->device, func->max_blksize, func->cur_blksize)); addHifDevice(func); device = getHifDevice(func); spin_lock_init(&device->lock); spin_lock_init(&device->asynclock); DL_LIST_INIT(&device->ScatterReqHead); if (!nohifscattersupport) { /* try to allow scatter operation on all instances, * unless globally overridden */ device->scatter_enabled = TRUE; } /* enable the SDIO function */ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: claim\n")); sdio_claim_host(func); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: enable\n")); if ((id->device & MANUFACTURER_ID_AR6K_BASE_MASK) >= MANUFACTURER_ID_AR6003_BASE) { /* enable 4-bit ASYNC interrupt on AR6003 or later devices */ ret = Func0_CMD52WriteByte(func->card, CCCR_SDIO_IRQ_MODE_REG, SDIO_IRQ_MODE_ASYNC_4BIT_IRQ); if (ret) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: failed to enable 4-bit ASYNC IRQ mode %d \n",ret)); sdio_release_host(func); return ret; } AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: 4-bit ASYNC IRQ mode enabled\n")); } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) /* give us some time to enable, in ms */ func->enable_timeout = 100; #endif ret = sdio_enable_func(func); if (ret) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to enable AR6K: 0x%X\n", __FUNCTION__, ret)); sdio_release_host(func); return ret; } AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: set block size 0x%X\n", HIF_MBOX_BLOCK_SIZE)); ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE); sdio_release_host(func); if (ret) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to set block size 0x%x AR6K: 0x%X\n", __FUNCTION__, HIF_MBOX_BLOCK_SIZE, ret)); return ret; } /* Initialize the bus requests to be used later */ A_MEMZERO(device->busRequest, sizeof(device->busRequest)); for (count = 0; count < BUS_REQUEST_MAX_NUM; count ++) { sema_init(&device->busRequest[count].sem_req, 0); hifFreeBusRequest(device, &device->busRequest[count]); } /* create async I/O thread */ device->async_shutdown = 0; device->async_task = kthread_create(async_task, (void *)device, "AR6K Async"); if (IS_ERR(device->async_task)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create async task\n", __FUNCTION__)); return A_ERROR; } AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start async task\n")); sema_init(&device->sem_async, 0); wake_up_process(device->async_task ); /* create startup thread */ startup_task_struct = kthread_create(startup_task, (void *)device, "AR6K startup"); if (IS_ERR(startup_task_struct)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create startup task\n", __FUNCTION__)); return A_ERROR; } AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start startup task\n")); wake_up_process(startup_task_struct); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: return %d\n", ret)); return ret; }
static int wl1251_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) { int ret; struct wl1251 *wl; struct ieee80211_hw *hw; struct wl1251_sdio *wl_sdio; const struct wl1251_platform_data *wl1251_board_data; hw = wl1251_alloc_hw(); if (IS_ERR(hw)) return PTR_ERR(hw); wl = hw->priv; wl_sdio = kzalloc(sizeof(*wl_sdio), GFP_KERNEL); if (wl_sdio == NULL) { ret = -ENOMEM; goto out_free_hw; } sdio_claim_host(func); ret = sdio_enable_func(func); if (ret) goto release; sdio_set_block_size(func, 512); sdio_release_host(func); SET_IEEE80211_DEV(hw, &func->dev); wl_sdio->func = func; wl->if_priv = wl_sdio; wl->if_ops = &wl1251_sdio_ops; wl1251_board_data = wl1251_get_platform_data(); if (!IS_ERR(wl1251_board_data)) { wl->power_gpio = wl1251_board_data->power_gpio; wl->irq = wl1251_board_data->irq; wl->use_eeprom = wl1251_board_data->use_eeprom; } if (gpio_is_valid(wl->power_gpio)) { #if 0 /* Not in RHEL */ ret = devm_gpio_request(&func->dev, wl->power_gpio, "wl1251 power"); #else ret = gpio_request(wl->power_gpio, "wl1251 power"); #endif if (ret) { wl1251_error("Failed to request gpio: %d\n", ret); goto disable; } } if (wl->irq) { irq_set_status_flags(wl->irq, IRQ_NOAUTOEN); ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl); if (ret < 0) { wl1251_error("request_irq() failed: %d", ret); goto disable; } irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq; wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq; wl1251_info("using dedicated interrupt line"); } else { wl1251_sdio_ops.enable_irq = wl1251_sdio_enable_irq; wl1251_sdio_ops.disable_irq = wl1251_sdio_disable_irq; wl1251_info("using SDIO interrupt"); } ret = wl1251_init_ieee80211(wl); if (ret) goto out_free_irq; sdio_set_drvdata(func, wl); /* Tell PM core that we don't need the card to be powered now */ pm_runtime_put_noidle(&func->dev); return ret; out_free_irq: if (wl->irq) free_irq(wl->irq, wl); disable: sdio_claim_host(func); sdio_disable_func(func); release: sdio_release_host(func); kfree(wl_sdio); out_free_hw: wl1251_free_hw(wl); return ret; }
static int smssdio_probe(struct sdio_func *func, const struct sdio_device_id *id) { int ret; int board_id; struct smssdio_device *smsdev; struct smsdevice_params_t params; board_id = id->driver_data; smsdev = kzalloc(sizeof(struct smssdio_device), GFP_KERNEL); if (!smsdev) return -ENOMEM; smsdev->func = func; memset(¶ms, 0, sizeof(struct smsdevice_params_t)); params.device = &func->dev; params.buffer_size = 0x5000; /* ?? */ params.num_buffers = 22; /* ?? */ params.context = smsdev; snprintf(params.devpath, sizeof(params.devpath), "sdio\\%s", sdio_func_id(func)); params.sendrequest_handler = smssdio_sendrequest; params.device_type = sms_get_board(board_id)->type; if (params.device_type != SMS_STELLAR) params.flags |= SMS_DEVICE_FAMILY2; else { /* * FIXME: Stellar needs special handling... */ ret = -ENODEV; goto free; } ret = smscore_register_device(¶ms, &smsdev->coredev); if (ret < 0) goto free; smscore_set_board_id(smsdev->coredev, board_id); sdio_claim_host(func); ret = sdio_enable_func(func); if (ret) goto release; ret = sdio_set_block_size(func, 128); if (ret) goto disable; ret = sdio_claim_irq(func, smssdio_interrupt); if (ret) goto disable; sdio_set_drvdata(func, smsdev); sdio_release_host(func); ret = smscore_start_device(smsdev->coredev); if (ret < 0) goto reclaim; return 0; reclaim: sdio_claim_host(func); sdio_release_irq(func); disable: sdio_disable_func(func); release: sdio_release_host(func); smscore_unregister_device(smsdev->coredev); free: kfree(smsdev); return ret; }
static void wl1271_sdio_set_block_size(struct wl1271 *wl, unsigned int blksz) { sdio_claim_host(wl->if_priv); sdio_set_block_size(wl->if_priv, blksz); sdio_release_host(wl->if_priv); }
static int wl1251_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) { int ret, t; struct wl1251 *wl; struct ieee80211_hw *hw; struct wl1251_sdio *wl_sdio; const struct wl12xx_platform_data *wl12xx_board_data; hw = wl1251_alloc_hw(); if (IS_ERR(hw)) return PTR_ERR(hw); wl = hw->priv; wl_sdio = kzalloc(sizeof(*wl_sdio), GFP_KERNEL); if (wl_sdio == NULL) { ret = -ENOMEM; goto out_free_hw; } sdio_claim_host(func); ret = sdio_enable_func(func); if (ret) goto release; sdio_set_block_size(func, 512); sdio_release_host(func); SET_IEEE80211_DEV(hw, &func->dev); wl_sdio->func = func; wl->if_priv = wl_sdio; wl->if_ops = &wl1251_sdio_ops; wl12xx_board_data = wl12xx_get_platform_data(); if (!IS_ERR(wl12xx_board_data)) { wl->set_power = wl12xx_board_data->set_power; wl->irq = wl12xx_board_data->irq; wl->use_eeprom = wl12xx_board_data->use_eeprom; } if (force_nvs_file) wl->use_eeprom = false; wl->dump_eeprom = dump_eeprom; if (wl->irq) { irq_set_status_flags(wl->irq, IRQ_NOAUTOEN); ret = request_threaded_irq(wl->irq, NULL, wl1251_irq, IRQF_ONESHOT, "wl1251", wl); if (ret < 0) { wl1251_error("request_irq() failed: %d", ret); goto disable; } irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq; wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq; wl1251_info("using dedicated interrupt line"); } else { wl1251_sdio_ops.enable_irq = wl1251_sdio_enable_irq; wl1251_sdio_ops.disable_irq = wl1251_sdio_disable_irq; wl1251_info("using SDIO interrupt"); } ret = wl1251_init_ieee80211(wl); if (ret) goto out_free_irq; sdio_set_drvdata(func, wl); for (t = 0; t < ARRAY_SIZE(wl1251_attrs); t++) { ret = device_create_file(&func->dev, &wl1251_attrs[t]); if (ret) { while (--t >= 0) device_remove_file(&func->dev, &wl1251_attrs[t]); goto out_free_irq; } } /* Tell PM core that we don't need the card to be powered now */ pm_runtime_put_noidle(&func->dev); return ret; out_free_irq: if (wl->irq) free_irq(wl->irq, wl); disable: sdio_claim_host(func); sdio_disable_func(func); release: sdio_release_host(func); kfree(wl_sdio); out_free_hw: wl1251_free_hw(wl); return ret; }
static int iwmct_probe(struct sdio_func *func, const struct sdio_device_id *id) { struct iwmct_priv *priv; int ret; int val = 1; int addr = IWMC_SDIO_INTR_ENABLE_ADDR; dev_dbg(&func->dev, "enter iwmct_probe\n"); dev_dbg(&func->dev, "IRQ polling period id %u msecs, HZ is %d\n", jiffies_to_msecs(2147483647), HZ); priv = kzalloc(sizeof(struct iwmct_priv), GFP_KERNEL); if (!priv) { dev_err(&func->dev, "kzalloc error\n"); return -ENOMEM; } priv->func = func; sdio_set_drvdata(func, priv); /* create drivers work queue */ priv->wq = create_workqueue(DRV_NAME "_wq"); priv->bus_rescan_wq = create_workqueue(DRV_NAME "_rescan_wq"); INIT_WORK(&priv->bus_rescan_worker, iwmct_rescan_worker); INIT_WORK(&priv->isr_worker, iwmct_irq_read_worker); init_waitqueue_head(&priv->wait_q); sdio_claim_host(func); /* FIXME: Remove after it is fixed in the Boot ROM upgrade */ func->enable_timeout = 10; /* In our HW, setting the block size also wakes up the boot rom. */ ret = sdio_set_block_size(func, priv->dbg.block_size); if (ret) { LOG_ERROR(priv, INIT, "sdio_set_block_size() failure: %d\n", ret); goto error_sdio_enable; } ret = sdio_enable_func(func); if (ret) { LOG_ERROR(priv, INIT, "sdio_enable_func() failure: %d\n", ret); goto error_sdio_enable; } /* init reset and dev_sync states */ atomic_set(&priv->reset, 0); atomic_set(&priv->dev_sync, 0); /* init read req queue */ INIT_LIST_HEAD(&priv->read_req_list); /* process configurable parameters */ iwmct_dbg_init_params(priv); ret = sysfs_create_group(&func->dev.kobj, &iwmct_attribute_group); if (ret) { LOG_ERROR(priv, INIT, "Failed to register attributes and " "initialize module_params\n"); goto error_dev_attrs; } iwmct_dbgfs_register(priv, DRV_NAME); if (!priv->dbg.direct && priv->dbg.download_trans_blks > 8) { LOG_INFO(priv, INIT, "Reducing transaction to 8 blocks = 2K (from %d)\n", priv->dbg.download_trans_blks); priv->dbg.download_trans_blks = 8; } priv->trans_len = priv->dbg.download_trans_blks * priv->dbg.block_size; LOG_INFO(priv, INIT, "Transaction length = %d\n", priv->trans_len); ret = sdio_claim_irq(func, iwmct_irq); if (ret) { LOG_ERROR(priv, INIT, "sdio_claim_irq() failure: %d\n", ret); goto error_claim_irq; } /* Enable function's interrupt */ sdio_writeb(priv->func, val, addr, &ret); if (ret) { LOG_ERROR(priv, INIT, "Failure writing to " "Interrupt Enable Register (%d): %d\n", addr, ret); goto error_enable_int; } sdio_release_host(func); LOG_INFO(priv, INIT, "exit iwmct_probe\n"); return ret; error_enable_int: sdio_release_irq(func); error_claim_irq: sdio_disable_func(func); error_dev_attrs: iwmct_dbgfs_unregister(priv->dbgfs); sysfs_remove_group(&func->dev.kobj, &iwmct_attribute_group); error_sdio_enable: sdio_release_host(func); return ret; }
/** * @brief This function registers the device. * * @param priv A pointer to bt_private structure * @return BT_STATUS_SUCCESS or BT_STATUS_FAILURE */ int sbi_register_dev(bt_private * priv) { int ret = BT_STATUS_SUCCESS; u8 reg; u8 chiprev; struct sdio_mmc_card *card = priv->bt_dev.card; struct sdio_func *func; ENTER(); if (!card || !card->func) { PRINTM(ERROR, "BT: Error: card or function is NULL!\n"); goto failed; } func = card->func; priv->hotplug_device = &func->dev; if (fw_name == NULL) fw_name = DEFAULT_FW_NAME; /* Initialize the private structure */ strncpy(priv->bt_dev.name, "bt_sdio0", sizeof(priv->bt_dev.name)); priv->bt_dev.ioport = 0; priv->bt_dev.fn = func->num; sdio_claim_host(func); ret = sdio_claim_irq(func, sd_interrupt); if (ret) { PRINTM(FATAL, "BT: sdio_claim_irq failed: ret=%d\n", ret); goto release_host; } ret = sdio_set_block_size(card->func, SD_BLOCK_SIZE); if (ret) { PRINTM(FATAL, "BT: %s: cannot set SDIO block size\n", __FUNCTION__); goto release_irq; } /* read Revision Register to get the chip revision number */ chiprev = sdio_readb(func, CARD_REVISION_REG, &ret); if (ret) { PRINTM(FATAL, "BT: cannot read CARD_REVISION_REG\n"); goto release_irq; } priv->adapter->chip_rev = chiprev; PRINTM(INFO, "revision=%#x\n", chiprev); /* * Read the HOST_INTSTATUS_REG for ACK the first interrupt got * from the bootloader. If we don't do this we get a interrupt * as soon as we register the irq. */ reg = sdio_readb(func, HOST_INTSTATUS_REG, &ret); if (ret < 0) goto release_irq; /* Read the IO port */ reg = sdio_readb(func, IO_PORT_0_REG, &ret); if (ret < 0) goto release_irq; else priv->bt_dev.ioport |= reg; reg = sdio_readb(func, IO_PORT_1_REG, &ret); if (ret < 0) goto release_irq; else priv->bt_dev.ioport |= (reg << 8); reg = sdio_readb(func, IO_PORT_2_REG, &ret); if (ret < 0) goto release_irq; else priv->bt_dev.ioport |= (reg << 16); PRINTM(INFO, "BT: SDIO FUNC%d IO port: 0x%x\n", priv->bt_dev.fn, priv->bt_dev.ioport); #define SDIO_INT_MASK 0x3F /* Set Host interrupt reset to read to clear */ reg = sdio_readb(func, HOST_INT_RSR_REG, &ret); if (ret < 0) goto release_irq; sdio_writeb(func, reg | SDIO_INT_MASK, HOST_INT_RSR_REG, &ret); if (ret < 0) goto release_irq; /* Set auto re-enable */ reg = sdio_readb(func, CARD_MISC_CFG_REG, &ret); if (ret < 0) goto release_irq; sdio_writeb(func, reg | AUTO_RE_ENABLE_INT, CARD_MISC_CFG_REG, &ret); if (ret < 0) goto release_irq; sdio_set_drvdata(func, card); sdio_release_host(func); LEAVE(); return BT_STATUS_SUCCESS; release_irq: sdio_release_irq(func); release_host: sdio_release_host(func); failed: LEAVE(); return BT_STATUS_FAILURE; }
static int ks7010_sdio_probe(struct sdio_func *func, const struct sdio_device_id *device) { struct ks_wlan_private *priv; struct ks_sdio_card *card; struct net_device *netdev; unsigned char byte; int ret; priv = NULL; netdev = NULL; card = kzalloc(sizeof(*card), GFP_KERNEL); if (!card) return -ENOMEM; card->func = func; sdio_claim_host(func); ret = sdio_set_block_size(func, KS7010_IO_BLOCK_SIZE); DPRINTK(5, "multi_block=%d sdio_set_block_size()=%d %d\n", func->card->cccr.multi_block, func->cur_blksize, ret); ret = sdio_enable_func(func); DPRINTK(5, "sdio_enable_func() %d\n", ret); if (ret) goto err_free_card; /* interrupt disable */ sdio_writeb(func, 0, INT_ENABLE, &ret); if (ret) goto err_free_card; sdio_writeb(func, 0xff, INT_PENDING, &ret); if (ret) goto err_disable_func; /* setup interrupt handler */ ret = sdio_claim_irq(func, ks_sdio_interrupt); if (ret) goto err_disable_func; sdio_release_host(func); sdio_set_drvdata(func, card); DPRINTK(5, "class = 0x%X, vendor = 0x%X, device = 0x%X\n", func->class, func->vendor, func->device); /* private memory allocate */ netdev = alloc_etherdev(sizeof(*priv)); if (!netdev) { dev_err(&card->func->dev, "ks7010 : Unable to alloc new net device\n"); goto err_release_irq; } if (dev_alloc_name(netdev, "wlan%d") < 0) { dev_err(&card->func->dev, "ks7010 : Couldn't get name!\n"); goto err_free_netdev; } priv = netdev_priv(netdev); card->priv = priv; SET_NETDEV_DEV(netdev, &card->func->dev); /* for create sysfs symlinks */ /* private memory initialize */ priv->ks_sdio_card = card; priv->dev_state = DEVICE_STATE_PREBOOT; priv->net_dev = netdev; priv->firmware_version[0] = '\0'; priv->version_size = 0; priv->last_doze = jiffies; priv->last_wakeup = jiffies; memset(&priv->nstats, 0, sizeof(priv->nstats)); memset(&priv->wstats, 0, sizeof(priv->wstats)); /* sleep mode */ atomic_set(&priv->sleepstatus.doze_request, 0); atomic_set(&priv->sleepstatus.wakeup_request, 0); atomic_set(&priv->sleepstatus.wakeup_request, 0); trx_device_init(priv); hostif_init(priv); ks_wlan_net_start(netdev); ks7010_init_defaults(priv); ret = ks7010_upload_firmware(card); if (ret) { dev_err(&card->func->dev, "ks7010: firmware load failed !! return code = %d\n", ret); goto err_free_netdev; } /* interrupt setting */ /* clear Interrupt status write (ARMtoSD_InterruptPending FN1:00_0024) */ sdio_claim_host(func); ret = ks7010_sdio_writeb(priv, INT_PENDING, 0xff); sdio_release_host(func); if (ret) DPRINTK(1, " error : INT_PENDING\n"); /* enable ks7010sdio interrupt */ byte = (INT_GCR_B | INT_READ_STATUS | INT_WRITE_STATUS); sdio_claim_host(func); ret = ks7010_sdio_writeb(priv, INT_ENABLE, byte); sdio_release_host(func); if (ret) DPRINTK(1, " err : INT_ENABLE\n"); DPRINTK(4, " enable Interrupt : INT_ENABLE=%02X\n", byte); priv->dev_state = DEVICE_STATE_BOOT; priv->wq = create_workqueue("wq"); if (!priv->wq) { DPRINTK(1, "create_workqueue failed !!\n"); goto err_free_netdev; } INIT_DELAYED_WORK(&priv->rw_dwork, ks7010_rw_function); ks7010_card_init(priv); ret = register_netdev(priv->net_dev); if (ret) goto err_free_netdev; return 0; err_free_netdev: free_netdev(priv->net_dev); card->priv = NULL; err_release_irq: sdio_claim_host(func); sdio_release_irq(func); err_disable_func: sdio_disable_func(func); err_free_card: sdio_release_host(func); sdio_set_drvdata(func, NULL); kfree(card); return -ENODEV; }
static int iwm_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) { struct iwm_priv *iwm; struct iwm_sdio_priv *hw; struct device *dev = &func->dev; int ret; /* check if TOP has already initialized the card */ sdio_claim_host(func); ret = sdio_enable_func(func); if (ret) { dev_err(dev, "wait for TOP to enable the device\n"); sdio_release_host(func); return ret; } ret = sdio_set_block_size(func, IWM_SDIO_BLK_SIZE); sdio_disable_func(func); sdio_release_host(func); if (ret < 0) { dev_err(dev, "Failed to set block size: %d\n", ret); return ret; } iwm = iwm_if_alloc(sizeof(struct iwm_sdio_priv), dev, &if_sdio_ops); if (IS_ERR(iwm)) { dev_err(dev, "allocate SDIO interface failed\n"); return PTR_ERR(iwm); } hw = iwm_private(iwm); hw->iwm = iwm; iwm_debugfs_init(iwm); sdio_set_drvdata(func, hw); hw->func = func; hw->blk_size = IWM_SDIO_BLK_SIZE; hw->isr_wq = create_singlethread_workqueue(KBUILD_MODNAME "_sdio"); if (!hw->isr_wq) { ret = -ENOMEM; goto debugfs_exit; } INIT_WORK(&hw->isr_worker, iwm_sdio_isr_worker); ret = iwm_if_add(iwm); if (ret) { dev_err(dev, "add SDIO interface failed\n"); goto destroy_wq; } dev_info(dev, "IWM SDIO probe\n"); return 0; destroy_wq: destroy_workqueue(hw->isr_wq); debugfs_exit: iwm_debugfs_exit(iwm); iwm_if_free(iwm); return ret; }
/** * @brief This function registers the device. * * @param priv A pointer to bt_private structure * @return BT_STATUS_SUCCESS or BT_STATUS_FAILURE */ int sbi_register_dev(bt_private *priv) { int ret = BT_STATUS_SUCCESS; u8 reg; u8 chiprev; struct sdio_mmc_card *card = priv->bt_dev.card; struct sdio_func *func; u8 host_intstatus_reg = HOST_INTSTATUS_REG; u8 card_revision_reg = CARD_REVISION_REG; u8 io_port_0_reg = IO_PORT_0_REG; u8 io_port_1_reg = IO_PORT_1_REG; u8 io_port_2_reg = IO_PORT_2_REG; ENTER(); if (!card || !card->func) { PRINTM(ERROR, "BT: Error: card or function is NULL!\n"); goto failed; } func = card->func; priv->hotplug_device = &func->dev; /* Initialize the private structure */ strncpy(priv->bt_dev.name, "bt_sdio0", sizeof(priv->bt_dev.name)); priv->bt_dev.ioport = 0; priv->bt_dev.fn = func->num; sdio_claim_host(func); ret = sdio_claim_irq(func, sd_interrupt); if (ret) { PRINTM(FATAL, ": sdio_claim_irq failed: ret=%d\n", ret); goto release_host; } ret = sdio_set_block_size(card->func, SD_BLOCK_SIZE); if (ret) { PRINTM(FATAL, ": %s: cannot set SDIO block size\n", __func__); goto release_irq; } /* read Revision Register to get the chip revision number */ chiprev = sdio_readb(func, card_revision_reg, &ret); if (ret) { PRINTM(FATAL, ": cannot read CARD_REVISION_REG\n"); goto release_irq; } priv->adapter->chip_rev = chiprev; PRINTM(INFO, "revision=%#x\n", chiprev); /* * Read the HOST_INTSTATUS_REG for ACK the first interrupt got * from the bootloader. If we don't do this we get a interrupt * as soon as we register the irq. */ reg = sdio_readb(func, host_intstatus_reg, &ret); if (ret < 0) goto release_irq; /* Read the IO port */ reg = sdio_readb(func, io_port_0_reg, &ret); if (ret < 0) goto release_irq; else priv->bt_dev.ioport |= reg; reg = sdio_readb(func, io_port_1_reg, &ret); if (ret < 0) goto release_irq; else priv->bt_dev.ioport |= (reg << 8); reg = sdio_readb(func, io_port_2_reg, &ret); if (ret < 0) goto release_irq; else priv->bt_dev.ioport |= (reg << 16); PRINTM(INFO, ": SDIO FUNC%d IO port: 0x%x\n", priv->bt_dev.fn, priv->bt_dev.ioport); sdio_set_drvdata(func, card); sdio_release_host(func); LEAVE(); return BT_STATUS_SUCCESS; release_irq: sdio_release_irq(func); release_host: sdio_release_host(func); failed: LEAVE(); return BT_STATUS_FAILURE; }
static int wl1251_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) { int ret; struct wl1251 *wl; struct ieee80211_hw *hw; hw = wl1251_alloc_hw(); if (IS_ERR(hw)) return PTR_ERR(hw); wl = hw->priv; sdio_claim_host(func); ret = sdio_enable_func(func); if (ret) goto release; sdio_set_block_size(func, 512); sdio_release_host(func); SET_IEEE80211_DEV(hw, &func->dev); wl->if_priv = func; wl->if_ops = &wl1251_sdio_ops; wl->set_power = wl1251_sdio_set_power; if (wl12xx_board_data != NULL) { wl->set_power = wl12xx_board_data->set_power; wl->irq = wl12xx_board_data->irq; wl->use_eeprom = wl12xx_board_data->use_eeprom; } if (wl->irq) { ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl); if (ret < 0) { wl1251_error("request_irq() failed: %d", ret); goto disable; } set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); disable_irq(wl->irq); wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq; wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq; wl1251_info("using dedicated interrupt line"); } else { wl1251_sdio_ops.enable_irq = wl1251_sdio_enable_irq; wl1251_sdio_ops.disable_irq = wl1251_sdio_disable_irq; wl1251_info("using SDIO interrupt"); } ret = wl1251_init_ieee80211(wl); if (ret) goto out_free_irq; sdio_set_drvdata(func, wl); return ret; out_free_irq: if (wl->irq) free_irq(wl->irq, wl); disable: sdio_claim_host(func); sdio_disable_func(func); release: sdio_release_host(func); wl1251_free_hw(wl); return ret; }