aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/host/sdhci-tegra.c119
-rw-r--r--include/linux/platform_data/mmc-sdhci-tegra.h28
2 files changed, 45 insertions, 102 deletions
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 5a600a53b876..08b06e9a3a21 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -27,8 +27,6 @@
27 27
28#include <asm/gpio.h> 28#include <asm/gpio.h>
29 29
30#include <linux/platform_data/mmc-sdhci-tegra.h>
31
32#include "sdhci-pltfm.h" 30#include "sdhci-pltfm.h"
33 31
34/* Tegra SDHOST controller vendor register definitions */ 32/* Tegra SDHOST controller vendor register definitions */
@@ -45,8 +43,11 @@ struct sdhci_tegra_soc_data {
45}; 43};
46 44
47struct sdhci_tegra { 45struct sdhci_tegra {
48 const struct tegra_sdhci_platform_data *plat;
49 const struct sdhci_tegra_soc_data *soc_data; 46 const struct sdhci_tegra_soc_data *soc_data;
47 int cd_gpio;
48 int wp_gpio;
49 int power_gpio;
50 int is_8bit;
50}; 51};
51 52
52static u32 tegra_sdhci_readl(struct sdhci_host *host, int reg) 53static u32 tegra_sdhci_readl(struct sdhci_host *host, int reg)
@@ -108,12 +109,11 @@ static unsigned int tegra_sdhci_get_ro(struct sdhci_host *host)
108{ 109{
109 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 110 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
110 struct sdhci_tegra *tegra_host = pltfm_host->priv; 111 struct sdhci_tegra *tegra_host = pltfm_host->priv;
111 const struct tegra_sdhci_platform_data *plat = tegra_host->plat;
112 112
113 if (!gpio_is_valid(plat->wp_gpio)) 113 if (!gpio_is_valid(tegra_host->wp_gpio))
114 return -1; 114 return -1;
115 115
116 return gpio_get_value(plat->wp_gpio); 116 return gpio_get_value(tegra_host->wp_gpio);
117} 117}
118 118
119static irqreturn_t carddetect_irq(int irq, void *data) 119static irqreturn_t carddetect_irq(int irq, void *data)
@@ -147,11 +147,10 @@ static int tegra_sdhci_buswidth(struct sdhci_host *host, int bus_width)
147{ 147{
148 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 148 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
149 struct sdhci_tegra *tegra_host = pltfm_host->priv; 149 struct sdhci_tegra *tegra_host = pltfm_host->priv;
150 const struct tegra_sdhci_platform_data *plat = tegra_host->plat;
151 u32 ctrl; 150 u32 ctrl;
152 151
153 ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); 152 ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
154 if (plat->is_8bit && bus_width == MMC_BUS_WIDTH_8) { 153 if (tegra_host->is_8bit && bus_width == MMC_BUS_WIDTH_8) {
155 ctrl &= ~SDHCI_CTRL_4BITBUS; 154 ctrl &= ~SDHCI_CTRL_4BITBUS;
156 ctrl |= SDHCI_CTRL_8BITBUS; 155 ctrl |= SDHCI_CTRL_8BITBUS;
157 } else { 156 } else {
@@ -217,31 +216,19 @@ static const struct of_device_id sdhci_tegra_dt_match[] = {
217}; 216};
218MODULE_DEVICE_TABLE(of, sdhci_dt_ids); 217MODULE_DEVICE_TABLE(of, sdhci_dt_ids);
219 218
220static struct tegra_sdhci_platform_data *sdhci_tegra_dt_parse_pdata( 219static void sdhci_tegra_parse_dt(struct device *dev,
221 struct platform_device *pdev) 220 struct sdhci_tegra *tegra_host)
222{ 221{
223 struct tegra_sdhci_platform_data *plat; 222 struct device_node *np = dev->of_node;
224 struct device_node *np = pdev->dev.of_node;
225 u32 bus_width; 223 u32 bus_width;
226 224
227 if (!np) 225 tegra_host->cd_gpio = of_get_named_gpio(np, "cd-gpios", 0);
228 return NULL; 226 tegra_host->wp_gpio = of_get_named_gpio(np, "wp-gpios", 0);
229 227 tegra_host->power_gpio = of_get_named_gpio(np, "power-gpios", 0);
230 plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL);
231 if (!plat) {
232 dev_err(&pdev->dev, "Can't allocate platform data\n");
233 return NULL;
234 }
235
236 plat->cd_gpio = of_get_named_gpio(np, "cd-gpios", 0);
237 plat->wp_gpio = of_get_named_gpio(np, "wp-gpios", 0);
238 plat->power_gpio = of_get_named_gpio(np, "power-gpios", 0);
239 228
240 if (of_property_read_u32(np, "bus-width", &bus_width) == 0 && 229 if (of_property_read_u32(np, "bus-width", &bus_width) == 0 &&
241 bus_width == 8) 230 bus_width == 8)
242 plat->is_8bit = 1; 231 tegra_host->is_8bit = 1;
243
244 return plat;
245} 232}
246 233
247static int sdhci_tegra_probe(struct platform_device *pdev) 234static int sdhci_tegra_probe(struct platform_device *pdev)
@@ -250,7 +237,6 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
250 const struct sdhci_tegra_soc_data *soc_data; 237 const struct sdhci_tegra_soc_data *soc_data;
251 struct sdhci_host *host; 238 struct sdhci_host *host;
252 struct sdhci_pltfm_host *pltfm_host; 239 struct sdhci_pltfm_host *pltfm_host;
253 struct tegra_sdhci_platform_data *plat;
254 struct sdhci_tegra *tegra_host; 240 struct sdhci_tegra *tegra_host;
255 struct clk *clk; 241 struct clk *clk;
256 int rc; 242 int rc;
@@ -263,52 +249,40 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
263 host = sdhci_pltfm_init(pdev, soc_data->pdata); 249 host = sdhci_pltfm_init(pdev, soc_data->pdata);
264 if (IS_ERR(host)) 250 if (IS_ERR(host))
265 return PTR_ERR(host); 251 return PTR_ERR(host);
266
267 pltfm_host = sdhci_priv(host); 252 pltfm_host = sdhci_priv(host);
268 253
269 plat = pdev->dev.platform_data;
270
271 if (plat == NULL)
272 plat = sdhci_tegra_dt_parse_pdata(pdev);
273
274 if (plat == NULL) {
275 dev_err(mmc_dev(host->mmc), "missing platform data\n");
276 rc = -ENXIO;
277 goto err_no_plat;
278 }
279
280 tegra_host = devm_kzalloc(&pdev->dev, sizeof(*tegra_host), GFP_KERNEL); 254 tegra_host = devm_kzalloc(&pdev->dev, sizeof(*tegra_host), GFP_KERNEL);
281 if (!tegra_host) { 255 if (!tegra_host) {
282 dev_err(mmc_dev(host->mmc), "failed to allocate tegra_host\n"); 256 dev_err(mmc_dev(host->mmc), "failed to allocate tegra_host\n");
283 rc = -ENOMEM; 257 rc = -ENOMEM;
284 goto err_no_plat; 258 goto err_alloc_tegra_host;
285 } 259 }
286
287 tegra_host->plat = plat;
288 tegra_host->soc_data = soc_data; 260 tegra_host->soc_data = soc_data;
289
290 pltfm_host->priv = tegra_host; 261 pltfm_host->priv = tegra_host;
291 262
292 if (gpio_is_valid(plat->power_gpio)) { 263 sdhci_tegra_parse_dt(&pdev->dev, tegra_host);
293 rc = gpio_request(plat->power_gpio, "sdhci_power"); 264
265 if (gpio_is_valid(tegra_host->power_gpio)) {
266 rc = gpio_request(tegra_host->power_gpio, "sdhci_power");
294 if (rc) { 267 if (rc) {
295 dev_err(mmc_dev(host->mmc), 268 dev_err(mmc_dev(host->mmc),
296 "failed to allocate power gpio\n"); 269 "failed to allocate power gpio\n");
297 goto err_power_req; 270 goto err_power_req;
298 } 271 }
299 gpio_direction_output(plat->power_gpio, 1); 272 gpio_direction_output(tegra_host->power_gpio, 1);
300 } 273 }
301 274
302 if (gpio_is_valid(plat->cd_gpio)) { 275 if (gpio_is_valid(tegra_host->cd_gpio)) {
303 rc = gpio_request(plat->cd_gpio, "sdhci_cd"); 276 rc = gpio_request(tegra_host->cd_gpio, "sdhci_cd");
304 if (rc) { 277 if (rc) {
305 dev_err(mmc_dev(host->mmc), 278 dev_err(mmc_dev(host->mmc),
306 "failed to allocate cd gpio\n"); 279 "failed to allocate cd gpio\n");
307 goto err_cd_req; 280 goto err_cd_req;
308 } 281 }
309 gpio_direction_input(plat->cd_gpio); 282 gpio_direction_input(tegra_host->cd_gpio);
310 283
311 rc = request_irq(gpio_to_irq(plat->cd_gpio), carddetect_irq, 284 rc = request_irq(gpio_to_irq(tegra_host->cd_gpio),
285 carddetect_irq,
312 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, 286 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,