--- zzzz-none-000/linux-3.10.107/drivers/mmc/host/dw_mmc-pltfm.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/mmc/host/dw_mmc-pltfm.c 2021-02-04 17:41:59.000000000 +0000 @@ -21,24 +21,34 @@ #include #include #include +#include #include "dw_mmc.h" +#include "dw_mmc-pltfm.h" + +static void dw_mci_pltfm_prepare_command(struct dw_mci *host, u32 *cmdr) +{ + *cmdr |= SDMMC_CMD_USE_HOLD_REG; +} + +static const struct dw_mci_drv_data socfpga_drv_data = { + .prepare_command = dw_mci_pltfm_prepare_command, +}; + +static const struct dw_mci_drv_data pistachio_drv_data = { + .prepare_command = dw_mci_pltfm_prepare_command, +}; int dw_mci_pltfm_register(struct platform_device *pdev, - const struct dw_mci_drv_data *drv_data) + const struct dw_mci_drv_data *drv_data) { struct dw_mci *host; struct resource *regs; - int ret; host = devm_kzalloc(&pdev->dev, sizeof(struct dw_mci), GFP_KERNEL); if (!host) return -ENOMEM; - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!regs) - return -ENXIO; - host->irq = platform_get_irq(pdev, 0); if (host->irq < 0) return host->irq; @@ -47,67 +57,37 @@ host->dev = &pdev->dev; host->irq_flags = 0; host->pdata = pdev->dev.platform_data; + + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); host->regs = devm_ioremap_resource(&pdev->dev, regs); if (IS_ERR(host->regs)) return PTR_ERR(host->regs); - if (drv_data && drv_data->init) { - ret = drv_data->init(host); - if (ret) - return ret; - } + /* Get registers' physical base address */ + host->phy_regs = regs->start; platform_set_drvdata(pdev, host); - ret = dw_mci_probe(host); - return ret; + return dw_mci_probe(host); } EXPORT_SYMBOL_GPL(dw_mci_pltfm_register); -static int dw_mci_pltfm_probe(struct platform_device *pdev) -{ - return dw_mci_pltfm_register(pdev, NULL); -} - -static int dw_mci_pltfm_remove(struct platform_device *pdev) -{ - struct dw_mci *host = platform_get_drvdata(pdev); - - platform_set_drvdata(pdev, NULL); - dw_mci_remove(host); - return 0; -} -EXPORT_SYMBOL_GPL(dw_mci_pltfm_remove); - #ifdef CONFIG_PM_SLEEP /* * TODO: we should probably disable the clock to the card in the suspend path. */ static int dw_mci_pltfm_suspend(struct device *dev) { - int ret; struct dw_mci *host = dev_get_drvdata(dev); - ret = dw_mci_suspend(host); - if (ret) - return ret; - - return 0; + return dw_mci_suspend(host); } static int dw_mci_pltfm_resume(struct device *dev) { - int ret; struct dw_mci *host = dev_get_drvdata(dev); - ret = dw_mci_resume(host); - if (ret) - return ret; - - return 0; + return dw_mci_resume(host); } -#else -#define dw_mci_pltfm_suspend NULL -#define dw_mci_pltfm_resume NULL #endif /* CONFIG_PM_SLEEP */ SIMPLE_DEV_PM_OPS(dw_mci_pltfm_pmops, dw_mci_pltfm_suspend, dw_mci_pltfm_resume); @@ -115,16 +95,42 @@ static const struct of_device_id dw_mci_pltfm_match[] = { { .compatible = "snps,dw-mshc", }, + { .compatible = "altr,socfpga-dw-mshc", + .data = &socfpga_drv_data }, + { .compatible = "img,pistachio-dw-mshc", + .data = &pistachio_drv_data }, {}, }; MODULE_DEVICE_TABLE(of, dw_mci_pltfm_match); +static int dw_mci_pltfm_probe(struct platform_device *pdev) +{ + const struct dw_mci_drv_data *drv_data = NULL; + const struct of_device_id *match; + + if (pdev->dev.of_node) { + match = of_match_node(dw_mci_pltfm_match, pdev->dev.of_node); + drv_data = match->data; + } + + return dw_mci_pltfm_register(pdev, drv_data); +} + +int dw_mci_pltfm_remove(struct platform_device *pdev) +{ + struct dw_mci *host = platform_get_drvdata(pdev); + + dw_mci_remove(host); + return 0; +} +EXPORT_SYMBOL_GPL(dw_mci_pltfm_remove); + static struct platform_driver dw_mci_pltfm_driver = { .probe = dw_mci_pltfm_probe, .remove = dw_mci_pltfm_remove, .driver = { .name = "dw_mmc", - .of_match_table = of_match_ptr(dw_mci_pltfm_match), + .of_match_table = dw_mci_pltfm_match, .pm = &dw_mci_pltfm_pmops, }, };