diff options
author | Chris Ball <cjb@laptop.org> | 2012-09-19 04:29:12 -0400 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2012-09-19 04:29:12 -0400 |
commit | 8f63795c60ef5bc3dbfcbf19c1ac64ed79d23c62 (patch) | |
tree | 073d48dd496caf00a35ab7030458288081ed4735 | |
parent | 15e8a8e42966162c207bb97ed55c803bc437eeae (diff) |
mmc: sdhci-pxav3: dt: Support "cd-gpios" property
Tested on OLPC XO-4/MMP3, where the card detection pin for one of
the controllers is a sideband GPIO. The third cell in the cd-gpios
property controls whether the GPIO is active high/active low.
(Also, pass host_caps2 through from platdata to the mmc host.)
Acked-by: Haojian Zhuang <haojian.zhuang@gmail.com>
[kliu5@marvell.com: Compile fix]
Signed-off-by: Chris Ball <cjb@laptop.org>
-rw-r--r-- | drivers/mmc/host/sdhci-pxav3.c | 25 | ||||
-rw-r--r-- | include/linux/platform_data/pxa_sdhci.h | 1 |
2 files changed, 26 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index a553b180d340..c5ff124f8f60 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c | |||
@@ -24,12 +24,14 @@ | |||
24 | #include <linux/gpio.h> | 24 | #include <linux/gpio.h> |
25 | #include <linux/mmc/card.h> | 25 | #include <linux/mmc/card.h> |
26 | #include <linux/mmc/host.h> | 26 | #include <linux/mmc/host.h> |
27 | #include <linux/mmc/slot-gpio.h> | ||
27 | #include <linux/platform_data/pxa_sdhci.h> | 28 | #include <linux/platform_data/pxa_sdhci.h> |
28 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
29 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
30 | #include <linux/module.h> | 31 | #include <linux/module.h> |
31 | #include <linux/of.h> | 32 | #include <linux/of.h> |
32 | #include <linux/of_device.h> | 33 | #include <linux/of_device.h> |
34 | #include <linux/of_gpio.h> | ||
33 | 35 | ||
34 | #include "sdhci.h" | 36 | #include "sdhci.h" |
35 | #include "sdhci-pltfm.h" | 37 | #include "sdhci-pltfm.h" |
@@ -182,6 +184,7 @@ static struct sdhci_pxa_platdata *pxav3_get_mmc_pdata(struct device *dev) | |||
182 | struct device_node *np = dev->of_node; | 184 | struct device_node *np = dev->of_node; |
183 | u32 bus_width; | 185 | u32 bus_width; |
184 | u32 clk_delay_cycles; | 186 | u32 clk_delay_cycles; |
187 | enum of_gpio_flags gpio_flags; | ||
185 | 188 | ||
186 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | 189 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); |
187 | if (!pdata) | 190 | if (!pdata) |
@@ -198,6 +201,10 @@ static struct sdhci_pxa_platdata *pxav3_get_mmc_pdata(struct device *dev) | |||
198 | if (clk_delay_cycles > 0) | 201 | if (clk_delay_cycles > 0) |
199 | pdata->clk_delay_cycles = clk_delay_cycles; | 202 | pdata->clk_delay_cycles = clk_delay_cycles; |
200 | 203 | ||
204 | pdata->ext_cd_gpio = of_get_named_gpio_flags(np, "cd-gpios", 0, &gpio_flags); | ||
205 | if (gpio_flags != OF_GPIO_ACTIVE_LOW) | ||
206 | pdata->host_caps2 |= MMC_CAP2_CD_ACTIVE_HIGH; | ||
207 | |||
201 | return pdata; | 208 | return pdata; |
202 | } | 209 | } |
203 | #else | 210 | #else |
@@ -266,8 +273,19 @@ static int __devinit sdhci_pxav3_probe(struct platform_device *pdev) | |||
266 | host->quirks |= pdata->quirks; | 273 | host->quirks |= pdata->quirks; |
267 | if (pdata->host_caps) | 274 | if (pdata->host_caps) |
268 | host->mmc->caps |= pdata->host_caps; | 275 | host->mmc->caps |= pdata->host_caps; |
276 | if (pdata->host_caps2) | ||
277 | host->mmc->caps2 |= pdata->host_caps2; | ||
269 | if (pdata->pm_caps) | 278 | if (pdata->pm_caps) |
270 | host->mmc->pm_caps |= pdata->pm_caps; | 279 | host->mmc->pm_caps |= pdata->pm_caps; |
280 | |||
281 | if (gpio_is_valid(pdata->ext_cd_gpio)) { | ||
282 | ret = mmc_gpio_request_cd(host->mmc, pdata->ext_cd_gpio); | ||
283 | if (ret) { | ||
284 | dev_err(mmc_dev(host->mmc), | ||
285 | "failed to allocate card detect gpio\n"); | ||
286 | goto err_cd_req; | ||
287 | } | ||
288 | } | ||
271 | } | 289 | } |
272 | 290 | ||
273 | host->ops = &pxav3_sdhci_ops; | 291 | host->ops = &pxav3_sdhci_ops; |
@@ -285,6 +303,8 @@ static int __devinit sdhci_pxav3_probe(struct platform_device *pdev) | |||
285 | err_add_host: | 303 | err_add_host: |
286 | clk_disable_unprepare(clk); | 304 | clk_disable_unprepare(clk); |
287 | clk_put(clk); | 305 | clk_put(clk); |
306 | mmc_gpio_free_cd(host->mmc); | ||
307 | err_cd_req: | ||
288 | err_clk_get: | 308 | err_clk_get: |
289 | sdhci_pltfm_free(pdev); | 309 | sdhci_pltfm_free(pdev); |
290 | kfree(pxa); | 310 | kfree(pxa); |
@@ -296,11 +316,16 @@ static int __devexit sdhci_pxav3_remove(struct platform_device *pdev) | |||
296 | struct sdhci_host *host = platform_get_drvdata(pdev); | 316 | struct sdhci_host *host = platform_get_drvdata(pdev); |
297 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 317 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
298 | struct sdhci_pxa *pxa = pltfm_host->priv; | 318 | struct sdhci_pxa *pxa = pltfm_host->priv; |
319 | struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data; | ||
299 | 320 | ||
300 | sdhci_remove_host(host, 1); | 321 | sdhci_remove_host(host, 1); |
301 | 322 | ||
302 | clk_disable_unprepare(pltfm_host->clk); | 323 | clk_disable_unprepare(pltfm_host->clk); |
303 | clk_put(pltfm_host->clk); | 324 | clk_put(pltfm_host->clk); |
325 | |||
326 | if (gpio_is_valid(pdata->ext_cd_gpio)) | ||
327 | mmc_gpio_free_cd(host->mmc); | ||
328 | |||
304 | sdhci_pltfm_free(pdev); | 329 | sdhci_pltfm_free(pdev); |
305 | kfree(pxa); | 330 | kfree(pxa); |
306 | 331 | ||
diff --git a/include/linux/platform_data/pxa_sdhci.h b/include/linux/platform_data/pxa_sdhci.h index 51ad0995abac..59acd987ed34 100644 --- a/include/linux/platform_data/pxa_sdhci.h +++ b/include/linux/platform_data/pxa_sdhci.h | |||
@@ -49,6 +49,7 @@ struct sdhci_pxa_platdata { | |||
49 | bool ext_cd_gpio_invert; | 49 | bool ext_cd_gpio_invert; |
50 | unsigned int max_speed; | 50 | unsigned int max_speed; |
51 | unsigned int host_caps; | 51 | unsigned int host_caps; |
52 | unsigned int host_caps2; | ||
52 | unsigned int quirks; | 53 | unsigned int quirks; |
53 | unsigned int pm_caps; | 54 | unsigned int pm_caps; |
54 | }; | 55 | }; |