aboutsummaryrefslogtreecommitdiff
path: root/drivers/mmc/host/dw_mmc-pltfm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/dw_mmc-pltfm.c')
-rw-r--r--drivers/mmc/host/dw_mmc-pltfm.c89
1 files changed, 47 insertions, 42 deletions
diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
index 41c27b74b00..d4a47a9f558 100644
--- a/drivers/mmc/host/dw_mmc-pltfm.c
+++ b/drivers/mmc/host/dw_mmc-pltfm.c
@@ -23,22 +23,31 @@
#include <linux/of.h>
#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 rockchip_drv_data = {
+ .prepare_command = dw_mci_pltfm_prepare_command,
+};
+
+static const struct dw_mci_drv_data socfpga_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,63 +56,33 @@ int dw_mci_pltfm_register(struct platform_device *pdev,
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;
- }
-
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
@@ -115,16 +94,42 @@ EXPORT_SYMBOL_GPL(dw_mci_pltfm_pmops);
static const struct of_device_id dw_mci_pltfm_match[] = {
{ .compatible = "snps,dw-mshc", },
+ { .compatible = "rockchip,rk2928-dw-mshc",
+ .data = &rockchip_drv_data },
+ { .compatible = "altr,socfpga-dw-mshc",
+ .data = &socfpga_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,
},
};