2 * SDHCI support for SiRF primaII and marco SoCs
4 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
6 * Licensed under GPLv2 or later.
9 #include <linux/delay.h>
10 #include <linux/device.h>
11 #include <linux/mmc/host.h>
12 #include <linux/module.h>
14 #include <linux/of_gpio.h>
15 #include <linux/mmc/slot-gpio.h>
16 #include <linux/pinctrl/consumer.h>
17 #include "sdhci-pltfm.h"
19 struct sdhci_sirf_priv
{
24 static unsigned int sdhci_sirf_get_max_clk(struct sdhci_host
*host
)
26 struct sdhci_pltfm_host
*pltfm_host
= sdhci_priv(host
);
27 struct sdhci_sirf_priv
*priv
= pltfm_host
->priv
;
28 return clk_get_rate(priv
->clk
);
31 static struct sdhci_ops sdhci_sirf_ops
= {
32 .get_max_clock
= sdhci_sirf_get_max_clk
,
35 static struct sdhci_pltfm_data sdhci_sirf_pdata
= {
36 .ops
= &sdhci_sirf_ops
,
37 .quirks
= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL
|
38 SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK
|
39 SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN
|
40 SDHCI_QUIRK_INVERTED_WRITE_PROTECT
|
41 SDHCI_QUIRK_DELAY_AFTER_POWER
,
44 static int sdhci_sirf_probe(struct platform_device
*pdev
)
46 struct sdhci_host
*host
;
47 struct sdhci_pltfm_host
*pltfm_host
;
48 struct sdhci_sirf_priv
*priv
;
49 struct pinctrl
*pinctrl
;
52 pinctrl
= devm_pinctrl_get_select_default(&pdev
->dev
);
53 if (IS_ERR(pinctrl
)) {
54 dev_err(&pdev
->dev
, "unable to get pinmux");
55 return PTR_ERR(pinctrl
);
58 priv
= devm_kzalloc(&pdev
->dev
, sizeof(struct sdhci_sirf_priv
),
61 dev_err(&pdev
->dev
, "unable to allocate private data");
65 priv
->clk
= devm_clk_get(&pdev
->dev
, NULL
);
66 if (IS_ERR(priv
->clk
)) {
67 dev_err(&pdev
->dev
, "unable to get clock");
68 return PTR_ERR(priv
->clk
);
71 if (pdev
->dev
.of_node
) {
72 priv
->gpio_cd
= of_get_named_gpio(pdev
->dev
.of_node
,
75 priv
->gpio_cd
= -EINVAL
;
78 host
= sdhci_pltfm_init(pdev
, &sdhci_sirf_pdata
);
81 goto err_sdhci_pltfm_init
;
84 pltfm_host
= sdhci_priv(host
);
85 pltfm_host
->priv
= priv
;
87 sdhci_get_of_property(pdev
);
89 clk_prepare_enable(priv
->clk
);
91 ret
= sdhci_add_host(host
);
96 * We must request the IRQ after sdhci_add_host(), as the tasklet only
97 * gets setup in sdhci_add_host() and we oops.
99 if (gpio_is_valid(priv
->gpio_cd
)) {
100 ret
= mmc_gpio_request_cd(host
->mmc
, priv
->gpio_cd
);
102 dev_err(&pdev
->dev
, "card detect irq request failed: %d\n",
111 sdhci_remove_host(host
, 0);
113 clk_disable_unprepare(priv
->clk
);
114 sdhci_pltfm_free(pdev
);
115 err_sdhci_pltfm_init
:
119 static int sdhci_sirf_remove(struct platform_device
*pdev
)
121 struct sdhci_host
*host
= platform_get_drvdata(pdev
);
122 struct sdhci_pltfm_host
*pltfm_host
= sdhci_priv(host
);
123 struct sdhci_sirf_priv
*priv
= pltfm_host
->priv
;
125 sdhci_pltfm_unregister(pdev
);
127 if (gpio_is_valid(priv
->gpio_cd
))
128 mmc_gpio_free_cd(host
->mmc
);
130 clk_disable_unprepare(priv
->clk
);
134 #ifdef CONFIG_PM_SLEEP
135 static int sdhci_sirf_suspend(struct device
*dev
)
137 struct sdhci_host
*host
= dev_get_drvdata(dev
);
138 struct sdhci_pltfm_host
*pltfm_host
= sdhci_priv(host
);
139 struct sdhci_sirf_priv
*priv
= pltfm_host
->priv
;
142 ret
= sdhci_suspend_host(host
);
146 clk_disable(priv
->clk
);
151 static int sdhci_sirf_resume(struct device
*dev
)
153 struct sdhci_host
*host
= dev_get_drvdata(dev
);
154 struct sdhci_pltfm_host
*pltfm_host
= sdhci_priv(host
);
155 struct sdhci_sirf_priv
*priv
= pltfm_host
->priv
;
158 ret
= clk_enable(priv
->clk
);
160 dev_dbg(dev
, "Resume: Error enabling clock\n");
164 return sdhci_resume_host(host
);
167 static SIMPLE_DEV_PM_OPS(sdhci_sirf_pm_ops
, sdhci_sirf_suspend
, sdhci_sirf_resume
);
170 static const struct of_device_id sdhci_sirf_of_match
[] = {
171 { .compatible
= "sirf,prima2-sdhc" },
174 MODULE_DEVICE_TABLE(of
, sdhci_sirf_of_match
);
176 static struct platform_driver sdhci_sirf_driver
= {
178 .name
= "sdhci-sirf",
179 .owner
= THIS_MODULE
,
180 .of_match_table
= sdhci_sirf_of_match
,
181 #ifdef CONFIG_PM_SLEEP
182 .pm
= &sdhci_sirf_pm_ops
,
185 .probe
= sdhci_sirf_probe
,
186 .remove
= sdhci_sirf_remove
,
189 module_platform_driver(sdhci_sirf_driver
);
191 MODULE_DESCRIPTION("SDHCI driver for SiRFprimaII/SiRFmarco");
192 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
193 MODULE_LICENSE("GPL v2");