static void wl1251_sdio_read_elp(struct wl1251 *wl, int addr, u32 *val) { int ret = 0; struct wl1251_sdio *wl_sdio = wl->if_priv; struct sdio_func *func = wl_sdio->func; /* * The hardware only supports RAW (read after write) access for * reading, regular sdio_readb won't work here (it interprets * the unused bits of CMD52 as write data even if we send read * request). */ sdio_claim_host(func); *val = sdio_writeb_readb(func, wl_sdio->elp_val, addr, &ret); sdio_release_host(func); if (ret) wl1251_error("sdio_readb failed (%d)", ret); }
void disable_sdio_interrupt(void){ #ifndef ATWILC_SDIO_IRQ_GPIO int ret; if(sdio_intr_lock == ATWILC_SDIO_HOST_IRQ_TAKEN ) wait_event_interruptible(sdio_intr_waitqueue, sdio_intr_lock == ATWILC_SDIO_HOST_NO_TAKEN ); sdio_intr_lock = ATWILC_SDIO_HOST_DIS_TAKEN; sdio_claim_host(local_sdio_func); ret = sdio_release_irq(local_sdio_func); if (ret < 0) { PRINT_ER("can't release sdio_irq, err(%d)\n", ret); } sdio_release_host(local_sdio_func); sdio_intr_lock = ATWILC_SDIO_HOST_NO_TAKEN; #endif }
/** * @brief This function updates card reg based on the Cmd52 value in dev structure * * @param priv A pointer to moal_handle structure * @param func A pointer to store func variable * @param reg A pointer to store reg variable * @param val A pointer to store val variable * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ int woal_sdio_read_write_cmd52(moal_handle * handle, int func, int reg, int val) { int ret = MLAN_STATUS_SUCCESS; struct sdio_mmc_card *card = (struct sdio_mmc_card *) handle->card; ENTER(); /* Save current func and reg for read */ handle->cmd52_func = func; handle->cmd52_reg = reg; sdio_claim_host(card->func); if (val >= 0) { /* Perform actual write only if val is provided */ if (func) sdio_writeb(card->func, val, reg, &ret); else sdio_f0_writeb(card->func, val, reg, &ret); if (ret) { PRINTM(MERROR, "Cannot write value (0x%x) to func %d reg 0x%x\n", val, func, reg); } else { PRINTM(MMSG, "write value (0x%x) to func %d reg 0x%x\n", (u8) val, func, reg); handle->cmd52_val = val; } } else { if (func) val = sdio_readb(card->func, reg, &ret); else val = sdio_f0_readb(card->func, reg, &ret); if (ret) { PRINTM(MERROR, "Cannot read value from func %d reg 0x%x\n", func, reg); } else { PRINTM(MMSG, "read value (0x%x) from func %d reg 0x%x\n", (u8) val, func, reg); handle->cmd52_val = val; } } sdio_release_host(card->func); LEAVE(); return ret; }
/** * @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 int if_sdio_send_chunk(struct iwm_priv *iwm, u8 *buf, int count) { struct iwm_sdio_priv *hw = iwm_to_if_sdio(iwm); int aligned_count = ALIGN(count, hw->blk_size); int ret; if ((unsigned long)buf & 0x3) { IWM_ERR(iwm, "buf <%p> is not dword aligned\n", buf); return -EINVAL; } sdio_claim_host(hw->func); ret = sdio_memcpy_toio(hw->func, IWM_SDIO_DATA_ADDR, buf, aligned_count); sdio_release_host(hw->func); return ret; }
/** * @brief This function de-registers the device * * @param handle A pointer to moal_handle structure * @return N/A */ void woal_unregister_dev(moal_handle * handle) { ENTER(); if (handle->card) { /* Release the SDIO IRQ */ sdio_claim_host(((struct sdio_mmc_card *)handle->card)->func); sdio_release_irq(((struct sdio_mmc_card *)handle->card)->func); sdio_disable_func(((struct sdio_mmc_card *)handle->card)->func); sdio_release_host(((struct sdio_mmc_card *)handle->card)->func); sdio_set_drvdata(((struct sdio_mmc_card *)handle->card)->func, NULL); PRINTM(MWARN, "Making the sdio dev card as NULL\n"); } LEAVE(); }
u8 sd_f0_read8(PSDIO_DATA psdio, u32 addr, s32 *err) { u8 v; struct sdio_func *func; _func_enter_; func = psdio->func; sdio_claim_host(func); v = sdio_f0_readb(func, addr, err); sdio_release_host(func); if (err && *err) printk(KERN_ERR "%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr); _func_exit_; return v; }
static int smssdio_sendrequest(void *context, void *buffer, size_t size) { int ret = 0; struct smssdio_device *smsdev; void* auxbuf = NULL; smsdev = context; if (size & 3) { /* Make sure size is aligned to 32 bits, round up if required*/ auxbuf = kmalloc((size + 3) & 0xfffffffc, GFP_KERNEL); memcpy (auxbuf, buffer, size); buffer = auxbuf; size = (size + 3) & 0xfffffffc; } sdio_claim_host(smsdev->func); while (size >= smsdev->func->cur_blksize) { ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA, buffer, smsdev->func->cur_blksize); if (ret) goto out; buffer += smsdev->func->cur_blksize; size -= smsdev->func->cur_blksize; } if (size) { ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA, buffer, size); } out: if (auxbuf) kfree(auxbuf); sdio_release_host(smsdev->func); return ret; }
/* * 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 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; }
/** * @brief This function reads multiple bytes from card memory * * @param handle A Pointer to the moal_handle structure * @param pmbuf Pointer to mlan_buffer structure * @param port Port * @param timeout Time out value * * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ mlan_status woal_read_data_sync(moal_handle *handle, mlan_buffer *pmbuf, t_u32 port, t_u32 timeout) { mlan_status ret = MLAN_STATUS_FAILURE; t_u8 *buffer = (t_u8 *)(pmbuf->pbuf + pmbuf->data_offset); t_u8 blkmode = (port & MLAN_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE; t_u32 blksz = (blkmode == BLOCK_MODE) ? MLAN_SDIO_BLOCK_SIZE : 1; t_u32 blkcnt = (blkmode == BLOCK_MODE) ? (pmbuf->data_len / MLAN_SDIO_BLOCK_SIZE) : pmbuf->data_len; t_u32 ioport = (port & MLAN_SDIO_IO_PORT_MASK); int status = 0; if (pmbuf->use_count > 1) return woal_sdio_rw_mb(handle, pmbuf, port, MFALSE); #ifdef SDIO_MMC_DEBUG handle->cmd53r = 1; #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) sdio_claim_host(((struct sdio_mmc_card *)handle->card)->func); #endif status = sdio_readsb(((struct sdio_mmc_card *)handle->card)->func, buffer, ioport, blkcnt * blksz); if (!status) { ret = MLAN_STATUS_SUCCESS; } else { PRINTM(MERROR, "cmd53 read error=%d\n", status); #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) /* issue abort cmd52 command through F0*/ sdio_f0_writeb(((struct sdio_mmc_card *)handle->card)->func, 0x01, SDIO_CCCR_ABORT, &status); #endif } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) sdio_release_host(((struct sdio_mmc_card *)handle->card)->func); #endif #ifdef SDIO_MMC_DEBUG handle->cmd53r = 2; #endif return ret; }
static void mtk_sdio_remove(struct sdio_func *func) { /* printk(KERN_INFO DRV_NAME"mtk_sdio_remove()\n"); */ #if CFG_DBG_GPIO_PINS /* printk(KERN_INFO "[%s] deinit debug gpio\n", __FUNCTION__); */ debug_gpio_deinit(); #endif ASSERT(func); /* printk(KERN_INFO DRV_NAME"pfWlanRemove done\n"); */ pfWlanRemove(); sdio_claim_host(func); sdio_disable_func(func); /* printk(KERN_INFO DRV_NAME"sdio_disable_func() done\n"); */ sdio_release_host(func); /* printk(KERN_INFO DRV_NAME"mtk_sdio_remove() done\n"); */ }
/** * @brief This function enables the host interrupts. * * @param priv A pointer to bt_private structure * @return BT_STATUS_SUCCESS or BT_STATUS_FAILURE */ int sbi_enable_host_int(bt_private * priv) { struct sdio_mmc_card *card = priv->bt_dev.card; int ret; ENTER(); if (!card || !card->func) { LEAVE(); return BT_STATUS_FAILURE; } sdio_claim_host(card->func); ret = sd_enable_host_int_mask(priv, HIM_ENABLE); sd_get_rx_unit(priv); sdio_release_host(card->func); LEAVE(); return ret; }
void sd_f0_write8(PSDIO_DATA psdio, u32 addr, u8 v, s32 *err) { struct sdio_func *func; bool claim_needed; _func_enter_; func = psdio->func; claim_needed = rtw_sdio_claim_host_needed(func); if (claim_needed) sdio_claim_host(func); sdio_f0_writeb(func, v, addr, err); if (claim_needed) sdio_release_host(func); if (err && *err) DBG_871X(KERN_ERR "%s: FAIL!(%d) addr=0x%05x val=0x%02x\n", __func__, *err, addr, v); _func_exit_; }
static int mtlte_sys_sdio_remove_irq(struct sdio_func *sdiofunc) { int ret = 0 ; KAL_RAWPRINT(("[REMOVE] =======> mtlte_sys_sdio_remove_irq\n")); lte_sdio_disable_eirq(); sdio_claim_host(sdiofunc); ret = sdio_release_irq(sdiofunc); sdio_release_host(sdiofunc); if (ret){ KAL_RAWPRINT(("[REMOVE] XXXXXX mtlte_sys_sdio_remove_irq fail, %d \n", ret )); return (ret); } KAL_RAWPRINT(("[REMOVE] <======= mtlte_sys_sdio_remove_irq\n")); return 0 ; }
void sif_enable_irq(struct esp_pub *epub) { int err; struct esp_sdio_ctrl *sctrl = NULL; sctrl = (struct esp_sdio_ctrl *)epub->sif; sdio_claim_host(sctrl->func); err = sdio_claim_irq(sctrl->func, sif_dsr); if (err) esp_dbg(ESP_DBG_ERROR, "sif %s failed\n", __func__); atomic_set(&epub->sip->state, SIP_BOOT); atomic_set(&sctrl->irq_installed, 1); sdio_release_host(sctrl->func); }
int bcmsdio_register_intr_handler(int func, sdio_irq_handler_t * handler) { struct sdio_func *function = func_data[func]->func; int ret; if (function == NULL) { BCM_DEBUG_PRINT(ERROR_LEVEL, KERN_ALERT " ***Error: %s %d ***\n", __func__, __LINE__); return -ENON_INTF_ERR; } sdio_claim_host(function); ret = sdio_claim_irq(function, handler); if (ret < 0) BCM_DEBUG_PRINT(debuglevel, KERN_ERR "Func-%d ISR Registration failed\n", func); sdio_release_host(function); 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; }
/*----------------------------------------------------------------------------*/ BOOL kalDevRegRead ( IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Register, OUT PUINT_32 pu4Value ) { int ret = 0; int a = 0; ASSERT(prGlueInfo); ASSERT(pu4Value); #if MTK_WCN_HIF_SDIO ret = mtk_wcn_hif_sdio_readl(prGlueInfo->rHifInfo.cltCtx, u4Register, (PUINT32) pu4Value); #else if (!in_interrupt) { sdio_claim_host(prGlueInfo->rHifInfo.func); } retry: *pu4Value = sdio_readl(prGlueInfo->rHifInfo.func, u4Register, &ret); if (ret && a < 10) { a++; printk("gwl =-==============> sdio_readl retry %d!\n", a); msleep(1); goto retry; } if (!in_interrupt) { sdio_release_host(prGlueInfo->rHifInfo.func); } #endif if (ret) { kalSendAeeWarning(HIF_SDIO_ERR_TITLE_STR, HIF_SDIO_ERR_DESC_STR "sdio_readl() reports error: %x", ret); DBGLOG(HAL, ERROR, ("sdio_readl() reports error: %x", ret)); } return (ret) ? FALSE : TRUE; } /* end of kalDevRegRead() */
/* * This function takes a queue of packets. The packets on the queue * are assumed to be properly aligned by the caller. */ int brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc, uint write, uint func, uint addr, struct sk_buff_head *pktq) { bool fifo = (fix_inc == SDIOH_DATA_FIX); u32 SGCount = 0; int err_ret = 0; struct sk_buff *pkt; brcmf_dbg(TRACE, "Enter\n"); brcmf_pm_resume_wait(sdiodev, &sdiodev->request_chain_wait); if (brcmf_pm_resume_error(sdiodev)) return -EIO; /* Claim host controller */ sdio_claim_host(sdiodev->func[func]); skb_queue_walk(pktq, pkt) { uint pkt_len = pkt->len; pkt_len += 3; pkt_len &= 0xFFFFFFFC; err_ret = brcmf_sdioh_request_data(sdiodev, write, fifo, func, addr, pkt, pkt_len); if (err_ret) { brcmf_dbg(ERROR, "%s FAILED %p[%d], addr=0x%05x, pkt_len=%d, ERR=0x%08x\n", write ? "TX" : "RX", pkt, SGCount, addr, pkt_len, err_ret); } else { brcmf_dbg(TRACE, "%s xfr'd %p[%d], addr=0x%05x, len=%d\n", write ? "TX" : "RX", pkt, SGCount, addr, pkt_len); } if (!fifo) addr += pkt_len; SGCount++; }
extern void sd_dvobj_deinit(_adapter * padapter) { unsigned char data; struct dvobj_priv *psddev=&padapter->dvobjpriv; struct sdio_func *func=psddev->func; RT_TRACE(_module_hci_intfs_c_,_drv_err_,("+SDIO deinit\n")); if(func !=0){ sdio_claim_host(func); RT_TRACE(_module_hci_intfs_c_,_drv_err_,(" in sd_dvobj_deinit():sdio_claim_host !\n")); // sdio_release_irq(func); RT_TRACE(_module_hci_intfs_c_,_drv_err_,(" in sd_dvobj_deinit():sdio_release_irq !\n")); sdio_disable_func(func); RT_TRACE(_module_hci_intfs_c_,_drv_err_,(" in sd_dvobj_deinit():sdio_disable_func !\n")); sdio_release_host(func); RT_TRACE(_module_hci_intfs_c_,_drv_err_,(" in sd_dvobj_deinit():sdio_release_host !\n")); } return; }
static void sdio_deinit(PADAPTER padapter) { struct dvobj_priv *psddev; struct sdio_func *func; int err; RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("+sdio_deinit\n")); if (padapter == NULL) return; psddev = &padapter->dvobjpriv; func = psddev->intf_data.func; if (func) { sdio_claim_host(func); err = sdio_disable_func(func); if (err) DBG_871X(KERN_ERR "%s: sdio_disable_func(%d)\n", __func__, err); sdio_release_host(func); } }
static int wl12xx_sdio_power_off(struct wl12xx_sdio_glue *glue) { int ret; struct sdio_func *func = dev_to_sdio_func(glue->dev); struct mmc_card *card = func->card; sdio_claim_host(func); sdio_disable_func(func); sdio_release_host(func); /* Power off the card manually in case it wasn't powered off above */ ret = mmc_power_save_host(card->host); if (ret < 0) goto out; /* Let runtime PM know the card is powered off */ pm_runtime_put_sync(&card->dev); out: return ret; }
static void ssb_sdio_write32(struct ssb_device *dev, u16 offset, u32 val) { struct ssb_bus *bus = dev->bus; int error = 0; sdio_claim_host(bus->host_sdio); if (unlikely(ssb_sdio_switch_core(bus, dev))) goto out; offset |= bus->sdio_sbaddr & 0xffff; offset &= SBSDIO_SB_OFT_ADDR_MASK; offset |= SBSDIO_SB_ACCESS_2_4B_FLAG; /* 32 bit data access */ sdio_writel(bus->host_sdio, val, offset, &error); if (error) { dev_dbg(ssb_sdio_dev(bus), "%04X:%04X < %08x, error %d\n", bus->sdio_sbaddr >> 16, offset, val, error); } if (bus->quirks & SSB_QUIRK_SDIO_READ_AFTER_WRITE32) sdio_readl(bus->host_sdio, 0, &error); out: sdio_release_host(bus->host_sdio); }
static int mtlte_sys_sdio_setup_irq(struct sdio_func *sdiofunc) { int ret = 0 ; KAL_RAWPRINT(("[PROBE] =======> mtlte_sys_sdio_setup_irq\n")); sdio_claim_host(sdiofunc); ret = sdio_claim_irq(sdiofunc, mtlte_sys_lte_sdio_isr); sdio_release_host(sdiofunc); if (ret){ KAL_RAWPRINT(("[PROBE] XXXXXX mtlte_sys_sdio_setup_irq fail, %d \n", ret )); return (ret); } mtlte_hif_enable_interrupt_at_probe(); lte_sdio_enable_eirq(); KAL_RAWPRINT(("[PROBE] <======= mtlte_sys_sdio_setup_irq\n")); return 0 ; }
static u16 ssb_sdio_read16(struct ssb_device *dev, u16 offset) { struct ssb_bus *bus = dev->bus; u16 val = 0xffff; int error = 0; sdio_claim_host(bus->host_sdio); if (unlikely(ssb_sdio_switch_core(bus, dev))) goto out; offset |= bus->sdio_sbaddr & 0xffff; offset &= SBSDIO_SB_OFT_ADDR_MASK; val = sdio_readw(bus->host_sdio, offset, &error); if (error) { dev_dbg(ssb_sdio_dev(bus), "%04X:%04X > %04x, error %d\n", bus->sdio_sbaddr >> 16, offset, val, error); } out: sdio_release_host(bus->host_sdio); return val; }
/** * @brief This function wakeup firmware * * @param priv A pointer to bt_private structure * @return BT_STATUS_SUCCESS/BT_STATUS_FAILURE or other error no. */ int sbi_wakeup_firmware(bt_private * priv) { struct sdio_mmc_card *card = priv->bt_dev.card; int ret = BT_STATUS_SUCCESS; ENTER(); if (!card || !card->func) { PRINTM(ERROR, "BT: card or function is NULL!\n"); LEAVE(); return BT_STATUS_FAILURE; } sdio_claim_host(card->func); sdio_writeb(card->func, HOST_POWER_UP, CONFIGURATION_REG, &ret); sdio_release_host(card->func); PRINTM(CMD, "BT wake up firmware\n"); LEAVE(); return ret; }
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; }
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 wimax_suspend(struct platform_device *pdev, pm_message_t state) { struct sdio_func *function; BCM_DEBUG_PRINT(debuglevel, "%s: FUNC Start\n", __func__); BCM_DEBUG_PRINT(debuglevel, "BRCM WiMAX Suspend Called\n"); if( func_data[BCM_SDIO_FN1] == NULL ) { BCM_DEBUG_PRINT(ERROR_LEVEL, KERN_ALERT " ***Error: %s %d function is NULL! ***\n", __func__, __LINE__); return 0; } else { function = func_data[BCM_SDIO_FN1]->func; } disable_irq_nosync(g_irq_num); sdio_claim_host(function); return 0; }