Example #1
0
static int __devinit ak98_mci_probe(struct platform_device *pdev)
{
	struct ak98_mci_platform_data *plat = pdev->dev.platform_data;
	struct ak98_mci_host *host;
	struct mmc_host *mmc;
	struct resource *res;
	int irq;
	int ret;

	/* must have platform data */
	if (!plat) {
		ret = -EINVAL;
		goto out;
	}

	PK("%s\n", __func__);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	irq = platform_get_irq(pdev, 0);

	PK("res: %x, %u", res->start, resource_size(res));
	res = request_mem_region(res->start, resource_size(res), DRIVER_NAME);
	if (!res) {
		ret = -EBUSY;
		goto out;
	}
	PK("res: %x, %u\n", res->start, resource_size(res));

	mmc = mmc_alloc_host(sizeof(struct ak98_mci_host), &pdev->dev);
	if (!mmc) {
		ret = -ENOMEM;
		goto out;
	}

	host = mmc_priv(mmc);
	host->mmc = mmc;

	host->gpio_wp = -ENOSYS;
	host->gpio_cd = -ENOSYS;

    ak98_mci_reset();
	host->clk = clk_get(&pdev->dev, "mci_clk");

    if (IS_ERR(host->clk)) {
        ret = PTR_ERR(host->clk);
        host->clk = NULL;
        goto host_free;
    }      

	ret = clk_enable(host->clk);
	if (ret)
		goto clk_free;

	host->plat = plat;
	host->asic_clkrate = ak98_get_asic_clk();
	

	host->base = ioremap(res->start, resource_size(res));
	if (!host->base) {
		ret = -ENOMEM;
		goto clk_disable;
	} 
    PK("asic_clkrate: %luhz,host->base=0x%x\n", host->asic_clkrate,host->base);
	mmc->ops = &ak98_mci_ops;
	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;

	/*
	 * set the transmit mode to four data line mode, if not set, 
	 * default is one data line mode.
	 */
	mmc->caps = MMC_CAP_4_BIT_DATA;
#if 0
	mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
#endif 

//	mmc->caps |= MMC_CAP_NEEDS_POLL;
	mmc->f_min = host->asic_clkrate / (255+1 + 255+1);
	mmc->f_max = host->asic_clkrate / (0+1 + 0+1);
	mmc->f_max = mmc->f_max < fmax ? mmc->f_max : fmax;

	/*
	 * We can do SGIO
	 */
	mmc->max_hw_segs = 16;
	mmc->max_phys_segs = NR_SG;

	/*
	 * Since we only have a 16-bit data length register, we must
	 * ensure that we don't exceed 2^16-1 bytes in a single request.
	 */
	mmc->max_req_size = 65536;

	/*
	 * Set the maximum segment size.  Since we aren't doing DMA
	 * (yet) we are only limited by the data length register.
	 */
	mmc->max_seg_size = mmc->max_req_size;

#if 0
	/*
	 * Block size can be up to 2048 bytes, but must be a power of two.
	 */
	mmc->max_blk_size = 2048;
#else
	/* as l2 fifo limit to 512 bytes */
	mmc->max_blk_size = 512;
#endif

	/*
	 * No limit on the number of blocks transferred.
	 */
	mmc->max_blk_count = mmc->max_req_size;

	spin_lock_init(&host->lock);
	
#ifdef CONFIG_MTD_NAND_AK98
    down(&nand_lock);
#endif
    ak98_group_pin_config();
   // writel(SDIO_INTR_CTR_ENABLE, host->base + AK98SDIOINTRCTR);	
	
	writel(MCI_ENABLE|MCI_FAIL_TRIGGER, host->base + AK98MCICLOCK);	
    PK("%s: MCICLOCK: 0x%08x\n", __func__, readl(host->base + AK98MCICLOCK));    

#ifdef CONFIG_MTD_NAND_AK98
    up(&nand_lock);
#endif

	writel(0, host->base + AK98MCIMASK);
	
	PK("request irq %i\n", irq);
	ret = request_irq(irq, ak98_mci_irq, IRQF_DISABLED, DRIVER_NAME " (cmd)", host);
	if (ret)
		goto unmap;
		
	host->irq_mci = irq;

	/*
	* if card detected pin or write protect pin has  
	* been config, then config the pins.
	*/
	if(plat->gpio_cd >= 0)
	{
    	host->gpio_cd = plat->gpio_cd;	
    	ak98_gpio_cfgpin(host->gpio_cd, AK98_GPIO_DIR_INPUT);
    	ak98_gpio_pulldown(host->gpio_cd,AK98_PULLDOWN_DISABLE);
	}
	if(plat->gpio_wp >= 0)
	{
    	host->gpio_wp = plat->gpio_wp;	
    	ak98_gpio_cfgpin(host->gpio_wp, AK98_GPIO_DIR_INPUT);
    	ak98_gpio_pullup(host->gpio_wp, AK98_PULLUP_ENABLE);
    	ak98_gpio_pulldown(host->gpio_wp,AK98_PULLDOWN_DISABLE);
    }
	setup_timer(&host->detect_timer, ak98_mci_detect_change,
		    (unsigned long)host);
		    
	irq = ak98_gpio_to_irq(host->gpio_cd);    
	ret = request_irq(irq, ak98_mci_card_detect_irq,
			  IRQF_DISABLED,
			  DRIVER_NAME " cd", host);
	printk("request gpio irq ret = %d, irq=%d", ret, irq);
	if (ret)
		goto irq_free;
	host->irq_cd = irq;
	host->irq_cd_type = IRQ_TYPE_LEVEL_LOW;	

	platform_set_drvdata(pdev, mmc);

	ret = ak98mci_cpufreq_register(host);
	if (ret) {
		goto irq_free;
	}

	ret = mmc_add_host(mmc);
	if (ret) {
		goto cpufreq_free;
	}

	PK(KERN_INFO "%s: ak98MCI at 0x%016llx irq %d\n",
		mmc_hostname(mmc), (unsigned long long)res->start,
		host->irq_mci);

	return 0;

 cpufreq_free:
	 PK("ERR cpufreq_free\n");
	 ak98mci_cpufreq_deregister(host);
 irq_free:
	PK("ERR irq_free\n");
	free_irq(host->irq_mci, host);
 unmap:
	PK("ERR unmap\n");
	iounmap(host->base);
 clk_disable:
	PK("ERR clk_disable\n");
	clk_disable(host->clk);
 clk_free:
	PK("ERR clk_free\n");
	clk_put(host->clk);
 host_free:
	PK("ERR host_free\n");
	mmc_free_host(mmc);
 out:
	PK("ERR out\n");
	return ret;
}
Example #2
0
static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
{
	struct s3cmci_host *host;
	struct mmc_host	*mmc;
	int ret;

	mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev);
	if (!mmc) {
		ret = -ENOMEM;
		goto probe_out;
	}

	host = mmc_priv(mmc);
	host->mmc 	= mmc;
	host->pdev	= pdev;
	host->is2440	= is2440;

	host->pdata = pdev->dev.platform_data;
	if (!host->pdata) {
		pdev->dev.platform_data = &s3cmci_def_pdata;
		host->pdata = &s3cmci_def_pdata;
	}

	spin_lock_init(&host->complete_lock);
	tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host);

	if (is2440) {
		host->sdiimsk	= S3C2440_SDIIMSK;
		host->sdidata	= S3C2440_SDIDATA;
		host->clk_div	= 1;
	} else {
		host->sdiimsk	= S3C2410_SDIIMSK;
		host->sdidata	= S3C2410_SDIDATA;
		host->clk_div	= 2;
	}

	host->dodma		= 0;
	host->complete_what 	= COMPLETION_NONE;
	host->pio_active 	= XFER_NONE;

	host->dma		= S3CMCI_DMA;

	host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!host->mem) {
		dev_err(&pdev->dev,
			"failed to get io memory region resouce.\n");

		ret = -ENOENT;
		goto probe_free_host;
	}

	host->mem = request_mem_region(host->mem->start,
				       RESSIZE(host->mem), pdev->name);

	if (!host->mem) {
		dev_err(&pdev->dev, "failed to request io memory region.\n");
		ret = -ENOENT;
		goto probe_free_host;
	}

	host->base = ioremap(host->mem->start, RESSIZE(host->mem));
	if (host->base == 0) {
		dev_err(&pdev->dev, "failed to ioremap() io memory region.\n");
		ret = -EINVAL;
		goto probe_free_mem_region;
	}

	host->irq = platform_get_irq(pdev, 0);
	if (host->irq == 0) {
		dev_err(&pdev->dev, "failed to get interrupt resouce.\n");
		ret = -EINVAL;
		goto probe_iounmap;
	}

	if (request_irq(host->irq, s3cmci_irq, 0, DRIVER_NAME, host)) {
		dev_err(&pdev->dev, "failed to request mci interrupt.\n");
		ret = -ENOENT;
		goto probe_iounmap;
	}

	/* We get spurious interrupts even when we have set the IMSK
	 * register to ignore everything, so use disable_irq() to make
	 * ensure we don't lock the system with un-serviceable requests. */

	disable_irq(host->irq);

	host->irq_cd = s3c2410_gpio_getirq(host->pdata->gpio_detect);

	if (host->irq_cd >= 0) {
		if (request_irq(host->irq_cd, s3cmci_irq_cd,
				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
				DRIVER_NAME, host)) {
			dev_err(&pdev->dev, "can't get card detect irq.\n");
			ret = -ENOENT;
			goto probe_free_irq;
		}
	} else {
		dev_warn(&pdev->dev, "host detect has no irq available\n");
		s3c2410_gpio_cfgpin(host->pdata->gpio_detect,
				    S3C2410_GPIO_INPUT);
	}

	if (host->pdata->gpio_wprotect)
		s3c2410_gpio_cfgpin(host->pdata->gpio_wprotect,
				    S3C2410_GPIO_INPUT);

	if (s3c2410_dma_request(S3CMCI_DMA, &s3cmci_dma_client, NULL) < 0) {
		dev_err(&pdev->dev, "unable to get DMA channel.\n");
		ret = -EBUSY;
		goto probe_free_irq_cd;
	}

	host->clk = clk_get(&pdev->dev, "sdi");
	if (IS_ERR(host->clk)) {
		dev_err(&pdev->dev, "failed to find clock source.\n");
		ret = PTR_ERR(host->clk);
		host->clk = NULL;
		goto probe_free_host;
	}

	ret = clk_enable(host->clk);
	if (ret) {
		dev_err(&pdev->dev, "failed to enable clock source.\n");
		goto clk_free;
	}

	host->clk_rate = clk_get_rate(host->clk);

	mmc->ops 	= &s3cmci_ops;
	mmc->ocr_avail	= MMC_VDD_32_33 | MMC_VDD_33_34;
	mmc->caps	= MMC_CAP_4_BIT_DATA;
	mmc->f_min 	= host->clk_rate / (host->clk_div * 256);
	mmc->f_max 	= host->clk_rate / host->clk_div;

	if (host->pdata->ocr_avail)
		mmc->ocr_avail = host->pdata->ocr_avail;

	mmc->max_blk_count	= 4095;
	mmc->max_blk_size	= 4095;
	mmc->max_req_size	= 4095 * 512;
	mmc->max_seg_size	= mmc->max_req_size;

	mmc->max_phys_segs	= 128;
	mmc->max_hw_segs	= 128;

	dbg(host, dbg_debug,
	    "probe: mode:%s mapped mci_base:%p irq:%u irq_cd:%u dma:%u.\n",
	    (host->is2440?"2440":""),
	    host->base, host->irq, host->irq_cd, host->dma);

	ret = mmc_add_host(mmc);
	if (ret) {
		dev_err(&pdev->dev, "failed to add mmc host.\n");
		goto free_dmabuf;
	}

	platform_set_drvdata(pdev, mmc);
	dev_info(&pdev->dev, "initialisation done.\n");

	return 0;

 free_dmabuf:
	clk_disable(host->clk);

 clk_free:
	clk_put(host->clk);

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

 probe_free_irq:
	free_irq(host->irq, host);

 probe_iounmap:
	iounmap(host->base);

 probe_free_mem_region:
	release_mem_region(host->mem->start, RESSIZE(host->mem));

 probe_free_host:
	mmc_free_host(mmc);
 probe_out:
	return ret;
}
Example #3
0
static int sh_mmcif_probe(struct platform_device *pdev)
{
	int ret = 0, irq[2];
	struct mmc_host *mmc;
	struct sh_mmcif_host *host;
	struct sh_mmcif_plat_data *pd = pdev->dev.platform_data;
	struct resource *res;
	void __iomem *reg;
	const char *name;

	irq[0] = platform_get_irq(pdev, 0);
	irq[1] = platform_get_irq(pdev, 1);
	if (irq[0] < 0) {
		dev_err(&pdev->dev, "Get irq error\n");
		return -ENXIO;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	reg = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(reg))
		return PTR_ERR(reg);

	mmc = mmc_alloc_host(sizeof(struct sh_mmcif_host), &pdev->dev);
	if (!mmc)
		return -ENOMEM;

	ret = mmc_of_parse(mmc);
	if (ret < 0)
		goto err_host;

	host		= mmc_priv(mmc);
	host->mmc	= mmc;
	host->addr	= reg;
	host->timeout	= msecs_to_jiffies(10000);
	host->ccs_enable = !pd || !pd->ccs_unsupported;
	host->clk_ctrl2_enable = pd && pd->clk_ctrl2_present;

	host->pd = pdev;

	spin_lock_init(&host->lock);

	mmc->ops = &sh_mmcif_ops;
	sh_mmcif_init_ocr(host);

	mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_WAIT_WHILE_BUSY;
	if (pd && pd->caps)
		mmc->caps |= pd->caps;
	mmc->max_segs = 32;
	mmc->max_blk_size = 512;
	mmc->max_req_size = PAGE_CACHE_SIZE * mmc->max_segs;
	mmc->max_blk_count = mmc->max_req_size / mmc->max_blk_size;
	mmc->max_seg_size = mmc->max_req_size;

	platform_set_drvdata(pdev, host);

	pm_runtime_enable(&pdev->dev);
	host->power = false;

	host->hclk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(host->hclk)) {
		ret = PTR_ERR(host->hclk);
		dev_err(&pdev->dev, "cannot get clock: %d\n", ret);
		goto err_pm;
	}
	ret = sh_mmcif_clk_update(host);
	if (ret < 0)
		goto err_pm;

	ret = pm_runtime_resume(&pdev->dev);
	if (ret < 0)
		goto err_clk;

	INIT_DELAYED_WORK(&host->timeout_work, mmcif_timeout_work);

	sh_mmcif_sync_reset(host);
	sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);

	name = irq[1] < 0 ? dev_name(&pdev->dev) : "sh_mmc:error";
	ret = devm_request_threaded_irq(&pdev->dev, irq[0], sh_mmcif_intr,
					sh_mmcif_irqt, 0, name, host);
	if (ret) {
		dev_err(&pdev->dev, "request_irq error (%s)\n", name);
		goto err_clk;
	}
	if (irq[1] >= 0) {
		ret = devm_request_threaded_irq(&pdev->dev, irq[1],
						sh_mmcif_intr, sh_mmcif_irqt,
						0, "sh_mmc:int", host);
		if (ret) {
			dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n");
			goto err_clk;
		}
	}

	if (pd && pd->use_cd_gpio) {
		ret = mmc_gpio_request_cd(mmc, pd->cd_gpio, 0);
		if (ret < 0)
			goto err_clk;
	}

	mutex_init(&host->thread_lock);

	ret = mmc_add_host(mmc);
	if (ret < 0)
		goto err_clk;

	dev_pm_qos_expose_latency_limit(&pdev->dev, 100);

	dev_info(&pdev->dev, "Chip version 0x%04x, clock rate %luMHz\n",
		 sh_mmcif_readl(host->addr, MMCIF_CE_VERSION) & 0xffff,
		 clk_get_rate(host->hclk) / 1000000UL);

	clk_disable_unprepare(host->hclk);
	return ret;

