Commit 0f6d504e authored by David Brownell's avatar David Brownell Committed by Linus Torvalds

gpiolib: gpio_to_irq() hooks

Add a new gpiolib mechanism: gpio_chip instances can provide mappings
between their (input) GPIOs and any associated IRQs.  This makes it easier
for platforms to support IRQs that are provided by board-specific external
chips instead of as part of their core (such as SOC-integrated GPIOs).

Also update the irq_to_gpio() description, saying to avoid it because it's
not always supported.
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 2f8d1197
...@@ -264,7 +264,7 @@ map between them using calls like: ...@@ -264,7 +264,7 @@ map between them using calls like:
/* map GPIO numbers to IRQ numbers */ /* map GPIO numbers to IRQ numbers */
int gpio_to_irq(unsigned gpio); 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); int irq_to_gpio(unsigned irq);
Those return either the corresponding number in the other namespace, or Those return either the corresponding number in the other namespace, or
...@@ -284,7 +284,8 @@ system wakeup capabilities. ...@@ -284,7 +284,8 @@ system wakeup capabilities.
Non-error values returned from irq_to_gpio() would most commonly be used 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 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 Emulating Open Drain Signals
......
...@@ -1010,6 +1010,24 @@ int __gpio_cansleep(unsigned gpio) ...@@ -1010,6 +1010,24 @@ int __gpio_cansleep(unsigned gpio)
} }
EXPORT_SYMBOL_GPL(__gpio_cansleep); 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. /* There's no value in making it easy to inline GPIO calls that may sleep.
......
...@@ -40,6 +40,8 @@ struct module; ...@@ -40,6 +40,8 @@ struct module;
* returns either the value actually sensed, or zero * returns either the value actually sensed, or zero
* @direction_output: configures signal "offset" as output, or returns error * @direction_output: configures signal "offset" as output, or returns error
* @set: assigns output value for signal "offset" * @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 * @dbg_show: optional routine to show contents in debugfs; default code
* will be used when this is omitted, but custom code can show extra * will be used when this is omitted, but custom code can show extra
* state (such as pullup/pulldown configuration). * state (such as pullup/pulldown configuration).
...@@ -73,6 +75,10 @@ struct gpio_chip { ...@@ -73,6 +75,10 @@ struct gpio_chip {
unsigned offset, int value); unsigned offset, int value);
void (*set)(struct gpio_chip *chip, void (*set)(struct gpio_chip *chip,
unsigned offset, int value); unsigned offset, int value);
int (*to_irq)(struct gpio_chip *chip,
unsigned offset);
void (*dbg_show)(struct seq_file *s, void (*dbg_show)(struct seq_file *s,
struct gpio_chip *chip); struct gpio_chip *chip);
int base; int base;
...@@ -112,6 +118,7 @@ extern void __gpio_set_value(unsigned gpio, int value); ...@@ -112,6 +118,7 @@ extern void __gpio_set_value(unsigned gpio, int value);
extern int __gpio_cansleep(unsigned gpio); extern int __gpio_cansleep(unsigned gpio);
extern int __gpio_to_irq(unsigned gpio);
#ifdef CONFIG_GPIO_SYSFS #ifdef CONFIG_GPIO_SYSFS
......
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