diff options
-rw-r--r-- | drivers/mmc/core/slot-gpio.c | 58 |
1 files changed, 35 insertions, 23 deletions
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c index 86547a2a82c6..47fa07e3604d 100644 --- a/drivers/mmc/core/slot-gpio.c +++ b/drivers/mmc/core/slot-gpio.c | |||
@@ -139,6 +139,39 @@ int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio) | |||
139 | } | 139 | } |
140 | EXPORT_SYMBOL(mmc_gpio_request_ro); | 140 | EXPORT_SYMBOL(mmc_gpio_request_ro); |
141 | 141 | ||
142 | static void mmc_gpiod_request_cd_irq(struct mmc_host *host) | ||
143 | { | ||
144 | struct mmc_gpio *ctx = host->slot.handler_priv; | ||
145 | int ret, irq; | ||
146 | |||
147 | if (host->slot.cd_irq >= 0 || !ctx || !ctx->cd_gpio) | ||
148 | return; | ||
149 | |||
150 | irq = gpiod_to_irq(ctx->cd_gpio); | ||
151 | |||
152 | /* | ||
153 | * Even if gpiod_to_irq() returns a valid IRQ number, the platform might | ||
154 | * still prefer to poll, e.g., because that IRQ number is already used | ||
155 | * by another unit and cannot be shared. | ||
156 | */ | ||
157 | if (irq >= 0 && host->caps & MMC_CAP_NEEDS_POLL) | ||
158 | irq = -EINVAL; | ||
159 | |||
160 | if (irq >= 0) { | ||
161 | ret = devm_request_threaded_irq(&host->class_dev, irq, | ||
162 | NULL, mmc_gpio_cd_irqt, | ||
163 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
164 | ctx->cd_label, host); | ||
165 | if (ret < 0) | ||
166 | irq = ret; | ||
167 | } | ||
168 | |||
169 | host->slot.cd_irq = irq; | ||
170 | |||
171 | if (irq < 0) | ||
172 | host->caps |= MMC_CAP_NEEDS_POLL; | ||
173 | } | ||
174 | |||
142 | /** | 175 | /** |
143 | * mmc_gpio_request_cd - request a gpio for card-detection | 176 | * mmc_gpio_request_cd - request a gpio for card-detection |
144 | * @host: mmc host | 177 | * @host: mmc host |
@@ -162,7 +195,6 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio, | |||
162 | unsigned int debounce) | 195 | unsigned int debounce) |
163 | { | 196 | { |
164 | struct mmc_gpio *ctx; | 197 | struct mmc_gpio *ctx; |
165 | int irq = gpio_to_irq(gpio); | ||
166 | int ret; | 198 | int ret; |
167 | 199 | ||
168 | ret = mmc_gpio_alloc(host); | 200 | ret = mmc_gpio_alloc(host); |
@@ -187,31 +219,11 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio, | |||
187 | return ret; | 219 | return ret; |
188 | } | 220 | } |
189 | 221 | ||
190 | /* | ||
191 | * Even if gpio_to_irq() returns a valid IRQ number, the platform might | ||
192 | * still prefer to poll, e.g., because that IRQ number is already used | ||
193 | * by another unit and cannot be shared. | ||
194 | */ | ||
195 | if (irq >= 0 && host->caps & MMC_CAP_NEEDS_POLL) | ||
196 | irq = -EINVAL; | ||
197 | |||
198 | if (irq >= 0) { | ||
199 | ret = devm_request_threaded_irq(&host->class_dev, irq, | ||
200 | NULL, mmc_gpio_cd_irqt, | ||
201 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
202 | ctx->cd_label, host); | ||
203 | if (ret < 0) | ||
204 | irq = ret; | ||
205 | } | ||
206 | |||
207 | host->slot.cd_irq = irq; | ||
208 | |||
209 | if (irq < 0) | ||
210 | host->caps |= MMC_CAP_NEEDS_POLL; | ||
211 | |||
212 | ctx->override_cd_active_level = true; | 222 | ctx->override_cd_active_level = true; |
213 | ctx->cd_gpio = gpio_to_desc(gpio); | 223 | ctx->cd_gpio = gpio_to_desc(gpio); |
214 | 224 | ||
225 | mmc_gpiod_request_cd_irq(host); | ||
226 | |||
215 | return 0; | 227 | return 0; |
216 | } | 228 | } |
217 | EXPORT_SYMBOL(mmc_gpio_request_cd); | 229 | EXPORT_SYMBOL(mmc_gpio_request_cd); |