static int sdhci_pxav3_probe(struct platform_device *pdev) { struct sdhci_pltfm_host *pltfm_host; struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data; struct device *dev = &pdev->dev; struct device_node *np = pdev->dev.of_node; struct sdhci_host *host = NULL; struct sdhci_pxa *pxa = NULL; const struct of_device_id *match; int ret; host = sdhci_pltfm_init(pdev, &sdhci_pxav3_pdata, sizeof(*pxa)); if (IS_ERR(host)) return PTR_ERR(host); pltfm_host = sdhci_priv(host); pxa = sdhci_pltfm_priv(pltfm_host); pxa->clk_io = devm_clk_get(dev, "io"); if (IS_ERR(pxa->clk_io)) pxa->clk_io = devm_clk_get(dev, NULL); if (IS_ERR(pxa->clk_io)) { dev_err(dev, "failed to get io clock\n"); ret = PTR_ERR(pxa->clk_io); goto err_clk_get; } pltfm_host->clk = pxa->clk_io; clk_prepare_enable(pxa->clk_io); pxa->clk_core = devm_clk_get(dev, "core"); if (!IS_ERR(pxa->clk_core)) clk_prepare_enable(pxa->clk_core); /* enable 1/8V DDR capable */ host->mmc->caps |= MMC_CAP_1_8V_DDR; if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) { ret = armada_38x_quirks(pdev, host); if (ret < 0) goto err_mbus_win; ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info()); if (ret < 0) goto err_mbus_win; } match = of_match_device(of_match_ptr(sdhci_pxav3_of_match), &pdev->dev); if (match) { ret = mmc_of_parse(host->mmc); if (ret) goto err_of_parse; sdhci_get_of_property(pdev); pdata = pxav3_get_mmc_pdata(dev); pdev->dev.platform_data = pdata; } else if (pdata) { /* on-chip device */ if (pdata->flags & PXA_FLAG_CARD_PERMANENT) host->mmc->caps |= MMC_CAP_NONREMOVABLE; /* If slot design supports 8 bit data, indicate this to MMC. */ if (pdata->flags & PXA_FLAG_SD_8_BIT_CAPABLE_SLOT) host->mmc->caps |= MMC_CAP_8_BIT_DATA; if (pdata->quirks) host->quirks |= pdata->quirks; if (pdata->quirks2) host->quirks2 |= pdata->quirks2; if (pdata->host_caps) host->mmc->caps |= pdata->host_caps; if (pdata->host_caps2) host->mmc->caps2 |= pdata->host_caps2; if (pdata->pm_caps) host->mmc->pm_caps |= pdata->pm_caps; if (gpio_is_valid(pdata->ext_cd_gpio)) { ret = mmc_gpio_request_cd(host->mmc, pdata->ext_cd_gpio, 0); if (ret) { dev_err(mmc_dev(host->mmc), "failed to allocate card detect gpio\n"); goto err_cd_req; } } } pm_runtime_get_noresume(&pdev->dev); pm_runtime_set_active(&pdev->dev); pm_runtime_set_autosuspend_delay(&pdev->dev, PXAV3_RPM_DELAY_MS); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_enable(&pdev->dev); pm_suspend_ignore_children(&pdev->dev, 1); ret = sdhci_add_host(host); if (ret) { dev_err(&pdev->dev, "failed to add host\n"); goto err_add_host; } platform_set_drvdata(pdev, host); if (host->mmc->pm_caps & MMC_PM_WAKE_SDIO_IRQ) device_init_wakeup(&pdev->dev, 1); pm_runtime_put_autosuspend(&pdev->dev); return 0; err_add_host: pm_runtime_disable(&pdev->dev); pm_runtime_put_noidle(&pdev->dev); err_of_parse: err_cd_req: err_mbus_win: clk_disable_unprepare(pxa->clk_io); clk_disable_unprepare(pxa->clk_core); err_clk_get: sdhci_pltfm_free(pdev); return ret; }
static int __devinit sdhci_pxav3_probe(struct platform_device *pdev) { struct sdhci_pltfm_host *pltfm_host; struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data; struct device *dev = &pdev->dev; struct sdhci_host *host = NULL; struct sdhci_pxa *pxa = NULL; const struct of_device_id *match; int ret; struct clk *clk; pxa = kzalloc(sizeof(struct sdhci_pxa), GFP_KERNEL); if (!pxa) return -ENOMEM; host = sdhci_pltfm_init(pdev, NULL); if (IS_ERR(host)) { kfree(pxa); return PTR_ERR(host); } pltfm_host = sdhci_priv(host); pltfm_host->priv = pxa; clk = clk_get(dev, NULL); if (IS_ERR(clk)) { dev_err(dev, "failed to get io clock\n"); ret = PTR_ERR(clk); goto err_clk_get; } pltfm_host->clk = clk; clk_prepare_enable(clk); host->quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | SDHCI_QUIRK_32BIT_ADMA_SIZE | SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN; /* enable 1/8V DDR capable */ host->mmc->caps |= MMC_CAP_1_8V_DDR; match = of_match_device(of_match_ptr(sdhci_pxav3_of_match), &pdev->dev); if (match) pdata = pxav3_get_mmc_pdata(dev); if (pdata) { if (pdata->flags & PXA_FLAG_CARD_PERMANENT) { /* on-chip device */ host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION; host->mmc->caps |= MMC_CAP_NONREMOVABLE; } /* If slot design supports 8 bit data, indicate this to MMC. */ if (pdata->flags & PXA_FLAG_SD_8_BIT_CAPABLE_SLOT) host->mmc->caps |= MMC_CAP_8_BIT_DATA; if (pdata->quirks) host->quirks |= pdata->quirks; if (pdata->quirks2) host->quirks2 |= pdata->quirks2; if (pdata->host_caps) host->mmc->caps |= pdata->host_caps; if (pdata->host_caps2) host->mmc->caps2 |= pdata->host_caps2; if (pdata->pm_caps) host->mmc->pm_caps |= pdata->pm_caps; if (gpio_is_valid(pdata->ext_cd_gpio)) { ret = mmc_gpio_request_cd(host->mmc, pdata->ext_cd_gpio); if (ret) { dev_err(mmc_dev(host->mmc), "failed to allocate card detect gpio\n"); goto err_cd_req; } } } host->ops = &pxav3_sdhci_ops; sdhci_get_of_property(pdev); ret = sdhci_add_host(host); if (ret) { dev_err(&pdev->dev, "failed to add host\n"); goto err_add_host; } platform_set_drvdata(pdev, host); return 0; err_add_host: clk_disable_unprepare(clk); clk_put(clk); mmc_gpio_free_cd(host->mmc); err_cd_req: err_clk_get: sdhci_pltfm_free(pdev); kfree(pxa); return ret; }
static int sdhci_pxav3_probe(struct platform_device *pdev) { struct sdhci_pltfm_host *pltfm_host; struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data; struct device *dev = &pdev->dev; struct sdhci_host *host = NULL; struct sdhci_pxa *pxa = NULL; const struct of_device_id *match; int ret; struct clk *clk; pxa = kzalloc(sizeof(struct sdhci_pxa), GFP_KERNEL); if (!pxa) return -ENOMEM; host = sdhci_pltfm_init(pdev, &sdhci_pxav3_pdata); if (IS_ERR(host)) { kfree(pxa); return PTR_ERR(host); } pltfm_host = sdhci_priv(host); pltfm_host->priv = pxa; clk = clk_get(dev, NULL); if (IS_ERR(clk)) { dev_err(dev, "failed to get io clock\n"); ret = PTR_ERR(clk); goto err_clk_get; } pltfm_host->clk = clk; clk_prepare_enable(clk); /* enable 1/8V DDR capable */ host->mmc->caps |= MMC_CAP_1_8V_DDR; match = of_match_device(of_match_ptr(sdhci_pxav3_of_match), &pdev->dev); if (match) { mmc_of_parse(host->mmc); sdhci_get_of_property(pdev); pdata = pxav3_get_mmc_pdata(dev); } else if (pdata) { /* on-chip device */ if (pdata->flags & PXA_FLAG_CARD_PERMANENT) host->mmc->caps |= MMC_CAP_NONREMOVABLE; /* If slot design supports 8 bit data, indicate this to MMC. */ if (pdata->flags & PXA_FLAG_SD_8_BIT_CAPABLE_SLOT) host->mmc->caps |= MMC_CAP_8_BIT_DATA; if (pdata->quirks) host->quirks |= pdata->quirks; if (pdata->quirks2) host->quirks2 |= pdata->quirks2; if (pdata->host_caps) host->mmc->caps |= pdata->host_caps; if (pdata->host_caps2) host->mmc->caps2 |= pdata->host_caps2; if (pdata->pm_caps) host->mmc->pm_caps |= pdata->pm_caps; if (gpio_is_valid(pdata->ext_cd_gpio)) { ret = mmc_gpio_request_cd(host->mmc, pdata->ext_cd_gpio); if (ret) { dev_err(mmc_dev(host->mmc), "failed to allocate card detect gpio\n"); goto err_cd_req; } } } pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); pm_runtime_set_autosuspend_delay(&pdev->dev, PXAV3_RPM_DELAY_MS); pm_runtime_use_autosuspend(&pdev->dev); pm_suspend_ignore_children(&pdev->dev, 1); pm_runtime_get_noresume(&pdev->dev); ret = sdhci_add_host(host); if (ret) { dev_err(&pdev->dev, "failed to add host\n"); pm_runtime_forbid(&pdev->dev); pm_runtime_disable(&pdev->dev); goto err_add_host; } platform_set_drvdata(pdev, host); if (host->mmc->pm_caps & MMC_PM_KEEP_POWER) { device_init_wakeup(&pdev->dev, 1); host->mmc->pm_flags |= MMC_PM_WAKE_SDIO_IRQ; } else { device_init_wakeup(&pdev->dev, 0); } pm_runtime_put_autosuspend(&pdev->dev); return 0; err_add_host: clk_disable_unprepare(clk); clk_put(clk); err_cd_req: err_clk_get: sdhci_pltfm_free(pdev); kfree(pxa); return ret; }
static int __devinit sdhci_pxav3_probe(struct platform_device *pdev) { struct sdhci_pltfm_host *pltfm_host; struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data; struct device *dev = &pdev->dev; struct sdhci_host *host = NULL; struct sdhci_pxa *pxa = NULL; const struct of_device_id *match; int ret; struct clk *clk; int qos_class = PM_QOS_CPUIDLE_BLOCK; pxa = kzalloc(sizeof(struct sdhci_pxa), GFP_KERNEL); if (!pxa) return -ENOMEM; host = sdhci_pltfm_init(pdev, NULL); if (IS_ERR(host)) { kfree(pxa); return PTR_ERR(host); } pltfm_host = sdhci_priv(host); pltfm_host->priv = pxa; clk = clk_get(dev, "PXA-SDHCLK"); if (IS_ERR(clk)) { dev_err(dev, "failed to get io clock\n"); ret = PTR_ERR(clk); goto err_clk_get; } pltfm_host->clk = clk; clk_prepare_enable(clk); host->quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | SDHCI_QUIRK_32BIT_ADMA_SIZE | SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN; match = of_match_device(of_match_ptr(sdhci_pxav3_of_match), &pdev->dev); if (match) pdata = pxav3_get_mmc_pdata(dev); if (pdata) { pdata->qos_idle.name = mmc_hostname(host->mmc); pm_qos_add_request(&pdata->qos_idle, qos_class, PM_QOS_CPUIDLE_BLOCK_DEFAULT_VALUE); /* If slot design supports 8 bit data, indicate this to MMC. */ if (pdata->flags & PXA_FLAG_SD_8_BIT_CAPABLE_SLOT) host->mmc->caps |= MMC_CAP_8_BIT_DATA; if (pdata->flags & PXA_FLAG_ENABLE_CLOCK_GATING) host->mmc->caps2 |= MMC_CAP2_BUS_AUTO_CLK_GATE; if (pdata->flags & PXA_FLAG_DISABLE_PROBE_CDSCAN) host->mmc->caps2 |= MMC_CAP2_DISABLE_PROBE_CDSCAN; if (pdata->quirks) host->quirks |= pdata->quirks; if (pdata->host_caps) host->mmc->caps |= pdata->host_caps; if (pdata->host_caps2) host->mmc->caps2 |= pdata->host_caps2; if (pdata->pm_caps) host->mmc->pm_caps |= pdata->pm_caps; if (pdata->cd_type != PXA_SDHCI_CD_HOST) host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION; if (pdata->cd_type == PXA_SDHCI_CD_GPIO && gpio_is_valid(pdata->ext_cd_gpio)) { ret = mmc_gpio_request_cd(host->mmc, pdata->ext_cd_gpio); if (ret) { dev_err(mmc_dev(host->mmc), "failed to allocate card detect gpio\n"); goto err_cd_req; } } else if (pdata->cd_type == PXA_SDHCI_CD_PERMANENT) { /* on-chip device */ host->mmc->caps |= MMC_CAP_NONREMOVABLE; } else if (pdata->cd_type == PXA_SDHCI_CD_NONE) host->mmc->caps |= MMC_CAP_NEEDS_POLL; } host->quirks2 = SDHCI_QUIRK2_NO_CURRENT_LIMIT | SDHCI_QUIRK2_PRESET_VALUE_BROKEN | SDHCI_QUIRK2_TIMEOUT_DIVIDE_4; host->ops = &pxav3_sdhci_ops; if (pdata && pdata->flags & PXA_FLAG_EN_PM_RUNTIME) { pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); pm_runtime_set_autosuspend_delay(&pdev->dev, PXAV3_RPM_DELAY_MS); pm_runtime_use_autosuspend(&pdev->dev); pm_suspend_ignore_children(&pdev->dev, 1); } #ifdef _MMC_SAFE_ACCESS_ mmc_is_available = 1; #endif ret = sdhci_add_host(host); if (ret) { dev_err(&pdev->dev, "failed to add host\n"); if (pdata && pdata->flags & PXA_FLAG_EN_PM_RUNTIME) { pm_runtime_forbid(&pdev->dev); pm_runtime_get_noresume(&pdev->dev); } goto err_add_host; } /* remove the caps that supported by the controller but not available * for certain platforms. */ if (pdata && pdata->host_caps_disable) host->mmc->caps &= ~(pdata->host_caps_disable); platform_set_drvdata(pdev, host); if (pdata && pdata->flags & PXA_FLAG_WAKEUP_HOST) { device_init_wakeup(&pdev->dev, 1); host->mmc->pm_flags |= MMC_PM_WAKE_SDIO_IRQ; } else device_init_wakeup(&pdev->dev, 0); #ifdef CONFIG_SD8XXX_RFKILL if (pdata && pdata->pmmc) *pdata->pmmc = host->mmc; #endif return 0; err_add_host: clk_disable_unprepare(clk); clk_put(clk); if (pdata) pm_qos_remove_request(&pdata->qos_idle); err_cd_req: mmc_gpio_free_cd(host->mmc); err_clk_get: sdhci_pltfm_free(pdev); kfree(pxa); return ret; }