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,
313 mmc_hostname(host->mmc), host); 287 mmc_hostname(host->mmc), host);
314 288
@@ -319,14 +293,14 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
319 293
320 } 294 }
321 295
322 if (gpio_is_valid(plat->wp_gpio)) { 296 if (gpio_is_valid(tegra_host->wp_gpio)) {
323 rc = gpio_request(plat->wp_gpio, "sdhci_wp"); 297 rc = gpio_request(tegra_host->wp_gpio, "sdhci_wp");
324 if (rc) { 298 if (rc) {
325 dev_err(mmc_dev(host->mmc), 299 dev_err(mmc_dev(host->mmc),
326 "failed to allocate wp gpio\n"); 300 "failed to allocate wp gpio\n");
327 goto err_wp_req; 301 goto err_wp_req;
328 } 302 }
329 gpio_direction_input(plat->wp_gpio); 303 gpio_direction_input(tegra_host->wp_gpio);
330 } 304 }
331 305
332 clk = clk_get(mmc_dev(host->mmc), NULL); 306 clk = clk_get(mmc_dev(host->mmc), NULL);
@@ -338,9 +312,7 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
338 clk_prepare_enable(clk); 312 clk_prepare_enable(clk);
339 pltfm_host->clk = clk; 313 pltfm_host->clk = clk;
340 314
341 host->mmc->pm_caps = plat->pm_flags; 315 if (tegra_host->is_8bit)
342
343 if (plat->is_8bit)
344 host->mmc->caps |= MMC_CAP_8_BIT_DATA; 316 host->mmc->caps |= MMC_CAP_8_BIT_DATA;
345 317
346 rc = sdhci_add_host(host); 318 rc = sdhci_add_host(host);
@@ -353,19 +325,19 @@ err_add_host:
353 clk_disable_unprepare(pltfm_host->clk); 325 clk_disable_unprepare(pltfm_host->clk);
354 clk_put(pltfm_host->clk); 326 clk_put(pltfm_host->clk);
355err_clk_get: 327err_clk_get:
356 if (gpio_is_valid(plat->wp_gpio)) 328 if (gpio_is_valid(tegra_host->wp_gpio))
357 gpio_free(plat->wp_gpio); 329 gpio_free(tegra_host->wp_gpio);
358err_wp_req: 330err_wp_req:
359 if (gpio_is_valid(plat->cd_gpio)) 331 if (gpio_is_valid(tegra_host->cd_gpio))
360 free_irq(gpio_to_irq(plat->cd_gpio), host); 332 free_irq(gpio_to_irq(tegra_host->cd_gpio), host);
361err_cd_irq_req: 333err_cd_irq_req:
362 if (gpio_is_valid(plat->cd_gpio)) 334 if (gpio_is_valid(tegra_host->cd_gpio))
363 gpio_free(plat->cd_gpio); 335 gpio_free(tegra_host->cd_gpio);
364err_cd_req: 336err_cd_req:
365 if (gpio_is_valid(plat->power_gpio)) 337 if (gpio_is_valid(tegra_host->power_gpio))
366 gpio_free(plat->power_gpio); 338 gpio_free(tegra_host->power_gpio);
367err_power_req: 339err_power_req:
368err_no_plat: 340err_alloc_tegra_host:
369 sdhci_pltfm_free(pdev); 341 sdhci_pltfm_free(pdev);
370 return rc; 342 return rc;
371} 343}
@@ -375,21 +347,20 @@ static int sdhci_tegra_remove(struct platform_device *pdev)
375 struct sdhci_host *host = platform_get_drvdata(pdev); 347 struct sdhci_host *host = platform_get_drvdata(pdev);
376 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 348 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
377 struct sdhci_tegra *tegra_host = pltfm_host->priv; 349 struct sdhci_tegra *tegra_host = pltfm_host->priv;
378 const struct tegra_sdhci_platform_data *plat = tegra_host->plat;
379 int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff); 350 int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff);
380 351
381 sdhci_remove_host(host, dead); 352 sdhci_remove_host(host, dead);
382 353
383 if (gpio_is_valid(plat->wp_gpio)) 354 if (gpio_is_valid(tegra_host->wp_gpio))
384 gpio_free(plat->wp_gpio); 355 gpio_free(tegra_host->wp_gpio);
385 356
386 if (gpio_is_valid(plat->cd_gpio)) { 357 if (gpio_is_valid(tegra_host->cd_gpio)) {
387 free_irq(gpio_to_irq(plat->cd_gpio), host); 358 free_irq(gpio_to_irq(tegra_host->cd_gpio), host);
388 gpio_free(plat->cd_gpio); 359 gpio_free(tegra_host->cd_gpio);
389 } 360 }
390 361
391 if (gpio_is_valid(plat->power_gpio)) 362 if (gpio_is_valid(tegra_host->power_gpio))
392 gpio_free(plat->power_gpio); 363 gpio_free(tegra_host->power_gpio);
393 364
394 clk_disable_unprepare(pltfm_host->clk); 365 clk_disable_unprepare(pltfm_host->clk);
395 clk_put(pltfm_host->clk); 366 clk_put(pltfm_host->clk);
diff --git a/include/linux/platform_data/mmc-sdhci-tegra.h b/include/linux/platform_data/mmc-sdhci-tegra.h
deleted file mode 100644
index 8f8430697686..000000000000
--- a/include/linux/platform_data/mmc-sdhci-tegra.h
+++ /dev/null
@@ -1,28 +0,0 @@
1/*
2 * Copyright (C) 2009 Palm, Inc.
3 * Author: Yvonne Yip <y@palm.com>
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15#ifndef __PLATFORM_DATA_TEGRA_SDHCI_H
16#define __PLATFORM_DATA_TEGRA_SDHCI_H
17
18#include <linux/mmc/host.h>
19
20struct tegra_sdhci_platform_data {
21 int cd_gpio;
22 int wp_gpio;
23 int power_gpio;
24 int is_8bit;
25 int pm_flags;
26};
27
28#endif