perf tools: Don't clone maps from parent when synthesizing forks
[linux/fpc-iii.git] / drivers / mmc / core / slot-gpio.c
blob86803a3a04dc9609a0c55de2df03f3a9e8cb1341
1 /*
2 * Generic GPIO card-detect helper
4 * Copyright (C) 2011, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
11 #include <linux/err.h>
12 #include <linux/gpio.h>
13 #include <linux/gpio/consumer.h>
14 #include <linux/interrupt.h>
15 #include <linux/jiffies.h>
16 #include <linux/mmc/host.h>
17 #include <linux/mmc/slot-gpio.h>
18 #include <linux/module.h>
19 #include <linux/slab.h>
21 #include "slot-gpio.h"
23 struct mmc_gpio {
24 struct gpio_desc *ro_gpio;
25 struct gpio_desc *cd_gpio;
26 bool override_ro_active_level;
27 bool override_cd_active_level;
28 irqreturn_t (*cd_gpio_isr)(int irq, void *dev_id);
29 char *ro_label;
30 u32 cd_debounce_delay_ms;
31 char cd_label[];
34 static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
36 /* Schedule a card detection after a debounce timeout */
37 struct mmc_host *host = dev_id;
38 struct mmc_gpio *ctx = host->slot.handler_priv;
40 host->trigger_card_event = true;
41 mmc_detect_change(host, msecs_to_jiffies(ctx->cd_debounce_delay_ms));
43 return IRQ_HANDLED;
46 int mmc_gpio_alloc(struct mmc_host *host)
48 size_t len = strlen(dev_name(host->parent)) + 4;
49 struct mmc_gpio *ctx = devm_kzalloc(host->parent,
50 sizeof(*ctx) + 2 * len, GFP_KERNEL);
52 if (ctx) {
53 ctx->ro_label = ctx->cd_label + len;
54 ctx->cd_debounce_delay_ms = 200;
55 snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent));
56 snprintf(ctx->ro_label, len, "%s ro", dev_name(host->parent));
57 host->slot.handler_priv = ctx;
58 host->slot.cd_irq = -EINVAL;
61 return ctx ? 0 : -ENOMEM;
64 int mmc_gpio_get_ro(struct mmc_host *host)
66 struct mmc_gpio *ctx = host->slot.handler_priv;
68 if (!ctx || !ctx->ro_gpio)
69 return -ENOSYS;
71 if (ctx->override_ro_active_level)
72 return !gpiod_get_raw_value_cansleep(ctx->ro_gpio) ^
73 !!(host->caps2 & MMC_CAP2_RO_ACTIVE_HIGH);
75 return gpiod_get_value_cansleep(ctx->ro_gpio);
77 EXPORT_SYMBOL(mmc_gpio_get_ro);
79 int mmc_gpio_get_cd(struct mmc_host *host)
81 struct mmc_gpio *ctx = host->slot.handler_priv;
82 int cansleep;
84 if (!ctx || !ctx->cd_gpio)
85 return -ENOSYS;
87 cansleep = gpiod_cansleep(ctx->cd_gpio);
88 if (ctx->override_cd_active_level) {
89 int value = cansleep ?
90 gpiod_get_raw_value_cansleep(ctx->cd_gpio) :
91 gpiod_get_raw_value(ctx->cd_gpio);
92 return !value ^ !!(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH);
95 return cansleep ?
96 gpiod_get_value_cansleep(ctx->cd_gpio) :
97 gpiod_get_value(ctx->cd_gpio);
99 EXPORT_SYMBOL(mmc_gpio_get_cd);
102 * mmc_gpio_request_ro - request a gpio for write-protection
103 * @host: mmc host
104 * @gpio: gpio number requested
106 * As devm_* managed functions are used in mmc_gpio_request_ro(), client
107 * drivers do not need to worry about freeing up memory.
109 * Returns zero on success, else an error.
111 int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio)
113 struct mmc_gpio *ctx = host->slot.handler_priv;
114 int ret;
116 if (!gpio_is_valid(gpio))
117 return -EINVAL;
119 ret = devm_gpio_request_one(host->parent, gpio, GPIOF_DIR_IN,
120 ctx->ro_label);
121 if (ret < 0)
122 return ret;
124 ctx->override_ro_active_level = true;
125 ctx->ro_gpio = gpio_to_desc(gpio);
127 return 0;
129 EXPORT_SYMBOL(mmc_gpio_request_ro);
131 void mmc_gpiod_request_cd_irq(struct mmc_host *host)
133 struct mmc_gpio *ctx = host->slot.handler_priv;
134 int irq = -EINVAL;
135 int ret;
137 if (host->slot.cd_irq >= 0 || !ctx || !ctx->cd_gpio)
138 return;
141 * Do not use IRQ if the platform prefers to poll, e.g., because that
142 * IRQ number is already used by another unit and cannot be shared.
144 if (!(host->caps & MMC_CAP_NEEDS_POLL))
145 irq = gpiod_to_irq(ctx->cd_gpio);
147 if (irq >= 0) {
148 if (!ctx->cd_gpio_isr)
149 ctx->cd_gpio_isr = mmc_gpio_cd_irqt;
150 ret = devm_request_threaded_irq(host->parent, irq,
151 NULL, ctx->cd_gpio_isr,
152 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
153 ctx->cd_label, host);
154 if (ret < 0)
155 irq = ret;
158 host->slot.cd_irq = irq;
160 if (irq < 0)
161 host->caps |= MMC_CAP_NEEDS_POLL;
163 EXPORT_SYMBOL(mmc_gpiod_request_cd_irq);
165 int mmc_gpio_set_cd_wake(struct mmc_host *host, bool on)
167 int ret = 0;
169 if (!(host->caps & MMC_CAP_CD_WAKE) ||
170 host->slot.cd_irq < 0 ||
171 on == host->slot.cd_wake_enabled)
172 return 0;
174 if (on) {
175 ret = enable_irq_wake(host->slot.cd_irq);
176 host->slot.cd_wake_enabled = !ret;
177 } else {
178 disable_irq_wake(host->slot.cd_irq);
179 host->slot.cd_wake_enabled = false;
182 return ret;
184 EXPORT_SYMBOL(mmc_gpio_set_cd_wake);
186 /* Register an alternate interrupt service routine for
187 * the card-detect GPIO.
189 void mmc_gpio_set_cd_isr(struct mmc_host *host,
190 irqreturn_t (*isr)(int irq, void *dev_id))
192 struct mmc_gpio *ctx = host->slot.handler_priv;
194 WARN_ON(ctx->cd_gpio_isr);
195 ctx->cd_gpio_isr = isr;
197 EXPORT_SYMBOL(mmc_gpio_set_cd_isr);
200 * mmc_gpio_request_cd - request a gpio for card-detection
201 * @host: mmc host
202 * @gpio: gpio number requested
203 * @debounce: debounce time in microseconds
205 * As devm_* managed functions are used in mmc_gpio_request_cd(), client
206 * drivers do not need to worry about freeing up memory.
208 * If GPIO debouncing is desired, set the debounce parameter to a non-zero
209 * value. The caller is responsible for ensuring that the GPIO driver associated
210 * with the GPIO supports debouncing, otherwise an error will be returned.
212 * Returns zero on success, else an error.
214 int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio,
215 unsigned int debounce)
217 struct mmc_gpio *ctx = host->slot.handler_priv;
218 int ret;
220 ret = devm_gpio_request_one(host->parent, gpio, GPIOF_DIR_IN,
221 ctx->cd_label);
222 if (ret < 0)
224 * don't bother freeing memory. It might still get used by other
225 * slot functions, in any case it will be freed, when the device
226 * is destroyed.
228 return ret;
230 if (debounce) {
231 ret = gpio_set_debounce(gpio, debounce);
232 if (ret < 0)
233 return ret;
236 ctx->override_cd_active_level = true;
237 ctx->cd_gpio = gpio_to_desc(gpio);
239 return 0;
241 EXPORT_SYMBOL(mmc_gpio_request_cd);
244 * mmc_gpiod_request_cd - request a gpio descriptor for card-detection
245 * @host: mmc host
246 * @con_id: function within the GPIO consumer
247 * @idx: index of the GPIO to obtain in the consumer
248 * @override_active_level: ignore %GPIO_ACTIVE_LOW flag
249 * @debounce: debounce time in microseconds
250 * @gpio_invert: will return whether the GPIO line is inverted or not, set
251 * to NULL to ignore
253 * Use this function in place of mmc_gpio_request_cd() to use the GPIO
254 * descriptor API. Note that it must be called prior to mmc_add_host()
255 * otherwise the caller must also call mmc_gpiod_request_cd_irq().
257 * Returns zero on success, else an error.
259 int mmc_gpiod_request_cd(struct mmc_host *host, const char *con_id,
260 unsigned int idx, bool override_active_level,
261 unsigned int debounce, bool *gpio_invert)
263 struct mmc_gpio *ctx = host->slot.handler_priv;
264 struct gpio_desc *desc;
265 int ret;
267 desc = devm_gpiod_get_index(host->parent, con_id, idx, GPIOD_IN);
268 if (IS_ERR(desc))
269 return PTR_ERR(desc);
271 if (debounce) {
272 ret = gpiod_set_debounce(desc, debounce);
273 if (ret < 0)
274 ctx->cd_debounce_delay_ms = debounce / 1000;
277 if (gpio_invert)
278 *gpio_invert = !gpiod_is_active_low(desc);
280 ctx->override_cd_active_level = override_active_level;
281 ctx->cd_gpio = desc;
283 return 0;
285 EXPORT_SYMBOL(mmc_gpiod_request_cd);
287 bool mmc_can_gpio_cd(struct mmc_host *host)
289 struct mmc_gpio *ctx = host->slot.handler_priv;
291 return ctx->cd_gpio ? true : false;
293 EXPORT_SYMBOL(mmc_can_gpio_cd);
296 * mmc_gpiod_request_ro - request a gpio descriptor for write protection
297 * @host: mmc host
298 * @con_id: function within the GPIO consumer
299 * @idx: index of the GPIO to obtain in the consumer
300 * @override_active_level: ignore %GPIO_ACTIVE_LOW flag
301 * @debounce: debounce time in microseconds
302 * @gpio_invert: will return whether the GPIO line is inverted or not,
303 * set to NULL to ignore
305 * Use this function in place of mmc_gpio_request_ro() to use the GPIO
306 * descriptor API.
308 * Returns zero on success, else an error.
310 int mmc_gpiod_request_ro(struct mmc_host *host, const char *con_id,
311 unsigned int idx, bool override_active_level,
312 unsigned int debounce, bool *gpio_invert)
314 struct mmc_gpio *ctx = host->slot.handler_priv;
315 struct gpio_desc *desc;
316 int ret;
318 desc = devm_gpiod_get_index(host->parent, con_id, idx, GPIOD_IN);
319 if (IS_ERR(desc))
320 return PTR_ERR(desc);
322 if (debounce) {
323 ret = gpiod_set_debounce(desc, debounce);
324 if (ret < 0)
325 return ret;
328 if (gpio_invert)
329 *gpio_invert = !gpiod_is_active_low(desc);
331 ctx->override_ro_active_level = override_active_level;
332 ctx->ro_gpio = desc;
334 return 0;
336 EXPORT_SYMBOL(mmc_gpiod_request_ro);
338 bool mmc_can_gpio_ro(struct mmc_host *host)
340 struct mmc_gpio *ctx = host->slot.handler_priv;
342 return ctx->ro_gpio ? true : false;
344 EXPORT_SYMBOL(mmc_can_gpio_ro);