in host/s3cmci.c [1508:1689]
static int s3cmci_probe(struct platform_device *pdev)
{
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;
if (pdev->dev.of_node)
ret = s3cmci_probe_dt(host);
else
ret = s3cmci_probe_pdata(host);
if (ret)
goto probe_free_host;
host->pdata = pdev->dev.platform_data;
spin_lock_init(&host->complete_lock);
tasklet_setup(&host->pio_tasklet, pio_tasklet);
if (host->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->complete_what = COMPLETION_NONE;
host->pio_active = XFER_NONE;
host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!host->mem) {
dev_err(&pdev->dev,
"failed to get io memory region resource.\n");
ret = -ENOENT;
goto probe_free_host;
}
host->mem = request_mem_region(host->mem->start,
resource_size(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, resource_size(host->mem));
if (!host->base) {
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) {
ret = -EINVAL;
goto probe_iounmap;
}
if (request_irq(host->irq, s3cmci_irq, IRQF_NO_AUTOEN, DRIVER_NAME, host)) {
dev_err(&pdev->dev, "failed to request mci interrupt.\n");
ret = -ENOENT;
goto probe_iounmap;
}
host->irq_state = false;
/* Depending on the dma state, get a DMA channel to use. */
if (s3cmci_host_usedma(host)) {
host->dma = dma_request_chan(&pdev->dev, "rx-tx");
ret = PTR_ERR_OR_ZERO(host->dma);
if (ret) {
dev_err(&pdev->dev, "cannot get DMA channel.\n");
goto probe_free_irq;
}
}
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_dma;
}
ret = clk_prepare_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;
#ifdef CONFIG_MMC_S3C_HW_SDIO_IRQ
mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
#else
mmc->caps = MMC_CAP_4_BIT_DATA;
#endif
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_segs = 128;
dbg(host, dbg_debug,
"probe: mode:%s mapped mci_base:%p irq:%u irq_cd:%u dma:%p.\n",
(host->is2440?"2440":""),
host->base, host->irq, host->irq_cd, host->dma);
ret = s3cmci_cpufreq_register(host);
if (ret) {
dev_err(&pdev->dev, "failed to register cpufreq\n");
goto free_dmabuf;
}
ret = mmc_add_host(mmc);
if (ret) {
dev_err(&pdev->dev, "failed to add mmc host.\n");
goto free_cpufreq;
}
s3cmci_debugfs_attach(host);
platform_set_drvdata(pdev, mmc);
dev_info(&pdev->dev, "%s - using %s, %s SDIO IRQ\n", mmc_hostname(mmc),
s3cmci_host_usedma(host) ? "dma" : "pio",
mmc->caps & MMC_CAP_SDIO_IRQ ? "hw" : "sw");
return 0;
free_cpufreq:
s3cmci_cpufreq_deregister(host);
free_dmabuf:
clk_disable_unprepare(host->clk);
clk_free:
clk_put(host->clk);
probe_free_dma:
if (s3cmci_host_usedma(host))
dma_release_channel(host->dma);
probe_free_irq:
free_irq(host->irq, host);
probe_iounmap:
iounmap(host->base);
probe_free_mem_region:
release_mem_region(host->mem->start, resource_size(host->mem));
probe_free_host:
mmc_free_host(mmc);
probe_out:
return ret;
}