示例#1
0
/*
 * Remove a device
 */
static int __exit rk28_sdmmc0_remove(struct platform_device *pdev)
{
    struct mmc_host *mmc = platform_get_drvdata(pdev);
    struct rk28mci_host *host;
    struct resource *res;

    if (!mmc)
        return -1;

    //printk("%s..%s..%d ********************====xbw===*******************\n",__FUNCTION__,__FILE__,__LINE__);

    host = mmc_priv(mmc);

    rk28_sdmmc_disable(host);
    mmc_remove_host(mmc);
    free_irq(host->irq, host);

    iounmap(host->baseaddr);
    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    release_mem_region(res->start, res->end - res->start + 1);

    mmc_free_host(mmc);
    platform_set_drvdata(pdev, NULL);
    pr_debug("MCI Removed\n");

    return 0;
}
示例#2
0
/*
 * Remove a device
 */
static int __exit at91_mci_remove(struct platform_device *pdev)
{
	struct mmc_host *mmc = platform_get_drvdata(pdev);
	struct at91mci_host *host;
	struct resource *res;

	if (!mmc)
		return -1;

	host = mmc_priv(mmc);

	if (host->board->det_pin) {
		device_init_wakeup(&pdev->dev, 0);
		free_irq(host->board->det_pin, host);
		cancel_delayed_work(&host->mmc->detect);
	}

	at91_mci_disable(host);
	mmc_remove_host(mmc);
	free_irq(host->irq, host);

	clk_disable(host->mci_clk);			/* Disable the peripheral clock */
	clk_put(host->mci_clk);

	iounmap(host->baseaddr);
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	release_mem_region(res->start, res->end - res->start + 1);

	mmc_free_host(mmc);
	platform_set_drvdata(pdev, NULL);
	pr_debug("MCI Removed\n");

	return 0;
}
static int omap_hsmmc_remove(struct platform_device *pdev)
{
	struct omap_hsmmc_host *host = platform_get_drvdata(pdev);
	struct resource *res;

	if (host) {
		mmc_host_enable(host->mmc);
		mmc_remove_host(host->mmc);
		if (host->pdata->cleanup)
			host->pdata->cleanup(&pdev->dev);
		free_irq(host->irq, host);
		if (mmc_slot(host).card_detect_irq)
			free_irq(mmc_slot(host).card_detect_irq, host);
		flush_scheduled_work();

		mmc_host_disable(host->mmc);
		clk_disable(host->iclk);
		clk_put(host->fclk);
		clk_put(host->iclk);
		if (host->got_dbclk) {
			clk_disable(host->dbclk);
			clk_put(host->dbclk);
		}

		mmc_free_host(host->mmc);
		iounmap(host->base);
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res)
		release_mem_region(res->start, res->end - res->start + 1);
	platform_set_drvdata(pdev, NULL);

	return 0;
}
示例#4
0
文件: sh_mmcif.c 项目: 3bsa/linux
static int sh_mmcif_remove(struct platform_device *pdev)
{
	struct sh_mmcif_host *host = platform_get_drvdata(pdev);

	host->dying = true;
	clk_prepare_enable(host->hclk);
	pm_runtime_get_sync(&pdev->dev);

	dev_pm_qos_hide_latency_limit(&pdev->dev);

	mmc_remove_host(host->mmc);
	sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);

	/*
	 * FIXME: cancel_delayed_work(_sync)() and free_irq() race with the
	 * mmc_remove_host() call above. But swapping order doesn't help either
	 * (a query on the linux-mmc mailing list didn't bring any replies).
	 */
	cancel_delayed_work_sync(&host->timeout_work);

	clk_disable_unprepare(host->hclk);
	mmc_free_host(host->mmc);
	pm_runtime_put_sync(&pdev->dev);
	pm_runtime_disable(&pdev->dev);

	return 0;
}
示例#5
0
文件: mmci.c 项目: 32bitmicro/xvisor
static int mmci_driver_remove(struct vmm_device *dev)
{
	struct mmc_host *mmc = dev->priv;
	struct mmci_host *host = mmc_priv(mmc);

	if (mmc && host) {
		mmc_remove_host(mmc);

		vmm_writel(0, &host->base->mask0);
		vmm_writel(0, &host->base->mask1);
		vmm_writel(0, &host->base->command);
		vmm_writel(0, &host->base->datactrl);

		if (!host->singleirq) {
			vmm_host_irq_unregister(host->irq1, mmc);
		}
		vmm_host_irq_unregister(host->irq0, mmc);
		vmm_devtree_regunmap_release(dev->node,
					(virtual_addr_t)host->base, 0);
		mmc_free_host(mmc);
		dev->priv = NULL;
	}

	return VMM_OK;
}
示例#6
0
文件: imxmmc.c 项目: ivucica/linux
static int imxmci_remove(struct platform_device *pdev)
{
	struct mmc_host *mmc = platform_get_drvdata(pdev);

	platform_set_drvdata(pdev, NULL);

	if (mmc) {
		struct imxmci_host *host = mmc_priv(mmc);

		tasklet_disable(&host->tasklet);

		del_timer_sync(&host->timer);
		mmc_remove_host(mmc);

		free_irq(host->irq, host);
		if(host->dma_allocated){
			imx_dma_free(host->dma);
			host->dma_allocated=0;
		}

		tasklet_kill(&host->tasklet);

		release_resource(host->res);

		mmc_free_host(mmc);
	}
	return 0;
}
示例#7
0
static int sslsd_remove(struct platform_device *dev)
{
	struct mmc_host	*mmc = platform_get_drvdata(dev);
	sslsd_host		*host = mmc_priv(mmc);

//printk("sslsd: remove\n");
	del_timer(&host->timer);
	sdhc_exit(&host->hw);
	platform_set_drvdata(dev, NULL);
	mmc_remove_host(mmc);
	free_irq(host->irq, host);
#if IO_MAP == 1
//	release_resource(host->res);
	iounmap((void *)(host->hw.r - 0x100));
#endif
#if SD_DMA
	if (host->hw.fdma)
	{
#if IO_MAP == 3
		ebm_mfree(ebm_mem);
#endif
	}
#endif
	mmc_free_host(mmc);
	sysfs_remove_group(&dev->dev.kobj, &sslsd_attr_group);
	return 0;
}
示例#8
0
static int s3c_hsmmc_remove(struct platform_device *dev)
{
	struct mmc_host *mmc  = platform_get_drvdata(dev);
	struct s3c_hsmmc_host *host = mmc_priv(mmc);
	int i;

	mmc = host->mmc;

	mmc_remove_host(mmc);

	s3c_hsmmc_reset(host, S3C_HSMMC_RESET_ALL);

	clk_disable(clk_get(&dev->dev, "hsmmc"));

	for (i=0; i<NUM_OF_HSMMC_CLKSOURCES; i++) {
		clk_disable(host->clk[i]);
		clk_put(host->clk[i]);
	}

	free_irq(host->irq, host);

	del_timer_sync(&host->timer);

	tasklet_kill(&host->card_tasklet);
	tasklet_kill(&host->finish_tasklet);

	mmc_free_host(mmc);

	return 0;
}
示例#9
0
static int mmci_remove(struct amba_device *dev)
{
    struct mmc_host *mmc = amba_get_drvdata(dev);

    amba_set_drvdata(dev, NULL);

    if (mmc) {
        struct mmci_host *host = mmc_priv(mmc);

        del_timer_sync(&host->timer);

        mmc_remove_host(mmc);

        writel(0, host->base + MMCIMASK0);
        writel(0, host->base + MMCIMASK1);

        writel(0, host->base + MMCICOMMAND);
        writel(0, host->base + MMCIDATACTRL);

        free_irq(dev->irq[0], host);
        free_irq(dev->irq[1], host);

        iounmap(host->base);
        clk_disable(host->clk);
        clk_put(host->clk);

        mmc_free_host(mmc);

        amba_release_regions(dev);
    }

    return 0;
}
static int __devexit pmpmci_remove(struct platform_device *pdev)
{
	struct pmpmci_host *host = platform_get_drvdata(pdev);
    struct sd_data_s *sd_data= host->platdata;	
	if (host) {
		mmc_remove_host(host->mmc);
    	clk_disable(host->clk);
//		if (host->platdata && host->platdata->cd_setup &&
//		    !(host->mmc->caps & MMC_CAP_NEEDS_POLL))
//			host->platdata->cd_setup(host->mmc, 0);
//
        sd_data->ops->deInit(&(sd_data->info));
		tasklet_kill(&host->data_task);
		tasklet_kill(&host->finish_task);

		free_irq(host->irq, host);
		iounmap((void *)host->iobase);
		release_resource(host->ioarea);
		kfree(host->ioarea);

		mmc_free_host(host->mmc);
		platform_set_drvdata(pdev, NULL);
	}
	return 0;
}
示例#11
0
/*
 * ubicom32sd_remove
 */
