示例#1
0
static void smssdio_remove(struct sdio_func *func)
{
	struct smssdio_device *smsdev;

	smsdev = sdio_get_drvdata(func);

	/* FIXME: racy! */
	if (smsdev->split_cb)
		smscore_putbuffer(smsdev->coredev, smsdev->split_cb);

	smscore_unregister_device(smsdev->coredev);

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

	kfree(smsdev);
}
/*
 * 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;
}
/*
 * 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;
}
/**
 *  @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();
}
示例#5
0
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"); */
}
示例#6
0
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;
}
示例#7
0
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);
	}
}
示例#8
0
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;
}
示例#9
0
文件: sdio.c 项目: 383530895/linux
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;
}
示例#10
0
static int wl1251_sdio_set_power(struct wl1251 *wl, bool enable)
{
	struct sdio_func *func = wl_to_func(wl);
	int ret;

	if (enable) {
		/*
		 * Power is controlled by runtime PM, but we still call board
		 * callback in case it wants to do any additional setup,
		 * for example enabling clock buffer for the module.
		 */
		if (gpio_is_valid(wl->power_gpio))
			gpio_set_value(wl->power_gpio, true);


		ret = pm_runtime_get_sync(&func->dev);
		if (ret < 0) {
			pm_runtime_put_sync(&func->dev);
			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);

		ret = pm_runtime_put_sync(&func->dev);
		if (ret < 0)
			goto out;

		if (gpio_is_valid(wl->power_gpio))
			gpio_set_value(wl->power_gpio, false);
	}

out:
	return ret;
}
示例#11
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);
}
示例#12
0
文件: sdio.c 项目: CSCLOG/beaglebone
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;
}
示例#13
0
static void bcmsdio_remove(struct sdio_func *func)
{
	struct bcmsdio_data *data = sdio_get_drvdata(func);

	BCM_DEBUG_PRINT(debuglevel, KERN_ALERT " WIMAX SDIO REMOVE: NUM:x%x VID:x%x DID:x%x\n", func->num, func->vendor, func->device);
	if (!data)
		return;

	remove_notifier(data->wimax_data);

	sdio_claim_host(func);
	data->bremoved = 1;
	sdio_release_host(func);

	/* Disable function */
	sdio_claim_host(func);
	sdio_disable_func(func);
	sdio_release_host(func);

	sdio_set_drvdata(func, NULL);
	func_data[func->num] = NULL;
	kfree(data);
}
示例#14
0
static int wl1271_sdio_power_off(struct wl1271 *wl)
{
	struct sdio_func *func = wl_to_func(wl);
	int ret;

	sdio_disable_func(func);
	sdio_release_host(func);

	/* Power off the card manually, even if runtime PM is enabled. */
	ret = mmc_power_save_host(func->card->host);
	if (ret < 0) {
printk (KERN_ERR "%s:mmc_power_save_host: %d\n", __func__, ret );
		return ret;
	}

	/* If enabled, let runtime PM know the card is powered off */
	if (pm_runtime_enabled(&func->dev))
		ret = pm_runtime_put_sync(&func->dev);

printk (KERN_ERR "%s: %d\n", __func__, ret );

	return ret;
}
示例#15
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;
}
示例#16
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;
}
示例#17
0
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;
}
示例#18
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;
}
示例#19
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;
}
示例#20
0
文件: sdio.c 项目: CSCLOG/beaglebone
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;
}
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;

	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;
	}
	
	/* Grab access to FN0 for ELP reg. */
	func->card->quirks |= MMC_QUIRK_LENIENT_FN0;

	/* Use block mode for transferring over one block size of data */
	func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;

	sdio_claim_host(func);
	pr_info("%s: claimed host\n", __func__);
	ret = sdio_enable_func(func);
	if (ret)
		goto release;
	pr_info("%s: enabled host\n", __func__);

	sdio_set_block_size(func, 512);
	sdio_release_host(func);
	pr_info("%s: released host\n", __func__);

	SET_IEEE80211_DEV(hw, &func->dev);
	wl_sdio->func = func;
	wl->if_priv = wl_sdio;
	wl->if_ops = &wl1251_sdio_ops;

	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);
	kfree(wl_sdio);
out_free_hw:
	wl1251_free_hw(wl);
	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;

	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;
}
示例#23
0
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;
}
示例#24
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;
}
示例#25
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");
}
示例#26
0
static void emapi_sdio_remove(struct sdio_func *func)
{
   	sdio_release_irq(func);
	sdio_disable_func(func);
	sdio_release_host(func);
}
示例#27
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;
}