aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2011-08-23 14:15:33 -0400
committerChris Ball <cjb@laptop.org>2011-10-26 15:43:35 -0400
commit275173b225ae663e54d8dc5c93d79265aad19f89 (patch)
treece6cd20e8d888c74d0eaa3975acee705f239462a /drivers/mmc
parent08da834a24312157f512224691ad1fddd11c1073 (diff)
mmc: sdhci-tegra: Add Device Tree probing support
Add hooks to read gpio configuration out of the device tree node. [grant.likely: Rewrite of original patch from John Bonesio] Signed-off-by: Grant Likely <grant.likely@secretlab.ca> [swarren: Fixed tegra_sdhci_get_ro() to retrieve pdata correctly] [swarren: Reworked to avoid #ifdef CONFIG_OF] [swarren: Reworked binding based on fsl-imx-esdhc.txt] [swarren: Documented binding] Signed-off-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/sdhci-tegra.c51
1 files changed, 40 insertions, 11 deletions
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 18b0bd31de78..8a114b6211c7 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -17,6 +17,7 @@
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/clk.h> 18#include <linux/clk.h>
19#include <linux/io.h> 19#include <linux/io.h>
20#include <linux/of_gpio.h>
20#include <linux/gpio.h> 21#include <linux/gpio.h>
21#include <linux/mmc/card.h> 22#include <linux/mmc/card.h>
22#include <linux/mmc/host.h> 23#include <linux/mmc/host.h>
@@ -73,10 +74,8 @@ static void tegra_sdhci_writel(struct sdhci_host *host, u32 val, int reg)
73 74
74static unsigned int tegra_sdhci_get_ro(struct sdhci_host *sdhci) 75static unsigned int tegra_sdhci_get_ro(struct sdhci_host *sdhci)
75{ 76{
76 struct platform_device *pdev = to_platform_device(mmc_dev(sdhci->mmc)); 77 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(sdhci);
77 struct tegra_sdhci_platform_data *plat; 78 struct tegra_sdhci_platform_data *plat = pltfm_host->priv;
78
79 plat = pdev->dev.platform_data;
80 79
81 if (!gpio_is_valid(plat->wp_gpio)) 80 if (!gpio_is_valid(plat->wp_gpio))
82 return -1; 81 return -1;
@@ -94,12 +93,10 @@ static irqreturn_t carddetect_irq(int irq, void *data)
94 93
95static int tegra_sdhci_8bit(struct sdhci_host *host, int bus_width) 94static int tegra_sdhci_8bit(struct sdhci_host *host, int bus_width)
96{ 95{
97 struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc)); 96 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
98 struct tegra_sdhci_platform_data *plat; 97 struct tegra_sdhci_platform_data *plat = pltfm_host->priv;
99 u32 ctrl; 98 u32 ctrl;
100 99
101 plat = pdev->dev.platform_data;
102
103 ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); 100 ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
104 if (plat->is_8bit && bus_width == MMC_BUS_WIDTH_8) { 101 if (plat->is_8bit && bus_width == MMC_BUS_WIDTH_8) {
105 ctrl &= ~SDHCI_CTRL_4BITBUS; 102 ctrl &= ~SDHCI_CTRL_4BITBUS;
@@ -131,6 +128,34 @@ static struct sdhci_pltfm_data sdhci_tegra_pdata = {
131 .ops = &tegra_sdhci_ops, 128 .ops = &tegra_sdhci_ops,
132}; 129};
133 130
131static const struct of_device_id sdhci_tegra_dt_match[] __devinitdata = {
132 { .compatible = "nvidia,tegra20-sdhci", },
133 {}
134};
135MODULE_DEVICE_TABLE(of, sdhci_dt_ids);
136
137static struct tegra_sdhci_platform_data * __devinit sdhci_tegra_dt_parse_pdata(
138 struct platform_device *pdev)
139{
140 struct tegra_sdhci_platform_data *plat;
141 struct device_node *np = pdev->dev.of_node;
142
143 if (!np)
144 return NULL;
145
146 plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL);
147 if (!plat) {
148 dev_err(&pdev->dev, "Can't allocate platform data\n");
149 return NULL;
150 }
151
152 plat->cd_gpio = of_get_named_gpio(np, "cd-gpios", 0);
153 plat->wp_gpio = of_get_named_gpio(np, "wp-gpios", 0);
154 plat->power_gpio = of_get_named_gpio(np, "power-gpios", 0);
155
156 return plat;
157}
158
134static int __devinit sdhci_tegra_probe(struct platform_device *pdev) 159static int __devinit sdhci_tegra_probe(struct platform_device *pdev)
135{ 160{
136 struct sdhci_pltfm_host *pltfm_host; 161 struct sdhci_pltfm_host *pltfm_host;
@@ -147,12 +172,17 @@ static int __devinit sdhci_tegra_probe(struct platform_device *pdev)
147 172
148 plat = pdev->dev.platform_data; 173 plat = pdev->dev.platform_data;
149 174
175 if (plat == NULL)
176 plat = sdhci_tegra_dt_parse_pdata(pdev);
177
150 if (plat == NULL) { 178 if (plat == NULL) {
151 dev_err(mmc_dev(host->mmc), "missing platform data\n"); 179 dev_err(mmc_dev(host->mmc), "missing platform data\n");
152 rc = -ENXIO; 180 rc = -ENXIO;
153 goto err_no_plat; 181 goto err_no_plat;
154 } 182 }
155 183
184 pltfm_host->priv = plat;
185
156 if (gpio_is_valid(plat->power_gpio)) { 186 if (gpio_is_valid(plat->power_gpio)) {
157 rc = gpio_request(plat->power_gpio, "sdhci_power"); 187 rc = gpio_request(plat->power_gpio, "sdhci_power");
158 if (rc) { 188 if (rc) {
@@ -247,13 +277,11 @@ static int __devexit sdhci_tegra_remove(struct platform_device *pdev)
247{ 277{
248 struct sdhci_host *host = platform_get_drvdata(pdev); 278 struct sdhci_host *host = platform_get_drvdata(pdev);
249 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 279 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
250 struct tegra_sdhci_platform_data *plat; 280 struct tegra_sdhci_platform_data *plat = pltfm_host->priv;
251 int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff); 281 int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff);
252 282
253 sdhci_remove_host(host, dead); 283 sdhci_remove_host(host, dead);
254 284
255 plat = pdev->dev.platform_data;
256
257 if (gpio_is_valid(plat->wp_gpio)) { 285 if (gpio_is_valid(plat->wp_gpio)) {
258 tegra_gpio_disable(plat->wp_gpio); 286 tegra_gpio_disable(plat->wp_gpio);
259 gpio_free(plat->wp_gpio); 287 gpio_free(plat->wp_gpio);
@@ -282,6 +310,7 @@ static struct platform_driver sdhci_tegra_driver = {
282 .driver = { 310 .driver = {
283 .name = "sdhci-tegra", 311 .name = "sdhci-tegra",
284 .owner = THIS_MODULE, 312 .owner = THIS_MODULE,
313 .of_match_table = sdhci_tegra_dt_match,
285 }, 314 },
286 .probe = sdhci_tegra_probe, 315 .probe = sdhci_tegra_probe,
287 .remove = __devexit_p(sdhci_tegra_remove), 316 .remove = __devexit_p(sdhci_tegra_remove),