/** 
 *  @brief This function de-registers the device.
 *  
 *  @param priv    A pointer to  bt_private structure
 *  @return 	   BT_STATUS_SUCCESS
 */
int
sbi_unregister_dev(bt_private * priv)
{
    struct sdio_mmc_card *card = priv->bt_dev.card;

    ENTER();

    if (card && card->func) {
        sdio_claim_host(card->func);
        sdio_release_irq(card->func);
        sdio_disable_func(card->func);
        sdio_release_host(card->func);
        sdio_set_drvdata(card->func, NULL);
    }

    LEAVE();
    return BT_STATUS_SUCCESS;
}
/** 
 *  @brief This function de-registers the device
 *  
 *  @param handle A pointer to moal_handle structure
 *  @return 	  None
 */
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();
}
Beispiel #3
0
static void wl1251_sdio_remove(struct sdio_func *func)
{
	struct wl1251 *wl = sdio_get_drvdata(func);
	struct wl1251_sdio *wl_sdio = wl->if_priv;

	/* Undo decrement done above in wl1251_probe */
	pm_runtime_get_noresume(&func->dev);

	if (wl->irq)
		free_irq(wl->irq, wl);
	wl1251_free_hw(wl);
	kfree(wl_sdio);

	sdio_claim_host(func);
	sdio_release_irq(func);
	sdio_disable_func(func);
	sdio_release_host(func);
}
static void smssdio_remove(struct sdio_func *func)
{
	struct smssdio_device *smsdev;

	smsdev = sdio_get_drvdata(func);
	sdio_claim_host(func);

	if (smsdev->split_cb)
		smscore_putbuffer(smsdev->coredev, smsdev->split_cb);

	smscore_unregister_device(smsdev->coredev);

	sdio_release_irq(func);
	sdio_disable_func(func);
	sdio_release_host(func);

	kfree(smsdev);
}
void i2400ms_rx_release(struct i2400ms *i2400ms)
{
	int result;
	struct sdio_func *func = i2400ms->func;
	struct device *dev = &func->dev;
	struct i2400m *i2400m = &i2400ms->i2400m;

	d_fnstart(5, dev, "(i2400ms %p)\n", i2400ms);
	spin_lock(&i2400m->rx_lock);
	i2400ms->bm_ack_size = -EINTR;
	spin_unlock(&i2400m->rx_lock);
	wake_up_all(&i2400ms->bm_wfa_wq);
	sdio_claim_host(func);
	sdio_writeb(func, 0, I2400MS_INTR_ENABLE_ADDR, &result);
	sdio_release_irq(func);
	sdio_release_host(func);
	d_fnend(5, dev, "(i2400ms %p) = %d\n", i2400ms, result);
}
Beispiel #6
0
/**
 *  @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;
}
Beispiel #7
0
void HIFMaskInterrupt(HIF_DEVICE *device)
{
    int ret;
    AR_DEBUG_ASSERT(device != NULL);
    AR_DEBUG_ASSERT(device->func != NULL);

    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFMaskInterrupt\n"));

    /* Mask our function IRQ */
    sdio_claim_host(device->func);
    while (atomic_read(&device->irqHandling)) {        
        sdio_release_host(device->func);
        schedule_timeout(HZ/10);
        sdio_claim_host(device->func);
    }
    ret = sdio_release_irq(device->func);
    sdio_release_host(device->func);
    AR_DEBUG_ASSERT(ret == 0);
}
Beispiel #8
0
/*
 * 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;
	strcpy(adapter->fw_name, SD8787_DEFAULT_FW_NAME);

	return 0;

release_irq:
	sdio_release_irq(func);
disable_func:
	sdio_disable_func(func);
	sdio_release_host(func);
	adapter->card = NULL;

	return -1;
}
Beispiel #9
0
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
}
Beispiel #10
0
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 ;
}
Beispiel #11
0
/* 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;
}
Beispiel #12
0
void sdio_free_irq(struct dvobj_priv *dvobj)
{
    PSDIO_DATA psdio_data;
    struct sdio_func *func;
    int err;

    if (dvobj->irq_alloc) {
        psdio_data = &dvobj->intf_data;
        func = psdio_data->func;

        if (func) {
            sdio_claim_host(func);
            err = sdio_release_irq(func);
            if (err)
            {
				DBG_871X("%s: sdio_release_irq FAIL(%d)!\n", __func__, err);
            }
            sdio_release_host(func);
        }
        dvobj->irq_alloc = 0;
    }
}
Beispiel #13
0
static void __devexit wl1251_sdio_remove(struct sdio_func *func)
{
	struct wl1251 *wl = sdio_get_drvdata(func);
	struct wl1251_sdio *wl_sdio = wl->if_priv;
	int t;

	/* Undo decrement done above in wl1251_probe */
	pm_runtime_get_noresume(&func->dev);

	for (t = 0; t < ARRAY_SIZE(wl1251_attrs); t++)
		device_remove_file(&func->dev, &wl1251_attrs[t]);

	if (wl->irq)
		free_irq(wl->irq, wl);
	wl1251_free_hw(wl);
	kfree(wl_sdio);

	sdio_claim_host(func);
	sdio_release_irq(func);
	sdio_disable_func(func);
	sdio_release_host(func);
}
Beispiel #14
0
static int if_sdio_disable(struct iwm_priv *iwm)
{
	struct iwm_sdio_priv *hw = iwm_to_if_sdio(iwm);
	int ret;

	sdio_claim_host(hw->func);
	sdio_writeb(hw->func, 0, IWM_SDIO_INTR_ENABLE_ADDR, &ret);
	if (ret < 0)
		IWM_WARN(iwm, "Couldn't disable INTR: %d\n", ret);

	sdio_release_irq(hw->func);
	sdio_disable_func(hw->func);
	sdio_release_host(hw->func);

	iwm_sdio_rx_free(hw);

	iwm_reset(iwm);

	IWM_DBG_SDIO(iwm, INFO, "IWM SDIO disable\n");

	return 0;
}
Beispiel #15
0
/*
 * Setup SDIO RX
 *
 * Hooks up the IRQ handler and then enables IRQs.
 */