static int __devexit ubicom32sd_remove(struct platform_device *pdev)
{
	struct mmc_host *mmc = platform_get_drvdata(pdev);

	platform_set_drvdata(pdev, NULL);

	if (mmc) {
		struct ubicom32sd_data *ud = (struct ubicom32sd_data *)mmc_priv(mmc);

		gpio_free(ud->pdata->cards[0].pin_pwr);
		gpio_free(ud->pdata->cards[0].pin_cd);
		if (ud->pdata->cards[0].pin_wp != -1) {
			gpio_free(ud->pdata->cards[0].pin_wp);
		}

		mmc_remove_host(mmc);
		mmc_free_host(mmc);
	}

	/*
	 * Note that our data is allocated as part of the mmc structure
	 * so we don't need to free it.
	 */
	return 0;
}
示例#12
0
static void sunximmc_shutdown(struct platform_device *pdev)
{
    struct mmc_host    *mmc = platform_get_drvdata(pdev);
    struct sunxi_mmc_host *smc_host = mmc_priv(mmc);

    SMC_MSG("%s: ShutDown.\n", dev_name(&pdev->dev));

    sunximmc_procfs_remove(smc_host);
    mmc_remove_host(mmc);
}
示例#13
0
static void s3cmci_shutdown(struct platform_device *pdev)
{
	struct mmc_host	*mmc = platform_get_drvdata(pdev);
	struct s3cmci_host *host = mmc_priv(mmc);

	if (host->irq_cd >= 0)
		free_irq(host->irq_cd, host);

	mmc_remove_host(mmc);
	clk_disable(host->clk);
}
示例#14
0
static int omap_mmc_remove(struct platform_device *pdev)
{
	struct mmc_omap_host *host = platform_get_drvdata(pdev);
	struct resource *res;
	u16 vdd = 0;

	/*
	 * TODO:
	 * The timer could kick in and turn off the clocks.
	 * if mmc_remove_host touches the mmc module regs, this can
	 * crash. So need to verify if mmc_remove_host indeed touches
	 * the module regs.
	 */
	mmc_clk_try_enable(host);

	if (!(OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET)) {
	/*
	 * Set the vdd back to 3V,
	 * applicable for dual volt support.
	 */
		vdd = fls(host->mmc->ocr_avail) - 1;
		if (omap_mmc_switch_opcond(host, vdd) != 0)
			host->mmc->ios.vdd = vdd;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res)
		release_mem_region(res->start, res->end - res->start + 1);

	platform_set_drvdata(pdev, NULL);
	if (host) {
		mmc_remove_host(host->mmc);
		if (host->pdata->cleanup)
			host->pdata->cleanup(&pdev->dev);
		free_irq(host->irq, host);
		if (mmc_slot(host).card_detect_irq)
			free_irq(mmc_slot(host).card_detect_irq, host);
		flush_scheduled_work();

		mmc_clk_try_disable(host);
		clk_put(host->fclk);
		clk_put(host->iclk);
		if (host->dbclk_enabled) {
			clk_disable(host->dbclk);
			clk_put(host->dbclk);
		}

		mmc_free_host(host->mmc);
		iounmap(host->base);
	}

	return 0;
}
示例#15
0
static int ocsdc_remove(struct platform_device *pdev)
{
	struct mmc_host *mmc = platform_get_drvdata(pdev);
	platform_set_drvdata(pdev, NULL);

	if (mmc) {
		mmc_remove_host(mmc);
		mmc_free_host(mmc);
	}

//	printk("ocsdc_remove\n");
	return 0;
}
示例#16
0
static int msmsdcc_remove(struct platform_device *pdev)
{
	struct mmc_host *mmc = mmc_get_drvdata(pdev);
	struct mmc_platform_data *plat;
	struct msmsdcc_host *host;

	if (!mmc)
		return -ENXIO;

	host = mmc_priv(mmc);

	DBG(host, "Removing SDCC2 device = %d\n", pdev->id);
	plat = host->plat;

	if (!plat->status_irq)
		sysfs_remove_group(&pdev->dev.kobj, &dev_attr_grp);

	tasklet_kill(&host->dma_tlet);
	mmc_remove_host(mmc);

	if (plat->status_irq)
		free_irq(plat->status_irq, host);

	if (plat->sdiowakeup_irq) {
		set_irq_wake(host->plat->sdiowakeup_irq, 0);
		free_irq(plat->sdiowakeup_irq, host);
	}

	free_irq(host->irqres->start, host);
	free_irq(host->irqres->end, host);

	writel(0, host->base + MMCIMASK0);
	writel(0, host->base + MMCIMASK1);
	writel(MCI_CLEAR_STATIC_MASK, host->base + MMCICLEAR);
	writel(0, host->base + MMCIDATACTRL);
	writel(0, host->base + MMCICOMMAND);

	clk_put(host->clk);
	clk_put(host->pclk);

	dma_free_coherent(NULL, sizeof(struct msmsdcc_nc_dmadata),
			host->dma.nc, host->dma.nc_busaddr);
	iounmap(host->base);
	mmc_free_host(mmc);

#ifdef CONFIG_HAS_EARLYSUSPEND
	unregister_early_suspend(&host->early_suspend);
#endif

	return 0;
}
示例#17
0
static int sdhci_sprd_remove(struct platform_device *pdev)
{
	struct sdhci_host *host = platform_get_drvdata(pdev);
	struct sdhci_sprd_host *sprd_host = TO_SPRD_HOST(host);
	struct mmc_host *mmc = host->mmc;

	mmc_remove_host(mmc);
	clk_disable_unprepare(sprd_host->clk_sdio);
	clk_disable_unprepare(sprd_host->clk_enable);

	mmc_free_host(mmc);

	return 0;
}
示例#18
0
static int __devexit ak98_sdio_remove(struct platform_device *dev)
{
	struct mmc_host *mmc = platform_get_drvdata(dev);
  
	platform_set_drvdata(dev, NULL);

	if (mmc) {
		struct ak98_mci_host *host = mmc_priv(mmc);

#if 0
		del_timer_sync(&host->timer);
#endif

		ak98sdio_cpufreq_deregister(host);

		mmc_remove_host(mmc);

		writel(0, host->base + AK98MCIMASK);

		writel(0, host->base + AK98MCICOMMAND);
		writel(0, host->base + AK98MCIDATACTRL);

#if 0
		if (gpio_is_valid(host->gpio_cd))
			free_irq(host->irq_cd, host);
		free_irq(host->irq_mci, host);

		if (host->gpio_wp != -ENOSYS)
			gpio_free(host->gpio_wp);
		if (host->gpio_cd != -ENOSYS)
			gpio_free(host->gpio_cd);
#else
        if (host->irq_cd > 0)
        {
		    free_irq(host->irq_cd, host);
		}
		free_irq(host->irq_mci, host);
#endif

		iounmap(host->base);
		clk_disable(host->clk);
		clk_put(host->clk);

		mmc_free_host(mmc);
	}

	return 0;
}
示例#19
0
static void mmc_omap_remove_slot(struct mmc_omap_slot *slot)
{
	struct mmc_host *mmc = slot->mmc;

	if (slot->pdata->name != NULL)
		device_remove_file(&mmc->class_dev, &dev_attr_slot_name);
	if (slot->pdata->get_cover_state != NULL)
		device_remove_file(&mmc->class_dev, &dev_attr_cover_switch);

	tasklet_kill(&slot->cover_tasklet);
	del_timer_sync(&slot->cover_timer);
	flush_scheduled_work();

	mmc_remove_host(mmc);
	mmc_free_host(mmc);
}
示例#20
0
static int s3cmci_remove(struct platform_device *pdev)
{
	struct mmc_host 	*mmc  = platform_get_drvdata(pdev);
	struct s3cmci_host 	*host = mmc_priv(mmc);

	mmc_remove_host(mmc);
	clk_disable(host->clk);
	clk_put(host->clk);
 	free_irq(host->irq_cd, host);
 	free_irq(host->irq, host);
	iounmap(host->base);
	release_mem_region(host->mem->start, RESSIZE(host->mem));
	mmc_free_host(mmc);

	return 0;
}
示例#21
0
文件: wbsd.c 项目: prime5711/blackbox
static int wbsd_remove(struct device* dev)
{
	struct mmc_host* mmc = dev_get_drvdata(dev);
	struct wbsd_host* host;
	
	if (!mmc)
		return 0;

	host = mmc_priv(mmc);
	
	/*
	 * Unregister host with MMC layer.
	 */
	mmc_remove_host(mmc);

	/*
	 * Power down the SD/MMC function.
	 */
	wbsd_unlock_config(host);
	wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD);
	wbsd_write_config(host, WBSD_CONF_ENABLE, 0);
	wbsd_lock_config(host);
	
	/*
	 * Free resources.
	 */
	if (host->dma_buffer)
		kfree(host->dma_buffer);
	
	if (host->dma >= 0)
		free_dma(host->dma);

	free_irq(host->irq, host);
	
	tasklet_kill(&host->card_tasklet);
	tasklet_kill(&host->fifo_tasklet);
	tasklet_kill(&host->crc_tasklet);
	tasklet_kill(&host->timeout_tasklet);
	tasklet_kill(&host->finish_tasklet);
	tasklet_kill(&host->block_tasklet);
	
	wbsd_release_regions(host);
	
	mmc_free_host(mmc);

	return 0;
}
示例#22
0
文件: mxs-mmc.c 项目: 020gzh/linux
static int mxs_mmc_remove(struct platform_device *pdev)
{
	struct mmc_host *mmc = platform_get_drvdata(pdev);
	struct mxs_mmc_host *host = mmc_priv(mmc);
	struct mxs_ssp *ssp = &host->ssp;

	mmc_remove_host(mmc);

	if (ssp->dmach)
		dma_release_channel(ssp->dmach);

	clk_disable_unprepare(ssp->clk);

	mmc_free_host(mmc);

	return 0;
}
示例#23
0
static void ushc_disconnect(struct usb_interface *intf)
{
	struct ushc_data *ushc = usb_get_intfdata(intf);

	spin_lock_irq(&ushc->lock);
	set_bit(DISCONNECTED, &ushc->flags);
	spin_unlock_irq(&ushc->lock);

	usb_kill_urb(ushc->int_urb);
	usb_kill_urb(ushc->cbw_urb);
	usb_kill_urb(ushc->data_urb);
	usb_kill_urb(ushc->csw_urb);

	mmc_remove_host(ushc->mmc);

	ushc_clean_up(ushc);
}
static int __exit at91_mci_remove(struct platform_device *pdev)
{
	struct mmc_host *mmc = platform_get_drvdata(pdev);
	struct at91mci_host *host;
	struct resource *res;

	if (!mmc)
		return -1;

	host = mmc_priv(mmc);

	if (host->buffer)
		dma_free_coherent(&pdev->dev, MCI_BUFSIZE,
				host->buffer, host->physical_address);

	if (gpio_is_valid(host->board->det_pin)) {
		if (device_can_wakeup(&pdev->dev))
			free_irq(gpio_to_irq(host->board->det_pin), host);
		device_init_wakeup(&pdev->dev, 0);
		gpio_free(host->board->det_pin);
	}

	at91_mci_disable(host);
	del_timer_sync(&host->timer);
	mmc_remove_host(mmc);
	free_irq(host->irq, host);

	clk_disable(host->mci_clk);			
	clk_put(host->mci_clk);

	if (gpio_is_valid(host->board->vcc_pin))
		gpio_free(host->board->vcc_pin);
	if (gpio_is_valid(host->board->wp_pin))
		gpio_free(host->board->wp_pin);

	iounmap(host->baseaddr);
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	release_mem_region(res->start, resource_size(res));

	mmc_free_host(mmc);
	platform_set_drvdata(pdev, NULL);
	pr_debug("MCI Removed\n");

	return 0;
}
示例#25
0
static void sdio_card_reset_worker(struct work_struct *work)
{
	struct mmc_host *target = reset_host;

	/* The actual reset operation must be run outside of driver thread.
	 * This is because mmc_remove_host() will cause the device to be
	 * instantly destroyed, and the driver then needs to end its thread,
	 * leading to a deadlock.
	 *
	 * We run it in a totally independent workqueue.
	 */

	pr_err("Resetting card...\n");
	mmc_remove_host(target);
	/* 20ms delay is based on experiment with sdhci controller */
	mdelay(20);
	mmc_add_host(target);
}
示例#26
0
static int __devexit sh_mmcif_remove(struct platform_device *pdev)
{
	struct sh_mmcif_host *host = platform_get_drvdata(pdev);
	struct sh_mmcif_plat_data *pd = pdev->dev.platform_data;
	int irq[2];

	host->dying = true;
	clk_enable(host->hclk);
	pm_runtime_get_sync(&pdev->dev);

	dev_pm_qos_hide_latency_limit(&pdev->dev);

	if (pd && pd->use_cd_gpio)
		mmc_gpio_free_cd(host->mmc);

	mmc_remove_host(host->mmc);
	sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);

	/*
	 * FIXME: cancel_delayed_work(_sync)() and free_irq() race with the
	 * mmc_remove_host() call above. But swapping order doesn't help either
	 * (a query on the linux-mmc mailing list didn't bring any replies).
	 */
	cancel_delayed_work_sync(&host->timeout_work);

	if (host->addr)
		iounmap(host->addr);

	irq[0] = platform_get_irq(pdev, 0);
	irq[1] = platform_get_irq(pdev, 1);

	free_irq(irq[0], host);
	free_irq(irq[1], host);

	platform_set_drvdata(pdev, NULL);

	clk_disable(host->hclk);
	mmc_free_host(host->mmc);
	pm_runtime_put_sync(&pdev->dev);
	pm_runtime_disable(&pdev->dev);

	return 0;
}
示例#27
0
static int __devexit mmci_remove(struct amba_device *dev)
{
	struct mmc_host *mmc = amba_get_drvdata(dev);

	amba_set_drvdata(dev, NULL);

	if (mmc) {
		struct mmci_host *host = mmc_priv(mmc);

		del_timer_sync(&host->timer);

		mmc_remove_host(mmc);

		writel(0, host->base + MMCIMASK0);
		writel(0, host->base + MMCIMASK1);

		writel(0, host->base + MMCICOMMAND);
		writel(0, host->base + MMCIDATACTRL);

		free_irq(dev->irq[0], host);
		free_irq(dev->irq[1], host);

		if (host->gpio_wp != -ENOSYS)
			gpio_free(host->gpio_wp);
		if (host->gpio_cd != -ENOSYS)
			gpio_free(host->gpio_cd);

		iounmap(host->base);
		clk_disable(host->clk);
		clk_put(host->clk);

		if (regulator_is_enabled(host->vcc))
			regulator_disable(host->vcc);
		regulator_put(host->vcc);

		mmc_free_host(mmc);

		amba_release_regions(dev);
	}

	return 0;
}
static int goldfish_mmc_remove(struct platform_device *pdev)
{
	struct goldfish_mmc_host *host = platform_get_drvdata(pdev);

	platform_set_drvdata(pdev, NULL);

	BUG_ON(host == NULL);

	mmc_remove_host(host->mmc);
	free_irq(host->irq, host);
#if defined(CONFIG_ARM)
	dma_free_writecombine(&pdev->dev, BUFFER_SIZE, host->virt_base, host->phys_base);
#elif defined(CONFIG_X86) || defined(CONFIG_MIPS)
	dma_free_coherent(NULL, BUFFER_SIZE, host->virt_base, host->phys_base);
#else
#error NOT SUPPORTED
#endif
	mmc_free_host(host->mmc);

	return 0;
}
示例#29
0
static int bcm2835_sdhost_remove(struct platform_device *pdev)
{
	struct bcm2835_host *host = platform_get_drvdata(pdev);

	pr_debug("bcm2835_sdhost_remove\n");

	mmc_remove_host(host->mmc);

	bcm2835_sdhost_set_power(host, false);

	free_irq(host->irq, host);

	del_timer_sync(&host->timer);

	tasklet_kill(&host->finish_tasklet);

	mmc_free_host(host->mmc);
	platform_set_drvdata(pdev, NULL);

	pr_debug("bcm2835_sdhost_remove - OK\n");
	return 0;
}
示例#30
0
文件: moxart-mmc.c 项目: 020gzh/linux
static int moxart_remove(struct platform_device *pdev)
{
	struct mmc_host *mmc = dev_get_drvdata(&pdev->dev);
	struct moxart_host *host = mmc_priv(mmc);

	dev_set_drvdata(&pdev->dev, NULL);

	if (mmc) {
		if (!IS_ERR(host->dma_chan_tx))
			dma_release_channel(host->dma_chan_tx);
		if (!IS_ERR(host->dma_chan_rx))
			dma_release_channel(host->dma_chan_rx);
		mmc_remove_host(mmc);
		mmc_free_host(mmc);

		writel(0, host->base + REG_INTERRUPT_MASK);
		writel(0, host->base + REG_POWER_CONTROL);
		writel(readl(host->base + REG_CLOCK_CONTROL) | CLK_OFF,
		       host->base + REG_CLOCK_CONTROL);
	}
	return 0;
}