1 // SPDX-License-Identifier: GPL-2.0
3 * Driver for Synopsys DesignWare Cores Mobile Storage Host Controller
5 * Copyright (C) 2018 Synaptics Incorporated
7 * Author: Jisheng Zhang <jszhang@kernel.org>
10 #include <linux/clk.h>
11 #include <linux/module.h>
14 #include "sdhci-pltfm.h"
20 static const struct sdhci_ops sdhci_dwcmshc_ops
= {
21 .set_clock
= sdhci_set_clock
,
22 .set_bus_width
= sdhci_set_bus_width
,
23 .set_uhs_signaling
= sdhci_set_uhs_signaling
,
24 .get_max_clock
= sdhci_pltfm_clk_get_max_clock
,
28 static const struct sdhci_pltfm_data sdhci_dwcmshc_pdata
= {
29 .ops
= &sdhci_dwcmshc_ops
,
30 .quirks
= SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN
,
33 static int dwcmshc_probe(struct platform_device
*pdev
)
35 struct sdhci_pltfm_host
*pltfm_host
;
36 struct sdhci_host
*host
;
37 struct dwcmshc_priv
*priv
;
40 host
= sdhci_pltfm_init(pdev
, &sdhci_dwcmshc_pdata
,
41 sizeof(struct dwcmshc_priv
));
45 pltfm_host
= sdhci_priv(host
);
46 priv
= sdhci_pltfm_priv(pltfm_host
);
48 pltfm_host
->clk
= devm_clk_get(&pdev
->dev
, "core");
49 if (IS_ERR(pltfm_host
->clk
)) {
50 err
= PTR_ERR(pltfm_host
->clk
);
51 dev_err(&pdev
->dev
, "failed to get core clk: %d\n", err
);
54 err
= clk_prepare_enable(pltfm_host
->clk
);
58 priv
->bus_clk
= devm_clk_get(&pdev
->dev
, "bus");
59 if (!IS_ERR(priv
->bus_clk
))
60 clk_prepare_enable(priv
->bus_clk
);
62 err
= mmc_of_parse(host
->mmc
);
66 sdhci_get_of_property(pdev
);
68 err
= sdhci_add_host(host
);
75 clk_disable_unprepare(pltfm_host
->clk
);
76 clk_disable_unprepare(priv
->bus_clk
);
78 sdhci_pltfm_free(pdev
);
82 static int dwcmshc_remove(struct platform_device
*pdev
)
84 struct sdhci_host
*host
= platform_get_drvdata(pdev
);
85 struct sdhci_pltfm_host
*pltfm_host
= sdhci_priv(host
);
86 struct dwcmshc_priv
*priv
= sdhci_pltfm_priv(pltfm_host
);
88 sdhci_remove_host(host
, 0);
90 clk_disable_unprepare(pltfm_host
->clk
);
91 clk_disable_unprepare(priv
->bus_clk
);
93 sdhci_pltfm_free(pdev
);
98 static const struct of_device_id sdhci_dwcmshc_dt_ids
[] = {
99 { .compatible
= "snps,dwcmshc-sdhci" },
102 MODULE_DEVICE_TABLE(of
, sdhci_dwcmshc_dt_ids
);
104 static struct platform_driver sdhci_dwcmshc_driver
= {
106 .name
= "sdhci-dwcmshc",
107 .of_match_table
= sdhci_dwcmshc_dt_ids
,
109 .probe
= dwcmshc_probe
,
110 .remove
= dwcmshc_remove
,
112 module_platform_driver(sdhci_dwcmshc_driver
);
114 MODULE_DESCRIPTION("SDHCI platform driver for Synopsys DWC MSHC");
115 MODULE_AUTHOR("Jisheng Zhang <jszhang@kernel.org>");
116 MODULE_LICENSE("GPL v2");