int i2400ms_rx_setup(struct i2400ms *i2400ms)
{
	int result;
	struct sdio_func *func = i2400ms->func;
	struct device *dev = &func->dev;
	struct i2400m *i2400m = &i2400ms->i2400m;

	d_fnstart(5, dev, "(i2400ms %p)\n", i2400ms);

	init_waitqueue_head(&i2400ms->bm_wfa_wq);
	spin_lock(&i2400m->rx_lock);
	i2400ms->bm_wait_result = -EINPROGRESS;
	/*
	 * Before we are about to enable the RX interrupt, make sure
	 * bm_ack_size is cleared to -EINPROGRESS which indicates
	 * no RX interrupt happened yet or the previous interrupt
	 * has been handled, we are ready to take the new interrupt
	 */
	i2400ms->bm_ack_size = -EINPROGRESS;
	spin_unlock(&i2400m->rx_lock);

	sdio_claim_host(func);
	result = sdio_claim_irq(func, i2400ms_irq);
	if (result < 0) {
		dev_err(dev, "Cannot claim IRQ: %d\n", result);
		goto error_irq_claim;
	}
	result = 0;
	sdio_writeb(func, 1, I2400MS_INTR_ENABLE_ADDR, &result);
	if (result < 0) {
		sdio_release_irq(func);
		dev_err(dev, "Failed to enable interrupts %d\n", result);
	}
error_irq_claim:
	sdio_release_host(func);
	d_fnend(5, dev, "(i2400ms %p) = %d\n", i2400ms, result);
	return result;
}
Beispiel #16
0
static void r8712s_dev_remove(struct sdio_func *func)
{
	_adapter *padapter = (_adapter*) (((struct dvobj_priv*)sdio_get_drvdata(func))->padapter);
	struct net_device *pnetdev = (struct net_device *)padapter->pnetdev;

_func_exit_;

	if (padapter)
	{
		RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+dev_remove()\n"));

//		padapter->bSurpriseRemoved = _TRUE;

		if (pnetdev)
			unregister_netdev(pnetdev); //will call netdev_close()

		cancel_all_timer(padapter);
		
		r871x_dev_unload(padapter);

		rtw_free_drv_sw(padapter);

		sdio_claim_host(func);
		RT_TRACE(_module_hci_intfs_c_,_drv_err_,(" in dev_remove():sdio_claim_host !\n"));
		sdio_release_irq(func);
		RT_TRACE(_module_hci_intfs_c_,_drv_err_,(" in dev_remove():sdio_release_irq !\n"));
		sdio_disable_func(func);
		RT_TRACE(_module_hci_intfs_c_,_drv_err_,(" in dev_remove():sdio_disable_func !\n"));
		sdio_release_host(func);
		RT_TRACE(_module_hci_intfs_c_,_drv_err_,(" in dev_remove():sdio_release_host !\n"));
	}
	RT_TRACE(_module_hci_intfs_c_,_drv_err_,("-dev_remove()\n"));

_func_exit_;

	return;
}
Beispiel #17
0
/*
 * Setup SDIO RX
 *
 * Hooks up the IRQ handler and then enables IRQs.
 */
