aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/sdhci-tegra.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-10-28 17:16:11 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-10-28 17:16:11 -0400
commit46b51ea2099fa2082342e52b8284aa828429b80b (patch)
tree0a0d7bfe1aff036c86a2e7beacbd91398008bfb6 /drivers/mmc/host/sdhci-tegra.c
parent1fdb24e969110fafea36d3b393bea438f702c87f (diff)
parenta6029e1f75bb484c1f5bc68b6a8572e4024795bc (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc: (83 commits) mmc: fix compile error when CONFIG_BLOCK is not enabled mmc: core: Cleanup eMMC4.5 conditionals mmc: omap_hsmmc: if multiblock reads are broken, disable them mmc: core: add workaround for controllers with broken multiblock reads mmc: core: Prevent too long response times for suspend mmc: recognise SDIO cards with SDIO_CCCR_REV 3.00 mmc: sd: Handle SD3.0 cards not supporting UHS-I bus speed mode mmc: core: support HPI send command mmc: core: Add cache control for eMMC4.5 device mmc: core: Modify the timeout value for writing power class mmc: core: new discard feature support at eMMC v4.5 mmc: core: mmc sanitize feature support for v4.5 mmc: dw_mmc: modify DATA register offset mmc: sdhci-pci: add flag for devices that can support runtime PM mmc: omap_hsmmc: ensure pbias configuration is always done mmc: core: Add Power Off Notify Feature eMMC 4.5 mmc: sdhci-s3c: fix potential NULL dereference mmc: replace printk with appropriate display macro mmc: core: Add default timeout value for CMD6 mmc: sdhci-pci: add runtime pm support ...
Diffstat (limited to 'drivers/mmc/host/sdhci-tegra.c')
-rw-r--r--drivers/mmc/host/sdhci-tegra.c55
1 files changed, 44 insertions, 11 deletions
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 21b00cefae63..067a4cded9cf 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -17,9 +17,12 @@
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.h>
21#include <linux/of_gpio.h>
20#include <linux/gpio.h> 22#include <linux/gpio.h>
21#include <linux/mmc/card.h> 23#include <linux/mmc/card.h>
22#include <linux/mmc/host.h> 24#include <linux/mmc/host.h>
25#include <linux/module.h>
23 26
24#include <asm/gpio.h> 27#include <asm/gpio.h>
25 28
@@ -75,10 +78,8 @@ static void tegra_sdhci_writel(struct sdhci_host *host, u32 val, int reg)
75 78
76static unsigned int tegra_sdhci_get_ro(struct sdhci_host *sdhci) 79static unsigned int tegra_sdhci_get_ro(struct sdhci_host *sdhci)
77{ 80{
78 struct platform_device *pdev = to_platform_device(mmc_dev(sdhci->mmc)); 81 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(sdhci);
79 struct tegra_sdhci_platform_data *plat; 82 struct tegra_sdhci_platform_data *plat = pltfm_host->priv;
80
81 plat = pdev->dev.platform_data;
82 83
83 if (!gpio_is_valid(plat->wp_gpio)) 84 if (!gpio_is_valid(plat->wp_gpio))
84 return -1; 85 return -1;
@@ -96,12 +97,10 @@ static irqreturn_t carddetect_irq(int irq, void *data)
96 97
97static int tegra_sdhci_8bit(struct sdhci_host *host, int bus_width) 98static int tegra_sdhci_8bit(struct sdhci_host *host, int bus_width)
98{ 99{
99 struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc)); 100 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
100 struct tegra_sdhci_platform_data *plat; 101 struct tegra_sdhci_platform_data *plat = pltfm_host->priv;
101 u32 ctrl; 102 u32 ctrl;
102 103
103 plat = pdev->dev.platform_data;
104
105 ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); 104 ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
106 if (plat->is_8bit && bus_width == MMC_BUS_WIDTH_8) { 105 if (plat->is_8bit && bus_width == MMC_BUS_WIDTH_8) {
107 ctrl &= ~SDHCI_CTRL_4BITBUS; 106 ctrl &= ~SDHCI_CTRL_4BITBUS;
@@ -133,6 +132,36 @@ static struct sdhci_pltfm_data sdhci_tegra_pdata = {
133 .ops = &tegra_sdhci_ops, 132 .ops = &tegra_sdhci_ops,
134}; 133};
135 134
135static const struct of_device_id sdhci_tegra_dt_match[] __devinitdata = {
136 { .compatible = "nvidia,tegra20-sdhci", },
137 {}
138};
139MODULE_DEVICE_TABLE(of, sdhci_dt_ids);
140
141static struct tegra_sdhci_platform_data * __devinit sdhci_tegra_dt_parse_pdata(
142 struct platform_device *pdev)
143{
144 struct tegra_sdhci_platform_data *plat;
145 struct device_node *np = pdev->dev.of_node;
146
147 if (!np)
148 return NULL;
149
150 plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL);
151 if (!plat) {
152 dev_err(&pdev->dev, "Can't allocate platform data\n");
153 return NULL;
154 }
155
156 plat->cd_gpio = of_get_named_gpio(np, "cd-gpios", 0);
157 plat->wp_gpio = of_get_named_gpio(np, "wp-gpios", 0);
158 plat->power_gpio = of_get_named_gpio(np, "power-gpios", 0);
159 if (of_find_property(np, "support-8bit", NULL))
160 plat->is_8bit = 1;
161
162 return plat;
163}
164
136static int __devinit sdhci_tegra_probe(struct platform_device *pdev) 165static int __devinit sdhci_tegra_probe(struct platform_device *pdev)
137{ 166{
138 struct sdhci_pltfm_host *pltfm_host; 167 struct sdhci_pltfm_host *pltfm_host;
@@ -149,12 +178,17 @@ static int __devinit sdhci_tegra_probe(struct platform_device *pdev)
149 178
150 plat = pdev->dev.platform_data; 179 plat = pdev->dev.platform_data;
151 180
181 if (plat == NULL)
182 plat = sdhci_tegra_dt_parse_pdata(pdev);
183
152 if (plat == NULL) { 184 if (plat == NULL) {
153 dev_err(mmc_dev(host->mmc), "missing platform data\n"); 185 dev_err(mmc_dev(host->mmc), "missing platform data\n");
154 rc = -ENXIO; 186 rc = -ENXIO;
155 goto err_no_plat; 187 goto err_no_plat;
156 } 188 }
157 189
190 pltfm_host->priv = plat;
191
158 if (gpio_is_valid(plat->power_gpio)) { 192 if (gpio_is_valid(plat->power_gpio)) {
159 rc = gpio_request(plat->power_gpio, "sdhci_power"); 193 rc = gpio_request(plat->power_gpio, "sdhci_power");
160 if (rc) { 194 if (rc) {
@@ -249,13 +283,11 @@ static int __devexit sdhci_tegra_remove(struct platform_device *pdev)
249{ 283{
250 struct sdhci_host *host = platform_get_drvdata(pdev); 284 struct sdhci_host *host = platform_get_drvdata(pdev);
251 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 285 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
252 struct tegra_sdhci_platform_data *plat; 286 struct tegra_sdhci_platform_data *plat = pltfm_host->priv;
253 int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff); 287 int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff);
254 288
255 sdhci_remove_host(host, dead); 289 sdhci_remove_host(host, dead);
256 290
257 plat = pdev->dev.platform_data;
258
259 if (gpio_is_valid(plat->wp_gpio)) { 291 if (gpio_is_valid(plat->wp_gpio)) {
260 tegra_gpio_disable(plat->wp_gpio); 292 tegra_gpio_disable(plat->wp_gpio);
261 gpio_free(plat->wp_gpio); 293 gpio_free(plat->wp_gpio);
@@ -284,6 +316,7 @@ static struct platform_driver sdhci_tegra_driver = {
284 .driver = { 316 .driver = {
285 .name = "sdhci-tegra", 317 .name = "sdhci-tegra",
286 .owner = THIS_MODULE, 318 .owner = THIS_MODULE,
319 .of_match_table = sdhci_tegra_dt_match,
287 }, 320 },
288 .probe = sdhci_tegra_probe, 321 .probe = sdhci_tegra_probe,
289 .remove = __devexit_p(sdhci_tegra_remove), 322 .remove = __devexit_p(sdhci_tegra_remove),