in host/pxamci.c [607:780]
static int pxamci_probe(struct platform_device *pdev)
{
struct mmc_host *mmc;
struct pxamci_host *host = NULL;
struct device *dev = &pdev->dev;
struct resource *r;
int ret, irq;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
mmc = mmc_alloc_host(sizeof(struct pxamci_host), dev);
if (!mmc) {
ret = -ENOMEM;
goto out;
}
mmc->ops = &pxamci_ops;
/*
* We can do SG-DMA, but we don't because we never know how much
* data we successfully wrote to the card.
*/
mmc->max_segs = NR_SG;
/*
* Our hardware DMA can handle a maximum of one page per SG entry.
*/
mmc->max_seg_size = PAGE_SIZE;
/*
* Block length register is only 10 bits before PXA27x.
*/
mmc->max_blk_size = cpu_is_pxa25x() ? 1023 : 2048;
/*
* Block count register is 16 bits.
*/
mmc->max_blk_count = 65535;
ret = pxamci_of_init(pdev, mmc);
if (ret)
return ret;
host = mmc_priv(mmc);
host->mmc = mmc;
host->pdata = pdev->dev.platform_data;
host->clkrt = CLKRT_OFF;
host->clk = devm_clk_get(dev, NULL);
if (IS_ERR(host->clk)) {
ret = PTR_ERR(host->clk);
host->clk = NULL;
goto out;
}
host->clkrate = clk_get_rate(host->clk);
/*
* Calculate minimum clock rate, rounding up.
*/
mmc->f_min = (host->clkrate + 63) / 64;
mmc->f_max = (mmc_has_26MHz()) ? 26000000 : host->clkrate;
ret = pxamci_init_ocr(host);
if (ret < 0)
return ret;
mmc->caps = 0;
host->cmdat = 0;
if (!cpu_is_pxa25x()) {
mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
host->cmdat |= CMDAT_SDIO_INT_EN;
if (mmc_has_26MHz())
mmc->caps |= MMC_CAP_MMC_HIGHSPEED |
MMC_CAP_SD_HIGHSPEED;
}
spin_lock_init(&host->lock);
host->res = r;
host->imask = MMC_I_MASK_ALL;
host->base = devm_ioremap_resource(dev, r);
if (IS_ERR(host->base)) {
ret = PTR_ERR(host->base);
goto out;
}
/*
* Ensure that the host controller is shut down, and setup
* with our defaults.
*/
pxamci_stop_clock(host);
writel(0, host->base + MMC_SPI);
writel(64, host->base + MMC_RESTO);
writel(host->imask, host->base + MMC_I_MASK);
ret = devm_request_irq(dev, irq, pxamci_irq, 0,
DRIVER_NAME, host);
if (ret)
goto out;
platform_set_drvdata(pdev, mmc);
host->dma_chan_rx = dma_request_chan(dev, "rx");
if (IS_ERR(host->dma_chan_rx)) {
dev_err(dev, "unable to request rx dma channel\n");
ret = PTR_ERR(host->dma_chan_rx);
host->dma_chan_rx = NULL;
goto out;
}
host->dma_chan_tx = dma_request_chan(dev, "tx");
if (IS_ERR(host->dma_chan_tx)) {
dev_err(dev, "unable to request tx dma channel\n");
ret = PTR_ERR(host->dma_chan_tx);
host->dma_chan_tx = NULL;
goto out;
}
if (host->pdata) {
host->detect_delay_ms = host->pdata->detect_delay_ms;
host->power = devm_gpiod_get_optional(dev, "power", GPIOD_OUT_LOW);
if (IS_ERR(host->power)) {
ret = PTR_ERR(host->power);
dev_err(dev, "Failed requesting gpio_power\n");
goto out;
}
/* FIXME: should we pass detection delay to debounce? */
ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0);
if (ret && ret != -ENOENT) {
dev_err(dev, "Failed requesting gpio_cd\n");
goto out;
}
if (!host->pdata->gpio_card_ro_invert)
mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
ret = mmc_gpiod_request_ro(mmc, "wp", 0, 0);
if (ret && ret != -ENOENT) {
dev_err(dev, "Failed requesting gpio_ro\n");
goto out;
}
if (!ret)
host->use_ro_gpio = true;
if (host->pdata->init)
host->pdata->init(dev, pxamci_detect_irq, mmc);
if (host->power && host->pdata->setpower)
dev_warn(dev, "gpio_power and setpower() both defined\n");
if (host->use_ro_gpio && host->pdata->get_ro)
dev_warn(dev, "gpio_ro and get_ro() both defined\n");
}
mmc_add_host(mmc);
return 0;
out:
if (host) {
if (host->dma_chan_rx)
dma_release_channel(host->dma_chan_rx);
if (host->dma_chan_tx)
dma_release_channel(host->dma_chan_tx);
}
if (mmc)
mmc_free_host(mmc);
return ret;
}