int i2400ms_rx_setup(struct i2400ms *i2400ms)
{
	int result;
	struct sdio_func *func = i2400ms->func;
	struct device *dev = &func->dev;

	d_fnstart(5, dev, "(i2400ms %p)\n", i2400ms);
	sdio_claim_host(func);
	result = sdio_claim_irq(func, i2400ms_irq);
	if (result < 0) {
		dev_err(dev, "Cannot claim IRQ: %d\n", result);
		goto error_irq_claim;
	}
	result = 0;
	sdio_writeb(func, 1, I2400MS_INTR_ENABLE_ADDR, &result);
	if (result < 0) {
		sdio_release_irq(func);
		dev_err(dev, "Failed to enable interrupts %d\n", result);
	}
error_irq_claim:
	sdio_release_host(func);
	d_fnend(5, dev, "(i2400ms %p) = %d\n", i2400ms, result);
	return result;
}
Beispiel #18
0
int adapter_probe(struct sdio_func *func, const struct sdio_device_id *id)
{
	struct net_adapter	*adapter;
	struct net_device	*net;
	u_char			charName[32];
	int			nRes = -ENOMEM;
	u_long			idx = 0;
	struct wimax732_platform_data	*pdata;

	dump_debug("Probe!!!!!!!!!");
	pdata = (struct wimax732_platform_data *) id->driver_data;
	net = alloc_etherdev(sizeof(struct net_adapter));
	if (!net) {
		dump_debug("adapter_probe: "
				"error can't allocate device");
		goto alloceth_fail;
	}

	adapter = netdev_priv(net);
	memset(adapter, 0, sizeof(struct net_adapter));
	g_adapter = adapter;

	adapter->pdata = (struct wimax732_platform_data *) id->driver_data;
	adapter->pdata->g_cfg->card_removed = false;
	adapter->pdata->g_cfg->powerup_done = false;

	/* Initialize control */
	control_init(adapter);

	/* initialize hardware */
	nRes = hw_init(adapter);

	if (nRes) {
		dump_debug("adapter_probe: error can't"
				"allocate receive buffer");
		goto hwInit_fail;
	}

	strcpy(net->name, "uwbr%d");

	adapter->func = func;
	adapter->net = net;
	net->netdev_ops = &wimax_net_ops;
	net->watchdog_timeo = ADAPTER_TIMEOUT;
	net->mtu = WIMAX_MTU_SIZE;
	adapter->msg_enable = netif_msg_init(msg_level, NETIF_MSG_DRV
			| NETIF_MSG_PROBE | NETIF_MSG_LINK);

	ether_setup(net);
	net->flags |= IFF_NOARP;

	adapter->media_state = MEDIA_DISCONNECTED;
	adapter->ready = FALSE;
	adapter->halted = FALSE;
	adapter->downloading = TRUE;
	adapter->removed = FALSE;
	adapter->mac_ready = FALSE;
	sdio_set_drvdata(func, adapter);

	SET_NETDEV_DEV(net, &func->dev);
	nRes = register_netdev(net);
	if (nRes)
		goto regdev_fail;

	netif_carrier_off(net);
	netif_tx_stop_all_queues(net);

	sdio_claim_host(adapter->func);
	nRes = sdio_enable_func(adapter->func);
	if (nRes < 0) {
		dump_debug("sdio_enable func error = %d", nRes);
		goto sdioen_fail;
	}

	nRes = sdio_claim_irq(adapter->func, adapter_interrupt);
	if (nRes < 0) {
		dump_debug("sdio_claim_irq = %d", nRes);
		goto sdioirq_fail;
	}
	sdio_set_block_size(adapter->func, 512);
	sdio_release_host(adapter->func);

	memset(charName, 0x00, sizeof(charName));
	create_char_name(charName, idx);
	if (misc_register(&uwibro_dev) != 0) {
		dump_debug("adapter_probe: misc_register() failed");
		goto regchar_fail;
	}

	/* Dummy value for "ifconfig up" for 2.6.24 */
	random_ether_addr(node_id);
	memcpy(net->dev_addr, node_id, sizeof(node_id));

	/* sangam dbg */
	INIT_WORK(&adapter->receive_work, rx_process_data);
	INIT_WORK(&adapter->transmit_work, hw_transmit_thread);
	INIT_WORK(&adapter->wimax_reset, cmc7xx_sdio_reset);

	if (hw_start(adapter)) {
		/* Free the resources and stop the driver processing */
		misc_deregister(&uwibro_dev);
		dump_debug("hw_start failed");
		goto regchar_fail;
	}

	adapter->ready = TRUE;

	return 0;

regchar_fail:
	sdio_claim_host(adapter->func);
	sdio_release_irq(adapter->func);
sdioirq_fail:
	sdio_disable_func(adapter->func);
sdioen_fail:
	sdio_release_host(adapter->func);
	unregister_netdev(adapter->net);
regdev_fail:
	sdio_set_drvdata(func, NULL);
	hw_remove(adapter);
hwInit_fail:
	free_netdev(net);
alloceth_fail:
	pdata->g_cfg->card_removed = true;
	pdata->g_cfg->powerup_done = true;
	pdata->power(0);
	return nRes;
}
Beispiel #19
0
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(&params, 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(&params, &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;
}
Beispiel #20
0
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;
}
Beispiel #22
0
static void ks7010_sdio_remove(struct sdio_func *func)
{
	int ret;
	struct ks_sdio_card *card;
	struct ks_wlan_private *priv;
	struct net_device *netdev;
	DPRINTK(1, "ks7010_sdio_remove()\n");

	card = sdio_get_drvdata(func);

	if (card == NULL)
		return;

	DPRINTK(1, "priv = card->priv\n");
	priv = card->priv;
	netdev = priv->net_dev;
	if (priv) {
		ks_wlan_net_stop(netdev);
		DPRINTK(1, "ks_wlan_net_stop\n");

		/* interrupt disable */
		sdio_claim_host(func);
		sdio_writeb(func, 0, INT_ENABLE, &ret);
		sdio_writeb(func, 0xff, INT_PENDING, &ret);
		sdio_release_host(func);
		DPRINTK(1, "interrupt disable\n");

		/* send stop request to MAC */
		{
			struct hostif_stop_request_t *pp;
			pp = (struct hostif_stop_request_t *)
			    kzalloc(hif_align_size(sizeof(*pp)), GFP_KERNEL);
			if (pp == NULL) {
				DPRINTK(3, "allocate memory failed..\n");
				return;	/* to do goto ni suru */
			}
			pp->header.size =
			    cpu_to_le16((uint16_t)
					(sizeof(*pp) -
					 sizeof(pp->header.size)));
			pp->header.event = cpu_to_le16((uint16_t) HIF_STOP_REQ);

			sdio_claim_host(func);
			write_to_device(priv, (unsigned char *)pp,
					hif_align_size(sizeof(*pp)));
			sdio_release_host(func);
			kfree(pp);
		}
		DPRINTK(1, "STOP Req\n");

		if (priv->ks_wlan_hw.ks7010sdio_wq) {
			flush_workqueue(priv->ks_wlan_hw.ks7010sdio_wq);
			destroy_workqueue(priv->ks_wlan_hw.ks7010sdio_wq);
		}
		DPRINTK(1,
			"destroy_workqueue(priv->ks_wlan_hw.ks7010sdio_wq);\n");

		hostif_exit(priv);
		DPRINTK(1, "hostif_exit\n");

		unregister_netdev(netdev);

		trx_device_exit(priv);
		if (priv->ks_wlan_hw.read_buf) {
			kfree(priv->ks_wlan_hw.read_buf);
		}
		free_netdev(priv->net_dev);
		card->priv = NULL;
	}

	sdio_claim_host(func);
	sdio_release_irq(func);
	DPRINTK(1, "sdio_release_irq()\n");
	sdio_disable_func(func);
	DPRINTK(1, "sdio_disable_func()\n");
	sdio_release_host(func);

	sdio_set_drvdata(func, NULL);

	kfree(card);
	DPRINTK(1, "kfree()\n");

	DPRINTK(5, " Bye !!\n");
	return;
}
Beispiel #23
0
static void ks7010_sdio_remove(struct sdio_func *func)
{
	int ret;
	struct ks_sdio_card *card;
	struct ks_wlan_private *priv;

	card = sdio_get_drvdata(func);

	if (!card)
		return;

	DPRINTK(1, "priv = card->priv\n");
	priv = card->priv;
	if (priv) {
		struct net_device *netdev = priv->net_dev;

		ks_wlan_net_stop(netdev);
		DPRINTK(1, "ks_wlan_net_stop\n");

		/* interrupt disable */
		sdio_claim_host(func);
		sdio_writeb(func, 0, INT_ENABLE, &ret);
		sdio_writeb(func, 0xff, INT_PENDING, &ret);
		sdio_release_host(func);
		DPRINTK(1, "interrupt disable\n");

		ret = send_stop_request(func);
		if (ret)	/* memory allocation failure */
			return;

		DPRINTK(1, "STOP Req\n");

		if (priv->wq) {
			flush_workqueue(priv->wq);
			destroy_workqueue(priv->wq);
		}
		DPRINTK(1, "destroy_workqueue(priv->wq);\n");

		hostif_exit(priv);
		DPRINTK(1, "hostif_exit\n");

		unregister_netdev(netdev);

		trx_device_exit(priv);
		free_netdev(priv->net_dev);
		card->priv = NULL;
	}

	sdio_claim_host(func);
	sdio_release_irq(func);
	DPRINTK(1, "sdio_release_irq()\n");
	sdio_disable_func(func);
	DPRINTK(1, "sdio_disable_func()\n");
	sdio_release_host(func);

	sdio_set_drvdata(func, NULL);

	kfree(card);
	DPRINTK(1, "kfree()\n");

	DPRINTK(5, " Bye !!\n");
}
Beispiel #24
0
static void emapi_sdio_remove(struct sdio_func *func)
{
   	sdio_release_irq(func);
	sdio_disable_func(func);
	sdio_release_host(func);
}
Beispiel #25
0
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;
}
/**
 *  @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;
}