diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt index 18022e249c53dc1ad991d74d160551fa32f32070..8a7c45956d2412d69a26f8de991db19ed25a838f 100644 --- a/Documentation/gpio.txt +++ b/Documentation/gpio.txt @@ -264,7 +264,7 @@ map between them using calls like: /* map GPIO numbers to IRQ numbers */ int gpio_to_irq(unsigned gpio); - /* map IRQ numbers to GPIO numbers */ + /* map IRQ numbers to GPIO numbers (avoid using this) */ int irq_to_gpio(unsigned irq); Those return either the corresponding number in the other namespace, or @@ -284,7 +284,8 @@ system wakeup capabilities. Non-error values returned from irq_to_gpio() would most commonly be used with gpio_get_value(), for example to initialize or update driver state -when the IRQ is edge-triggered. +when the IRQ is edge-triggered. Note that some platforms don't support +this reverse mapping, so you should avoid using it. Emulating Open Drain Signals diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 317004fd94fbb6908e40e8f0b7482a887845ce13..29a7e6b1be5d8db915909a17164aec251ac91759 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1010,6 +1010,24 @@ int __gpio_cansleep(unsigned gpio) } EXPORT_SYMBOL_GPL(__gpio_cansleep); +/** + * __gpio_to_irq() - return the IRQ corresponding to a GPIO + * @gpio: gpio whose IRQ will be returned (already requested) + * Context: any + * + * This is used directly or indirectly to implement gpio_to_irq(). + * It returns the number of the IRQ signaled by this (input) GPIO, + * or a negative errno. + */ +int __gpio_to_irq(unsigned gpio) +{ + struct gpio_chip *chip; + + chip = gpio_to_chip(gpio); + return chip->to_irq ? chip->to_irq(chip, gpio - chip->base) : -ENXIO; +} +EXPORT_SYMBOL_GPL(__gpio_to_irq); + /* There's no value in making it easy to inline GPIO calls that may sleep. diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 2c5744b66decacac4b381f33080ab5964b03750b..04cb1d175df1782274bda4d9098d43937ae6f60c 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -40,6 +40,8 @@ struct module; * returns either the value actually sensed, or zero * @direction_output: configures signal "offset" as output, or returns error * @set: assigns output value for signal "offset" + * @to_irq: optional hook supporting non-static gpio_to_irq() mappings; + * implementation may not sleep * @dbg_show: optional routine to show contents in debugfs; default code * will be used when this is omitted, but custom code can show extra * state (such as pullup/pulldown configuration). @@ -73,6 +75,10 @@ struct gpio_chip { unsigned offset, int value); void (*set)(struct gpio_chip *chip, unsigned offset, int value); + + int (*to_irq)(struct gpio_chip *chip, + unsigned offset); + void (*dbg_show)(struct seq_file *s, struct gpio_chip *chip); int base; @@ -112,6 +118,7 @@ extern void __gpio_set_value(unsigned gpio, int value); extern int __gpio_cansleep(unsigned gpio); +extern int __gpio_to_irq(unsigned gpio); #ifdef CONFIG_GPIO_SYSFS