diff options
author | Joseph Lo <josephl@nvidia.com> | 2013-03-11 16:44:11 -0400 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2013-03-19 13:10:09 -0400 |
commit | 0aacd23ff29a846c7eebbd9db8752fa360f34ad1 (patch) | |
tree | 49dce83c205aa1c24e12890be982302fe506ac87 /drivers/mmc | |
parent | 2c06aeb25ca92b839399c4e2c956cffc95b41978 (diff) |
mmc: tegra: use mmc_of_parse to get the support of standard MMC DT bindings
Updating the sdhci-tegra driver to use mmc_of_parse to support standard
MMC DT bindings. Then we can remove the redundant code that already support
in generic MMC core.
Signed-off-by: Joseph Lo <josephl@nvidia.com>
Tested-by: Thierry Reding <thierry.reding@avionic-design.de>
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.c | 92 |
1 files changed, 10 insertions, 82 deletions
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index ff99b632808d..c665d1d26320 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c | |||
@@ -24,6 +24,7 @@ | |||
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 | 28 | ||
28 | #include <asm/gpio.h> | 29 | #include <asm/gpio.h> |
29 | 30 | ||
@@ -44,10 +45,7 @@ struct sdhci_tegra_soc_data { | |||
44 | 45 | ||
45 | struct sdhci_tegra { | 46 | struct sdhci_tegra { |
46 | const struct sdhci_tegra_soc_data *soc_data; | 47 | const struct sdhci_tegra_soc_data *soc_data; |
47 | int cd_gpio; | ||
48 | int wp_gpio; | ||
49 | int power_gpio; | 48 | int power_gpio; |
50 | int is_8bit; | ||
51 | }; | 49 | }; |
52 | 50 | ||
53 | static u32 tegra_sdhci_readl(struct sdhci_host *host, int reg) | 51 | static u32 tegra_sdhci_readl(struct sdhci_host *host, int reg) |
@@ -107,23 +105,9 @@ static void tegra_sdhci_writel(struct sdhci_host *host, u32 val, int reg) | |||
107 | 105 | ||
108 | static unsigned int tegra_sdhci_get_ro(struct sdhci_host *host) | 106 | static unsigned int tegra_sdhci_get_ro(struct sdhci_host *host) |
109 | { | 107 | { |
110 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 108 | return mmc_gpio_get_ro(host->mmc); |
111 | struct sdhci_tegra *tegra_host = pltfm_host->priv; | ||
112 | |||
113 | if (!gpio_is_valid(tegra_host->wp_gpio)) | ||
114 | return -1; | ||
115 | |||
116 | return gpio_get_value(tegra_host->wp_gpio); | ||
117 | } | 109 | } |
118 | 110 | ||
119 | static irqreturn_t carddetect_irq(int irq, void *data) | ||
120 | { | ||
121 | struct sdhci_host *sdhost = (struct sdhci_host *)data; | ||
122 | |||
123 | tasklet_schedule(&sdhost->card_tasklet); | ||
124 | return IRQ_HANDLED; | ||
125 | }; | ||
126 | |||
127 | static void tegra_sdhci_reset_exit(struct sdhci_host *host, u8 mask) | 111 | static void tegra_sdhci_reset_exit(struct sdhci_host *host, u8 mask) |
128 | { | 112 | { |
129 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 113 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
@@ -145,12 +129,11 @@ static void tegra_sdhci_reset_exit(struct sdhci_host *host, u8 mask) | |||
145 | 129 | ||
146 | static int tegra_sdhci_buswidth(struct sdhci_host *host, int bus_width) | 130 | static int tegra_sdhci_buswidth(struct sdhci_host *host, int bus_width) |
147 | { | 131 | { |
148 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
149 | struct sdhci_tegra *tegra_host = pltfm_host->priv; | ||
150 | u32 ctrl; | 132 | u32 ctrl; |
151 | 133 | ||
152 | ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); | 134 | ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); |
153 | if (tegra_host->is_8bit && bus_width == MMC_BUS_WIDTH_8) { | 135 | if ((host->mmc->caps & MMC_CAP_8_BIT_DATA) && |
136 | (bus_width == MMC_BUS_WIDTH_8)) { | ||
154 | ctrl &= ~SDHCI_CTRL_4BITBUS; | 137 | ctrl &= ~SDHCI_CTRL_4BITBUS; |
155 | ctrl |= SDHCI_CTRL_8BITBUS; | 138 | ctrl |= SDHCI_CTRL_8BITBUS; |
156 | } else { | 139 | } else { |
@@ -222,19 +205,15 @@ static const struct of_device_id sdhci_tegra_dt_match[] = { | |||
222 | }; | 205 | }; |
223 | MODULE_DEVICE_TABLE(of, sdhci_dt_ids); | 206 | MODULE_DEVICE_TABLE(of, sdhci_dt_ids); |
224 | 207 | ||
225 | static void sdhci_tegra_parse_dt(struct device *dev, | 208 | static void sdhci_tegra_parse_dt(struct device *dev) |
226 | struct sdhci_tegra *tegra_host) | ||
227 | { | 209 | { |
228 | struct device_node *np = dev->of_node; | 210 | struct device_node *np = dev->of_node; |
229 | u32 bus_width; | 211 | struct sdhci_host *host = dev_get_drvdata(dev); |
212 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
213 | struct sdhci_tegra *tegra_host = pltfm_host->priv; | ||
230 | 214 | ||
231 | tegra_host->cd_gpio = of_get_named_gpio(np, "cd-gpios", 0); | ||
232 | tegra_host->wp_gpio = of_get_named_gpio(np, "wp-gpios", 0); | ||
233 | tegra_host->power_gpio = of_get_named_gpio(np, "power-gpios", 0); | 215 | tegra_host->power_gpio = of_get_named_gpio(np, "power-gpios", 0); |
234 | 216 | mmc_of_parse(host->mmc); | |
235 | if (of_property_read_u32(np, "bus-width", &bus_width) == 0 && | ||
236 | bus_width == 8) | ||
237 | tegra_host->is_8bit = 1; | ||
238 | } | 217 | } |
239 | 218 | ||
240 | static int sdhci_tegra_probe(struct platform_device *pdev) | 219 | static int sdhci_tegra_probe(struct platform_device *pdev) |
@@ -266,7 +245,7 @@ static int sdhci_tegra_probe(struct platform_device *pdev) | |||
266 | tegra_host->soc_data = soc_data; | 245 | tegra_host->soc_data = soc_data; |
267 | pltfm_host->priv = tegra_host; | 246 | pltfm_host->priv = tegra_host; |
268 | 247 | ||
269 | sdhci_tegra_parse_dt(&pdev->dev, tegra_host); | 248 | sdhci_tegra_parse_dt(&pdev->dev); |
270 | 249 | ||
271 | if (gpio_is_valid(tegra_host->power_gpio)) { | 250 | if (gpio_is_valid(tegra_host->power_gpio)) { |
272 | rc = gpio_request(tegra_host->power_gpio, "sdhci_power"); | 251 | rc = gpio_request(tegra_host->power_gpio, "sdhci_power"); |
@@ -278,37 +257,6 @@ static int sdhci_tegra_probe(struct platform_device *pdev) | |||
278 | gpio_direction_output(tegra_host->power_gpio, 1); | 257 | gpio_direction_output(tegra_host->power_gpio, 1); |
279 | } | 258 | } |
280 | 259 | ||
281 | if (gpio_is_valid(tegra_host->cd_gpio)) { | ||
282 | rc = gpio_request(tegra_host->cd_gpio, "sdhci_cd"); | ||
283 | if (rc) { | ||
284 | dev_err(mmc_dev(host->mmc), | ||
285 | "failed to allocate cd gpio\n"); | ||
286 | goto err_cd_req; | ||
287 | } | ||
288 | gpio_direction_input(tegra_host->cd_gpio); | ||
289 | |||
290 | rc = request_irq(gpio_to_irq(tegra_host->cd_gpio), | ||
291 | carddetect_irq, | ||
292 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, | ||
293 | mmc_hostname(host->mmc), host); | ||
294 | |||
295 | if (rc) { | ||
296 | dev_err(mmc_dev(host->mmc), "request irq error\n"); | ||
297 | goto err_cd_irq_req; | ||
298 | } | ||
299 | |||
300 | } | ||
301 | |||
302 | if (gpio_is_valid(tegra_host->wp_gpio)) { | ||
303 | rc = gpio_request(tegra_host->wp_gpio, "sdhci_wp"); | ||
304 | if (rc) { | ||
305 | dev_err(mmc_dev(host->mmc), | ||
306 | "failed to allocate wp gpio\n"); | ||
307 | goto err_wp_req; | ||
308 | } | ||
309 | gpio_direction_input(tegra_host->wp_gpio); | ||
310 | } | ||
311 | |||
312 | clk = clk_get(mmc_dev(host->mmc), NULL); | 260 | clk = clk_get(mmc_dev(host->mmc), NULL); |
313 | if (IS_ERR(clk)) { | 261 | if (IS_ERR(clk)) { |
314 | dev_err(mmc_dev(host->mmc), "clk err\n"); | 262 | dev_err(mmc_dev(host->mmc), "clk err\n"); |
@@ -318,9 +266,6 @@ static int sdhci_tegra_probe(struct platform_device *pdev) | |||
318 | clk_prepare_enable(clk); | 266 | clk_prepare_enable(clk); |
319 | pltfm_host->clk = clk; | 267 | pltfm_host->clk = clk; |
320 | 268 | ||
321 | if (tegra_host->is_8bit) | ||
322 | host->mmc->caps |= MMC_CAP_8_BIT_DATA; | ||
323 | |||
324 | rc = sdhci_add_host(host); | 269 | rc = sdhci_add_host(host); |
325 | if (rc) | 270 | if (rc) |
326 | goto err_add_host; | 271 | goto err_add_host; |
@@ -331,15 +276,6 @@ err_add_host: | |||
331 | clk_disable_unprepare(pltfm_host->clk); | 276 | clk_disable_unprepare(pltfm_host->clk); |
332 | clk_put(pltfm_host->clk); | 277 | clk_put(pltfm_host->clk); |
333 | err_clk_get: | 278 | err_clk_get: |
334 | if (gpio_is_valid(tegra_host->wp_gpio)) | ||
335 | gpio_free(tegra_host->wp_gpio); | ||
336 | err_wp_req: | ||
337 | if (gpio_is_valid(tegra_host->cd_gpio)) | ||
338 | free_irq(gpio_to_irq(tegra_host->cd_gpio), host); | ||
339 | err_cd_irq_req: | ||
340 | if (gpio_is_valid(tegra_host->cd_gpio)) | ||
341 | gpio_free(tegra_host->cd_gpio); | ||
342 | err_cd_req: | ||
343 | if (gpio_is_valid(tegra_host->power_gpio)) | 279 | if (gpio_is_valid(tegra_host->power_gpio)) |
344 | gpio_free(tegra_host->power_gpio); | 280 | gpio_free(tegra_host->power_gpio); |
345 | err_power_req: | 281 | err_power_req: |
@@ -357,14 +293,6 @@ static int sdhci_tegra_remove(struct platform_device *pdev) | |||
357 | 293 | ||
358 | sdhci_remove_host(host, dead); | 294 | sdhci_remove_host(host, dead); |
359 | 295 | ||
360 | if (gpio_is_valid(tegra_host->wp_gpio)) | ||
361 | gpio_free(tegra_host->wp_gpio); | ||
362 | |||
363 | if (gpio_is_valid(tegra_host->cd_gpio)) { | ||
364 | free_irq(gpio_to_irq(tegra_host->cd_gpio), host); | ||
365 | gpio_free(tegra_host->cd_gpio); | ||
366 | } | ||
367 | |||
368 | if (gpio_is_valid(tegra_host->power_gpio)) | 296 | if (gpio_is_valid(tegra_host->power_gpio)) |
369 | gpio_free(tegra_host->power_gpio); | 297 | gpio_free(tegra_host->power_gpio); |
370 | 298 | ||