Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mmc: sdhci-dove: use mmc_of_parse() and remove card_tasklet CD handler

f8ec589b86f6 ("mmc: sdhci-dove: allow GPIOs to be used for card detection
on Dove" added a gpio based card detect interrupt handler that was hooked
up into card_tasket.

3560db8e247a ("mmc: sdhci: push card_tasklet into threaded irq handler")
now removed that very card_tasklet causing sdhci-dove to fail on build
with:
drivers/mmc/host/sdhci-dove.c: In function 'sdhci_dove_carddetect_irq':
drivers/mmc/host/sdhci-dove.c:42:24: error: 'struct sdhci_host' has no member named 'card_tasklet'

To fix both the build error and get a working gpio card detection without
card_tasklet, replace sdhci_get_of_property() with more recent
mmc_of_parse(). It takes care of gpio-based card detect passed through DT
already and allows to remove the offending code sections dealing with
removed card_tasklet.

Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Chris Ball <chris@printf.net>

authored by

Sebastian Hesselbarth and committed by
Chris Ball
c5ee2490 708dce3f

+5 -69
+5 -69
drivers/mmc/host/sdhci-dove.c
··· 21 21 22 22 #include <linux/clk.h> 23 23 #include <linux/err.h> 24 - #include <linux/gpio.h> 25 24 #include <linux/io.h> 26 25 #include <linux/mmc/host.h> 27 26 #include <linux/module.h> 28 27 #include <linux/of.h> 29 - #include <linux/of_gpio.h> 30 28 31 29 #include "sdhci-pltfm.h" 32 30 33 31 struct sdhci_dove_priv { 34 32 struct clk *clk; 35 - int gpio_cd; 36 33 }; 37 - 38 - static irqreturn_t sdhci_dove_carddetect_irq(int irq, void *data) 39 - { 40 - struct sdhci_host *host = data; 41 - 42 - tasklet_schedule(&host->card_tasklet); 43 - return IRQ_HANDLED; 44 - } 45 34 46 35 static u16 sdhci_dove_readw(struct sdhci_host *host, int reg) 47 36 { ··· 49 60 50 61 static u32 sdhci_dove_readl(struct sdhci_host *host, int reg) 51 62 { 52 - struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 53 - struct sdhci_dove_priv *priv = pltfm_host->priv; 54 63 u32 ret; 55 64 56 65 ret = readl(host->ioaddr + reg); ··· 57 70 case SDHCI_CAPABILITIES: 58 71 /* Mask the support for 3.0V */ 59 72 ret &= ~SDHCI_CAN_VDD_300; 60 - break; 61 - case SDHCI_PRESENT_STATE: 62 - if (gpio_is_valid(priv->gpio_cd)) { 63 - if (gpio_get_value(priv->gpio_cd) == 0) 64 - ret |= SDHCI_CARD_PRESENT; 65 - else 66 - ret &= ~SDHCI_CARD_PRESENT; 67 - } 68 73 break; 69 74 } 70 75 return ret; ··· 96 117 97 118 priv->clk = devm_clk_get(&pdev->dev, NULL); 98 119 99 - if (pdev->dev.of_node) { 100 - priv->gpio_cd = of_get_named_gpio(pdev->dev.of_node, 101 - "cd-gpios", 0); 102 - } else { 103 - priv->gpio_cd = -EINVAL; 104 - } 105 - 106 - if (gpio_is_valid(priv->gpio_cd)) { 107 - ret = gpio_request(priv->gpio_cd, "sdhci-cd"); 108 - if (ret) { 109 - dev_err(&pdev->dev, "card detect gpio request failed: %d\n", 110 - ret); 111 - return ret; 112 - } 113 - gpio_direction_input(priv->gpio_cd); 114 - } 115 - 116 120 host = sdhci_pltfm_init(pdev, &sdhci_dove_pdata, 0); 117 - if (IS_ERR(host)) { 118 - ret = PTR_ERR(host); 119 - goto err_sdhci_pltfm_init; 120 - } 121 + if (IS_ERR(host)) 122 + return PTR_ERR(host); 121 123 122 124 pltfm_host = sdhci_priv(host); 123 125 pltfm_host->priv = priv; ··· 106 146 if (!IS_ERR(priv->clk)) 107 147 clk_prepare_enable(priv->clk); 108 148 109 - sdhci_get_of_property(pdev); 149 + ret = mmc_of_parse(host->mmc); 150 + if (ret) 151 + goto err_sdhci_add; 110 152 111 153 ret = sdhci_add_host(host); 112 154 if (ret) 113 155 goto err_sdhci_add; 114 156 115 - /* 116 - * We must request the IRQ after sdhci_add_host(), as the tasklet only 117 - * gets setup in sdhci_add_host() and we oops. 118 - */ 119 - if (gpio_is_valid(priv->gpio_cd)) { 120 - ret = request_irq(gpio_to_irq(priv->gpio_cd), 121 - sdhci_dove_carddetect_irq, 122 - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, 123 - mmc_hostname(host->mmc), host); 124 - if (ret) { 125 - dev_err(&pdev->dev, "card detect irq request failed: %d\n", 126 - ret); 127 - goto err_request_irq; 128 - } 129 - } 130 - 131 157 return 0; 132 158 133 - err_request_irq: 134 - sdhci_remove_host(host, 0); 135 159 err_sdhci_add: 136 160 if (!IS_ERR(priv->clk)) 137 161 clk_disable_unprepare(priv->clk); 138 162 sdhci_pltfm_free(pdev); 139 - err_sdhci_pltfm_init: 140 - if (gpio_is_valid(priv->gpio_cd)) 141 - gpio_free(priv->gpio_cd); 142 163 return ret; 143 164 } 144 165 ··· 130 189 struct sdhci_dove_priv *priv = pltfm_host->priv; 131 190 132 191 sdhci_pltfm_unregister(pdev); 133 - 134 - if (gpio_is_valid(priv->gpio_cd)) { 135 - free_irq(gpio_to_irq(priv->gpio_cd), host); 136 - gpio_free(priv->gpio_cd); 137 - } 138 192 139 193 if (!IS_ERR(priv->clk)) 140 194 clk_disable_unprepare(priv->clk);