err_clk:
	clk_disable_unprepare(host->hclk);
err_pm:
	pm_runtime_disable(&pdev->dev);
err_host:
	mmc_free_host(mmc);
	return ret;
}
Example #4
0
static int __devinit sh_mmcif_probe(struct platform_device *pdev)
{
	int ret = 0, irq[2];
	struct mmc_host *mmc;
	struct sh_mmcif_host *host;
	struct sh_mmcif_plat_data *pd = pdev->dev.platform_data;
	struct resource *res;
	void __iomem *reg;
	char clk_name[8];

	irq[0] = platform_get_irq(pdev, 0);
	irq[1] = platform_get_irq(pdev, 1);
	if (irq[0] < 0 || irq[1] < 0) {
		dev_err(&pdev->dev, "Get irq error\n");
		return -ENXIO;
	}
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "platform_get_resource error.\n");
		return -ENXIO;
	}
	reg = ioremap(res->start, resource_size(res));
	if (!reg) {
		dev_err(&pdev->dev, "ioremap error.\n");
		return -ENOMEM;
	}

	mmc = mmc_alloc_host(sizeof(struct sh_mmcif_host), &pdev->dev);
	if (!mmc) {
		ret = -ENOMEM;
		goto ealloch;
	}
	host		= mmc_priv(mmc);
	host->mmc	= mmc;
	host->addr	= reg;
	host->timeout	= 1000;

	host->pd = pdev;

	spin_lock_init(&host->lock);

	mmc->ops = &sh_mmcif_ops;
	sh_mmcif_init_ocr(host);

	mmc->caps = MMC_CAP_MMC_HIGHSPEED;
	if (pd && pd->caps)
		mmc->caps |= pd->caps;
	mmc->max_segs = 32;
	mmc->max_blk_size = 512;
	mmc->max_req_size = PAGE_CACHE_SIZE * mmc->max_segs;
	mmc->max_blk_count = mmc->max_req_size / mmc->max_blk_size;
	mmc->max_seg_size = mmc->max_req_size;

	platform_set_drvdata(pdev, host);

	pm_runtime_enable(&pdev->dev);
	host->power = false;

	snprintf(clk_name, sizeof(clk_name), "mmc%d", pdev->id);
	host->hclk = clk_get(&pdev->dev, clk_name);
	if (IS_ERR(host->hclk)) {
		ret = PTR_ERR(host->hclk);
		dev_err(&pdev->dev, "cannot get clock \"%s\": %d\n", clk_name, ret);
		goto eclkget;
	}
	ret = sh_mmcif_clk_update(host);
	if (ret < 0)
		goto eclkupdate;

	ret = pm_runtime_resume(&pdev->dev);
	if (ret < 0)
		goto eresume;

	INIT_DELAYED_WORK(&host->timeout_work, mmcif_timeout_work);

	sh_mmcif_sync_reset(host);
	sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);

	ret = request_threaded_irq(irq[0], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:error", host);
	if (ret) {
		dev_err(&pdev->dev, "request_irq error (sh_mmc:error)\n");
		goto ereqirq0;
	}
	ret = request_threaded_irq(irq[1], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:int", host);
	if (ret) {
		dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n");
		goto ereqirq1;
	}

	if (pd && pd->use_cd_gpio) {
		ret = mmc_gpio_request_cd(mmc, pd->cd_gpio);
		if (ret < 0)
			goto erqcd;
	}

	clk_disable(host->hclk);
	ret = mmc_add_host(mmc);
	if (ret < 0)
		goto emmcaddh;

	dev_pm_qos_expose_latency_limit(&pdev->dev, 100);

	dev_info(&pdev->dev, "driver version %s\n", DRIVER_VERSION);
	dev_dbg(&pdev->dev, "chip ver H'%04x\n",
		sh_mmcif_readl(host->addr, MMCIF_CE_VERSION) & 0x0000ffff);
	return ret;

emmcaddh:
	if (pd && pd->use_cd_gpio)
		mmc_gpio_free_cd(mmc);
erqcd:
	free_irq(irq[1], host);
ereqirq1:
	free_irq(irq[0], host);
ereqirq0:
	pm_runtime_suspend(&pdev->dev);
eresume:
	clk_disable(host->hclk);
eclkupdate:
	clk_put(host->hclk);
eclkget:
	pm_runtime_disable(&pdev->dev);
	mmc_free_host(mmc);
ealloch:
	iounmap(reg);
	return ret;
}
Example #5
0
/*
 * Probe for the device
 */
static int __init at91_mci_probe(struct platform_device *pdev)
{
	struct mmc_host *mmc;
	struct at91mci_host *host;
	struct resource *res;
	int ret;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENXIO;

	if (!request_mem_region(res->start, resource_size(res), DRIVER_NAME))
		return -EBUSY;

	mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev);
	if (!mmc) {
		ret = -ENOMEM;
		dev_dbg(&pdev->dev, "couldn't allocate mmc host\n");
		goto fail6;
	}

	mmc->ops = &at91_mci_ops;
	mmc->f_min = 375000;
	mmc->f_max = 25000000;
	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
	mmc->caps = 0;

	mmc->max_blk_size  = MCI_MAXBLKSIZE;
	mmc->max_blk_count = MCI_BLKATONCE;
	mmc->max_req_size  = MCI_BUFSIZE;
	mmc->max_segs      = MCI_BLKATONCE;
	mmc->max_seg_size  = MCI_BUFSIZE;

	host = mmc_priv(mmc);
	host->mmc = mmc;
	host->bus_mode = 0;
	host->board = pdev->dev.platform_data;
	if (host->board->wire4) {
		if (at91mci_is_mci1rev2xx())
			mmc->caps |= MMC_CAP_4_BIT_DATA;
		else
			dev_warn(&pdev->dev, "4 wire bus mode not supported"
				" - using 1 wire\n");
	}

	host->buffer = dma_alloc_coherent(&pdev->dev, MCI_BUFSIZE,
					&host->physical_address, GFP_KERNEL);
	if (!host->buffer) {
		ret = -ENOMEM;
		dev_err(&pdev->dev, "Can't allocate transmit buffer\n");
		goto fail5;
	}

	/* Add SDIO capability when available */
	if (at91mci_is_mci1rev2xx()) {
		/* at91mci MCI1 rev2xx sdio interrupt erratum */
		if (host->board->wire4 || !host->board->slot_b)
			mmc->caps |= MMC_CAP_SDIO_IRQ;
	}

	/*
	 * Reserve GPIOs ... board init code makes sure these pins are set
	 * up as GPIOs with the right direction (input, except for vcc)
	 */
	if (host->board->det_pin) {
		ret = gpio_request(host->board->det_pin, "mmc_detect");
		if (ret < 0) {
			dev_dbg(&pdev->dev, "couldn't claim card detect pin\n");
			goto fail4b;
		}
	}
	if (host->board->wp_pin) {
		ret = gpio_request(host->board->wp_pin, "mmc_wp");
		if (ret < 0) {
			dev_dbg(&pdev->dev, "couldn't claim wp sense pin\n");
			goto fail4;
		}
	}
	if (host->board->vcc_pin) {
		ret = gpio_request(host->board->vcc_pin, "mmc_vcc");
		if (ret < 0) {
			dev_dbg(&pdev->dev, "couldn't claim vcc switch pin\n");
			goto fail3;
		}
	}

	/*
	 * Get Clock
	 */
	host->mci_clk = clk_get(&pdev->dev, "mci_clk");
	if (IS_ERR(host->mci_clk)) {
		ret = -ENODEV;
		dev_dbg(&pdev->dev, "no mci_clk?\n");
		goto fail2;
	}

	/*
	 * Map I/O region
	 */
	host->baseaddr = ioremap(res->start, resource_size(res));
	if (!host->baseaddr) {
		ret = -ENOMEM;
		goto fail1;
	}

	/*
	 * Reset hardware
	 */
	clk_enable(host->mci_clk);		/* Enable the peripheral clock */
	at91_mci_disable(host);
	at91_mci_enable(host);

	/*
	 * Allocate the MCI interrupt
	 */
	host->irq = platform_get_irq(pdev, 0);
	ret = request_irq(host->irq, at91_mci_irq, IRQF_SHARED,
			mmc_hostname(mmc), host);
	if (ret) {
		dev_dbg(&pdev->dev, "request MCI interrupt failed\n");
		goto fail0;
	}

	setup_timer(&host->timer, at91_timeout_timer, (unsigned long)host);

	platform_set_drvdata(pdev, mmc);

	/*
	 * Add host to MMC layer
	 */
	if (host->board->det_pin) {
		host->present = !gpio_get_value(host->board->det_pin);
	}
	else
		host->present = -1;

	mmc_add_host(mmc);

	/*
	 * monitor card insertion/removal if we can
	 */
	if (host->board->det_pin) {
		ret = request_irq(gpio_to_irq(host->board->det_pin),
				at91_mmc_det_irq, 0, mmc_hostname(mmc), host);
		if (ret)
			dev_warn(&pdev->dev, "request MMC detect irq failed\n");
		else
			device_init_wakeup(&pdev->dev, 1);
	}

	pr_debug("Added MCI driver\n");

	return 0;

fail0:
	clk_disable(host->mci_clk);
	iounmap(host->baseaddr);
fail1:
	clk_put(host->mci_clk);
fail2:
	if (host->board->vcc_pin)
		gpio_free(host->board->vcc_pin);
fail3:
	if (host->board->wp_pin)
		gpio_free(host->board->wp_pin);
fail4:
	if (host->board->det_pin)
		gpio_free(host->board->det_pin);
fail4b:
	if (host->buffer)
		dma_free_coherent(&pdev->dev, MCI_BUFSIZE,
				host->buffer, host->physical_address);
fail5:
	mmc_free_host(mmc);
fail6:
	release_mem_region(res->start, resource_size(res));
	dev_err(&pdev->dev, "probe failed, err %d\n", ret);
	return ret;
}
Example #6
0
static int csb536pc_mmc_probe(struct device *dev)
{
    struct platform_device *pdev = to_platform_device(dev);
    struct mmc_host *mmc;
    struct csb536pc_mmc_host *host = NULL;
    struct resource *r;
    int ret;
//    int irq;

    _cp;

    r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if (r == NULL) {
        return -ENXIO;
    }
//	irq = platform_get_irq(pdev, 0);
//	if (irq == NO_IRQ) {
//		return -ENXIO;
//      }

//    _cp;
//    r = request_mem_region(r->start, SZ_4K, DRIVER_NAME);
//    if (r == NULL) {
//        return -EBUSY;
//    }

    _cp;
    mmc = mmc_alloc_host(sizeof(struct csb536pc_mmc_host), dev);
    if (mmc == NULL ) {
        ret = -ENOMEM;
        goto out;
    }

    _cp;
	mmc->ops = &csb536pc_mmc_ops;
//	mmc->f_min = CLOCKRATE_MIN;
//	mmc->f_max = CLOCKRATE_MAX;

    /*
     * Let's not deal with SG for now.
     */
    _cp;
    mmc->max_phys_segs = NR_SG;

    _cp;
    mmc->max_seg_size = PAGE_SIZE;

    _cp;
    host = mmc_priv(mmc);
    host->mmc = mmc;
    host->dma = -1;
    host->pdata = pdev->dev.platform_data;
//	mmc->ocr_avail = host->pdata ?
//			 host->pdata->ocr_mask :
//			 MMC_VDD_32_33|MMC_VDD_33_34;

//    host->sg_cpu = dma_alloc_coherent(dev, PAGE_SIZE, &host->sg_dma, GFP_KERNEL);
//	if (!host->sg_cpu) {
//		ret = -ENOMEM;
//		goto out;
//	}

    spin_lock_init(&host->lock);
//    host->res = r;
//    host->irq = irq;
//	host->imask = MMC_I_MASK_ALL;

    host->base = ioremap(r->start, SZ_4K);
    if (host->base == NULL) {
        ret = -ENOMEM;
        goto out;
    }

#if 0
    /* Configure GPIO for SPI and MMC */
    imx_gpio_mode(14 | GPIO_PORTC | GPIO_PF);    /* SCLK */
    imx_gpio_mode(15 | GPIO_PORTC | GPIO_PF);    /* *SS */
    imx_gpio_mode(16 | GPIO_PORTC | GPIO_PF);    /* MISO */
    imx_gpio_mode(17 | GPIO_PORTC | GPIO_PF);    /* MOSI */

    imx_gpio_mode(14 | GPIO_PORTB | GPIO_OUT);    /* SD_VEN */
    /* Disable the SD voltage regulator */
    DR(1) &= ~(1 << 14)
  
    SSP1_CTRL_REG = (
        SSP_RATE_DIV256  |  /*  PCLK2 = SYSCLK/4 = 24MHz. 24MHZ/125KHz = 192 */
        SSP_MODE_MASTER  |
        SSP_SS_POL_LOW   |
        SSP_ENABLE       |
        SSP_PHA0         |
        SSP_POL0         |
        SSP_WS(8));
#endif
	/*
	 * Ensure that the host controller is shut down, and setup
	 * with our defaults.
	 */
//	csb536pc_mmc_stop_clock(host);
//	writel(0, host->base + MMC_SPI);
//	writel(64, host->base + MMC_RESTO);
//	writel(host->imask, host->base + MMC_I_MASK);

//	host->dma = pxa_request_dma(DRIVER_NAME, DMA_PRIO_LOW,
//				    csb536pc_mmc_dma_irq, host);
//	if (host->dma < 0) {
//		ret = -EBUSY;
//		goto out;
//	}

//	ret = request_irq(host->irq, csb536pc_mmc_irq, 0, DRIVER_NAME, host);
//	if (ret)
//		goto out;

	dev_set_drvdata(dev, mmc);

//	if (host->pdata && host->pdata->init)
//		host->pdata->init(dev, csb536pc_mmc_detect_irq, mmc);

	mmc_add_host(mmc);

	return 0;

 out:
	if (host) {
//		if (host->dma >= 0)
//			pxa_free_dma(host->dma);
		if (host->base)
			iounmap(host->base);
//		if (host->sg_cpu)
//			dma_free_coherent(dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
	}
	if (mmc)
		mmc_free_host(mmc);
	release_resource(r);
	return ret;
}
Example #7
0
static int __devinit mmc_omap_new_slot(struct mmc_omap_host *host, int id)
{
	struct mmc_omap_slot *slot = NULL;
	struct mmc_host *mmc;
	int r;

	mmc = mmc_alloc_host(sizeof(struct mmc_omap_slot), host->dev);
	if (mmc == NULL)
		return -ENOMEM;

	slot = mmc_priv(mmc);
	slot->host = host;
	slot->mmc = mmc;
	slot->id = id;
	slot->pdata = &host->pdata->slots[id];

	host->slots[id] = slot;

	mmc->caps = 0;
	if (host->pdata->slots[id].wires >= 4)
		mmc->caps |= MMC_CAP_4_BIT_DATA;

	mmc->ops = &mmc_omap_ops;
	mmc->f_min = 400000;

	if (cpu_class_is_omap2())
		mmc->f_max = 48000000;
	else
		mmc->f_max = 24000000;
	if (host->pdata->max_freq)
		mmc->f_max = min(host->pdata->max_freq, mmc->f_max);
	mmc->ocr_avail = slot->pdata->ocr_mask;

	/* Use scatterlist DMA to reduce per-transfer costs.
	 * NOTE max_seg_size assumption that small blocks aren't
	 * normally used (except e.g. for reading SD registers).
	 */
	mmc->max_segs = 32;
	mmc->max_blk_size = 2048;	/* BLEN is 11 bits (+1) */
	mmc->max_blk_count = 2048;	/* NBLK is 11 bits (+1) */
	mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
	mmc->max_seg_size = mmc->max_req_size;

	r = mmc_add_host(mmc);
	if (r < 0)
		goto err_remove_host;

	if (slot->pdata->name != NULL) {
		r = device_create_file(&mmc->class_dev,
					&dev_attr_slot_name);
		if (r < 0)
			goto err_remove_host;
	}

	if (slot->pdata->get_cover_state != NULL) {
		r = device_create_file(&mmc->class_dev,
					&dev_attr_cover_switch);
		if (r < 0)
			goto err_remove_slot_name;

		setup_timer(&slot->cover_timer, mmc_omap_cover_timer,
			    (unsigned long)slot);
		tasklet_init(&slot->cover_tasklet, mmc_omap_cover_handler,
			     (unsigned long)slot);
		tasklet_schedule(&slot->cover_tasklet);
	}

	return 0;

err_remove_slot_name:
	if (slot->pdata->name != NULL)
		device_remove_file(&mmc->class_dev, &dev_attr_slot_name);
err_remove_host:
	mmc_remove_host(mmc);
	mmc_free_host(mmc);
	return r;
}
Example #8
0
static int s3c_sdi_probe(struct device *dev)
{
    struct platform_device* pdev = to_platform_device(dev);
    struct mmc_host *mmc;
    struct s3c_sdi_host *host;

    int ret;
#ifdef CONFIG_S3C2443_EVT1
    /* EXTINT0 S3C2443 EVT1 workaround */
    u32 tmp;
#endif

    mmc = mmc_alloc_host(sizeof(struct s3c_sdi_host), &pdev->dev);
    if (!mmc) {
        ret = -ENOMEM;
        goto probe_out;
    }

    host = mmc_priv(mmc);
    spin_lock_init(&host->complete_lock);
    host->complete_what 	= COMPLETION_NONE;
    host->mmc 		= mmc;
#if CONFIG_MACH_TOMTOMGO
    host->irq_cd		= IO_GetInterruptNumber(CD_SD);
    mmc->removable		= 1;
#elif CONFIG_ARCH_S3C2460
    host->irq_cd		= IRQ_EINT3;
#elif defined(CONFIG_MACH_SMDK2443)
    host->irq_cd		= IRQ_EINT1;
#elif defined(CONFIG_ARCH_MDIRAC3)
    host->subchannel	=S3C_DMA3_SDMMC;
//	host->irq_cd		= IRQ_EINT7;
#elif defined CONFIG_ARCH_S3C2412
    host->irq_cd		= IRQ_EINT18;
#endif
    host->dma		= S3C_SDI_DMA;

    host->mem = platform_get_resource(pdev, IORESOURCE_MEM ,0);
    if (!host->mem) {
        printk("failed to get io memory region resource.\n");
        ret = -ENOENT;
        goto probe_free_host;
    }

    host->mem = request_mem_region(host->mem->start,
                                   RESSIZE(host->mem), pdev->name);

    if (!host->mem) {
        printk("failed to request io memory region.\n");
        ret = -ENOENT;
        goto probe_free_host;
    }

    /* if there is an error here, check your SoC dependent code.
     * You must have iotable that contains SDI in it.
     * by scsuh.
     */
    host->base = S3C24XX_VA_SDI;
    host->irq = platform_get_irq(pdev, 0);

    if (host->irq == 0) {
        printk("failed to get interrupt resouce.\n");
        ret = -EINVAL;
        goto release_memory;
    }

    if (request_irq(host->irq, s3c_sdi_irq, 0, DRIVER_NAME, host)) {
        printk("failed to request sdi interrupt.\n");
        ret = -ENOENT;
        goto release_memory;
    }

#if defined(CONFIG_MACH_SMDK2443)
#ifdef CONFIG_S3C2443_EVT1
    /* EXTINT0 S3C2443 EVT1 workaround */
    tmp = __raw_readl(S3C_EXTINT0);
    s3c_swap_4bit(tmp);
    __raw_writel(tmp | (1<<7), S3C_EXTINT0);
#endif
    s3c_gpio_cfgpin(S3C_GPF1, S3C_GPF1_EINT1);
#elif defined(CONFIG_ARCH_S3C2460)
    s3c_gpio_cfgpin(S3C_GPJ3, S3C_GPJ3_EXT_INT3);
#elif defined CONFIG_ARCH_S3C2412
    s3c_gpio_cfgpin(S3C_GPG10, S3C_GPG10_EINT18);
#elif defined CONFIG_ARCH_MDIRAC3
    ;
#endif

#ifdef CONFIG_ARCH_MDIRAC3
    if (s3c_dma_request(host->dma,host->subchannel, &s3c_sdi_dma_client,NULL)) {
        printk("unable to get DMA channel.\n" );
        ret = -EBUSY;
        goto probe_free_irq_cd;
    }
#else
    INIT_WORK( &host->irq_cd_wq, s3c24xx_irq_cd_handler, mmc );
    set_irq_type(host->irq_cd, IRQT_BOTHEDGE);

    if (host->irq_cd > 0) {
        if (request_irq(host->irq_cd, s3c_sdi_irq_cd, SA_INTERRUPT, DRIVER_NAME, host)) {
            printk("failed to request card detect interrupt.\n" );
            ret = -ENOENT;
            goto probe_free_irq;
        }
    }
    if (s3c_dma_request(S3C_SDI_DMA, &s3c_sdi_dma_client, NULL)) {
        printk("unable to get DMA channel.\n" );
        ret = -EBUSY;
        goto probe_free_irq_cd;
    }

#endif
    host->clk = clk_get(&pdev->dev, "sdi");
    if (IS_ERR(host->clk)) {
        printk("failed to find clock source.\n");
        ret = PTR_ERR(host->clk);
        host->clk = NULL;
        goto probe_free_host;
    }

    if ((ret = clk_enable(host->clk))) {
        printk("failed to enable clock source.\n");
        goto clk_free;
    }

    mmc->ops = &s3c_sdi_ops;
    mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34;
    mmc->f_min = clk_get_rate(host->clk) / 512;
    /* you must make sure that our sdmmc block can support
     * up to 25MHz. by scsuh
     */
    mmc->f_max = 25 * MHZ;
    mmc->caps = MMC_CAP_4_BIT_DATA;

    /*
     * Since we only have a 16-bit data length register, we must
     * ensure that we don't exceed 2^16-1 bytes in a single request.
     */
    mmc->max_req_size = 65535;

    /*
     * Set the maximum segment size.  Since we aren't doing DMA
     * (yet) we are only limited by the data length register.
     */

    mmc->max_seg_size = mmc->max_req_size;

    /*
     * Both block size and block count use 12 bit registers.
     */
    mmc->max_blk_size = 4095;
    mmc->max_blk_count = 4095;

    printk(KERN_INFO PFX "probe: mapped sdi_base=%p irq=%u irq_cd=%u dma=%u.\n",
           host->base, host->irq, host->irq_cd, host->dma);
    platform_set_drvdata(pdev, mmc);

    init_timer(&host->timer);
    host->timer.data = (unsigned long)host;
    host->timer.function = s3c_sdi_check_status;
    host->timer.expires = jiffies + HZ;
    host->ena_2410_workaround=(IO_GetCpuType( ) == GOCPU_S3C2410);

    if ((ret = mmc_add_host(mmc))) {
        printk(KERN_INFO PFX "failed to add mmc host.\n");
        goto free_dmabuf;
    }

    /* Do CPUFREQ registration. */
#if defined CONFIG_CPU_FREQ && defined CONFIG_S3C24XX_DFS_CPUFREQ
    host->freq_transition.notifier_call = s3c24xxsdi_freq_transition;
    host->freq_transition.priority = CPUFREQ_ORDER_S3C24XX_SDCARD_PRIO;
    host->freq_policy.notifier_call = s3c24xxsdi_freq_policy;
    cpufreq_register_notifier(&host->freq_transition, CPUFREQ_TRANSITION_NOTIFIER);
    cpufreq_register_notifier(&host->freq_policy, CPUFREQ_POLICY_NOTIFIER);
#endif

    printk(KERN_INFO PFX "initialization done.\n");
    return 0;

free_dmabuf:
    clk_disable(host->clk);

clk_free:
    clk_put(host->clk);

probe_free_irq_cd:
#ifndef CONFIG_ARCH_MDIRAC3
    free_irq(host->irq_cd, host);
#endif
probe_free_irq:
    free_irq(host->irq, host);

release_memory:
    release_mem_region(host->mem->start, RESSIZE(host->mem));

probe_free_host:
    mmc_free_host(mmc);

probe_out:
    return ret;
}
Example #9
0
static int mxs_mmc_probe(struct platform_device *pdev)
{
	const struct of_device_id *of_id =
			of_match_device(mxs_mmc_dt_ids, &pdev->dev);
	struct device_node *np = pdev->dev.of_node;
	struct mxs_mmc_host *host;
	struct mmc_host *mmc;
	struct resource *iores;
	int ret = 0, irq_err;
	struct regulator *reg_vmmc;
	struct mxs_ssp *ssp;

	irq_err = platform_get_irq(pdev, 0);
	if (irq_err < 0)
		return irq_err;

	mmc = mmc_alloc_host(sizeof(struct mxs_mmc_host), &pdev->dev);
	if (!mmc)
		return -ENOMEM;

	host = mmc_priv(mmc);
	ssp = &host->ssp;
	ssp->dev = &pdev->dev;
	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	ssp->base = devm_ioremap_resource(&pdev->dev, iores);
	if (IS_ERR(ssp->base)) {
		ret = PTR_ERR(ssp->base);
		goto out_mmc_free;
	}

	ssp->devid = (enum mxs_ssp_id) of_id->data;

	host->mmc = mmc;
	host->sdio_irq_en = 0;

	reg_vmmc = devm_regulator_get(&pdev->dev, "vmmc");
	if (!IS_ERR(reg_vmmc)) {
		ret = regulator_enable(reg_vmmc);
		if (ret) {
			dev_err(&pdev->dev,
				"Failed to enable vmmc regulator: %d\n", ret);
			goto out_mmc_free;
		}
	}

	ssp->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(ssp->clk)) {
		ret = PTR_ERR(ssp->clk);
		goto out_mmc_free;
	}
	ret = clk_prepare_enable(ssp->clk);
	if (ret)
		goto out_mmc_free;

	ret = mxs_mmc_reset(host);
	if (ret) {
		dev_err(&pdev->dev, "Failed to reset mmc: %d\n", ret);
		goto out_clk_disable;
	}

	ssp->dmach = dma_request_slave_channel(&pdev->dev, "rx-tx");
	if (!ssp->dmach) {
		dev_err(mmc_dev(host->mmc),
			"%s: failed to request dma\n", __func__);
		ret = -ENODEV;
		goto out_clk_disable;
	}

	/* set mmc core parameters */
	mmc->ops = &mxs_mmc_ops;
	mmc->caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED |
		    MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL;

	host->broken_cd = of_property_read_bool(np, "broken-cd");

	mmc->f_min = 400000;
	mmc->f_max = 288000000;

	ret = mmc_of_parse(mmc);
	if (ret)
		goto out_clk_disable;

	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;

	mmc->max_segs = 52;
	mmc->max_blk_size = 1 << 0xf;
	mmc->max_blk_count = (ssp_is_old(ssp)) ? 0xff : 0xffffff;
	mmc->max_req_size = (ssp_is_old(ssp)) ? 0xffff : 0xffffffff;
	mmc->max_seg_size = dma_get_max_seg_size(ssp->dmach->device->dev);

	platform_set_drvdata(pdev, mmc);

	ret = devm_request_irq(&pdev->dev, irq_err, mxs_mmc_irq_handler, 0,
			       dev_name(&pdev->dev), host);
	if (ret)
		goto out_free_dma;

	spin_lock_init(&host->lock);

	ret = mmc_add_host(mmc);
	if (ret)
		goto out_free_dma;

	dev_info(mmc_dev(host->mmc), "initialized\n");

	return 0;

out_free_dma:
	dma_release_channel(ssp->dmach);
out_clk_disable:
	clk_disable_unprepare(ssp->clk);
out_mmc_free:
	mmc_free_host(mmc);
	return ret;
}