Commit b1b8fea9 authored by Tomasz Figa's avatar Tomasz Figa Committed by Chris Ball

mmc: host: sdhci-s3c: Use devm_gpio_request to request GPIOs

The set of GPIO pins used by sdhci-s3c driver varies between
configurations, such as card detect method, pinctrl availability, etc.
This overly complicates the code requesting and freeing GPIO pins, which
must check which pins are used, when freeing them.

This patch modifies the sdhci-s3c driver to use devm_gpio_request to
free requested pins automatically after unbinding the driver.
Signed-off-by: default avatarTomasz Figa <t.figa@samsung.com>
Acked-by: default avatarThomas Abraham <thomas.abraham@linaro.org>
Signed-off-by: default avatarChris Ball <cjb@laptop.org>
parent 3cf38833
...@@ -413,7 +413,7 @@ static void sdhci_s3c_setup_card_detect_gpio(struct sdhci_s3c *sc) ...@@ -413,7 +413,7 @@ static void sdhci_s3c_setup_card_detect_gpio(struct sdhci_s3c *sc)
struct s3c_sdhci_platdata *pdata = sc->pdata; struct s3c_sdhci_platdata *pdata = sc->pdata;
struct device *dev = &sc->pdev->dev; struct device *dev = &sc->pdev->dev;
if (gpio_request(pdata->ext_cd_gpio, "SDHCI EXT CD") == 0) { if (devm_gpio_request(dev, pdata->ext_cd_gpio, "SDHCI EXT CD") == 0) {
sc->ext_cd_gpio = pdata->ext_cd_gpio; sc->ext_cd_gpio = pdata->ext_cd_gpio;
sc->ext_cd_irq = gpio_to_irq(pdata->ext_cd_gpio); sc->ext_cd_irq = gpio_to_irq(pdata->ext_cd_gpio);
if (sc->ext_cd_irq && if (sc->ext_cd_irq &&
...@@ -494,7 +494,7 @@ static int __devinit sdhci_s3c_parse_dt(struct device *dev, ...@@ -494,7 +494,7 @@ static int __devinit sdhci_s3c_parse_dt(struct device *dev,
if (of_get_property(node, "cd-inverted", NULL)) if (of_get_property(node, "cd-inverted", NULL))
pdata->ext_cd_gpio_invert = 1; pdata->ext_cd_gpio_invert = 1;
} else if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { } else if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
ret = gpio_request(gpio, "sdhci-cd"); ret = devm_gpio_request(dev, gpio, "sdhci-cd");
if (ret) { if (ret) {
dev_err(dev, "card detect gpio request failed\n"); dev_err(dev, "card detect gpio request failed\n");
return -EINVAL; return -EINVAL;
...@@ -508,28 +508,20 @@ static int __devinit sdhci_s3c_parse_dt(struct device *dev, ...@@ -508,28 +508,20 @@ static int __devinit sdhci_s3c_parse_dt(struct device *dev,
gpio = of_get_gpio(node, cnt); gpio = of_get_gpio(node, cnt);
if (!gpio_is_valid(gpio)) { if (!gpio_is_valid(gpio)) {
dev_err(dev, "invalid gpio[%d]\n", cnt); dev_err(dev, "invalid gpio[%d]\n", cnt);
goto err_free_dt_cd_gpio; return -EINVAL;
} }
ourhost->gpios[cnt] = gpio; ourhost->gpios[cnt] = gpio;
} }
for (cnt = 0; cnt < NUM_GPIOS(pdata->max_width); cnt++) { for (cnt = 0; cnt < NUM_GPIOS(pdata->max_width); cnt++) {
ret = gpio_request(ourhost->gpios[cnt], "sdhci-gpio"); ret = devm_gpio_request(dev, ourhost->gpios[cnt], "sdhci-gpio");
if (ret) { if (ret) {
dev_err(dev, "gpio[%d] request failed\n", cnt); dev_err(dev, "gpio[%d] request failed\n", cnt);
goto err_free_dt_gpios; return -EINVAL;
} }
} }
return 0; return 0;
err_free_dt_gpios:
while (--cnt >= 0)
gpio_free(ourhost->gpios[cnt]);
err_free_dt_cd_gpio:
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL)
gpio_free(ourhost->ext_cd_gpio);
return -EINVAL;
} }
#else #else
static int __devinit sdhci_s3c_parse_dt(struct device *dev, static int __devinit sdhci_s3c_parse_dt(struct device *dev,
...@@ -586,13 +578,13 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) ...@@ -586,13 +578,13 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata) { if (!pdata) {
ret = -ENOMEM; ret = -ENOMEM;
goto err_pdata; goto err_pdata_io_clk;
} }
if (pdev->dev.of_node) { if (pdev->dev.of_node) {
ret = sdhci_s3c_parse_dt(&pdev->dev, host, pdata); ret = sdhci_s3c_parse_dt(&pdev->dev, host, pdata);
if (ret) if (ret)
goto err_pdata; goto err_pdata_io_clk;
} else { } else {
memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata)); memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata));
sc->ext_cd_gpio = -1; /* invalid gpio number */ sc->ext_cd_gpio = -1; /* invalid gpio number */
...@@ -610,7 +602,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) ...@@ -610,7 +602,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
if (IS_ERR(sc->clk_io)) { if (IS_ERR(sc->clk_io)) {
dev_err(dev, "failed to get io clock\n"); dev_err(dev, "failed to get io clock\n");
ret = PTR_ERR(sc->clk_io); ret = PTR_ERR(sc->clk_io);
goto err_io_clk; goto err_pdata_io_clk;
} }
/* enable the local io clock and keep it running for the moment. */ /* enable the local io clock and keep it running for the moment. */
...@@ -773,13 +765,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) ...@@ -773,13 +765,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
clk_disable_unprepare(sc->clk_io); clk_disable_unprepare(sc->clk_io);
clk_put(sc->clk_io); clk_put(sc->clk_io);
err_io_clk: err_pdata_io_clk:
for (ptr = 0; ptr < NUM_GPIOS(sc->pdata->max_width); ptr++)
gpio_free(sc->gpios[ptr]);
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL)
gpio_free(sc->ext_cd_gpio);
err_pdata:
sdhci_free_host(host); sdhci_free_host(host);
return ret; return ret;
...@@ -798,9 +784,6 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) ...@@ -798,9 +784,6 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
if (sc->ext_cd_irq) if (sc->ext_cd_irq)
free_irq(sc->ext_cd_irq, sc); free_irq(sc->ext_cd_irq, sc);
if (gpio_is_valid(sc->ext_cd_gpio))
gpio_free(sc->ext_cd_gpio);
#ifdef CONFIG_PM_RUNTIME #ifdef CONFIG_PM_RUNTIME
if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL) if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL)
clk_prepare_enable(sc->clk_io); clk_prepare_enable(sc->clk_io);
...@@ -821,11 +804,6 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) ...@@ -821,11 +804,6 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
clk_disable_unprepare(sc->clk_io); clk_disable_unprepare(sc->clk_io);
clk_put(sc->clk_io); clk_put(sc->clk_io);
if (pdev->dev.of_node) {
for (ptr = 0; ptr < NUM_GPIOS(sc->pdata->max_width); ptr++)
gpio_free(sc->gpios[ptr]);
}
sdhci_free_host(host); sdhci_free_host(host);
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment