[PATCH] [PATCH][GPIO] Add IRQ edge setter to gpiolib Signed-off-by:Drasko DRASKOVIC <drasko.draskovic@gmail.com>

From: Drasko DRASKOVIC
Date: Fri Oct 05 2012 - 05:59:47 EST


---
Documentation/gpio.txt | 3 ++
drivers/gpio/gpiolib.c | 70 ++++++++++++++++++++++++++++++++++++++++++++
include/asm-generic/gpio.h | 5 +++
3 files changed, 78 insertions(+), 0 deletions(-)

diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt
index e08a883..8db95e1 100644
--- a/Documentation/gpio.txt
+++ b/Documentation/gpio.txt
@@ -712,6 +712,9 @@ requested using gpio_request():
/* change the polarity of a GPIO node in sysfs */
int gpio_sysfs_set_active_low(unsigned gpio, int value);

+ /* change the irq edge of a GPIO node in sysfs */
+ gpio_sysfs_set_edge(unsigned gpio, unsigned int irq_type);
+
After a kernel driver requests a GPIO, it may only be made available in
the sysfs interface by gpio_export(). The driver can control whether the
signal direction may change. This helps drivers prevent userspace code
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 5d6c71e..9b07d67 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -820,6 +820,76 @@ EXPORT_SYMBOL_GPL(gpio_export_link);


/**
+ * gpio_sysfs_set_edge - sets irq edge type for an exported GPIO node
+ * @gpio: gpio to set-up edge to, already exported
+ * @irq_type: irq type to be set
+ *
+ * Returns zero on success, else an error.
+ */
+int gpio_sysfs_set_edge(unsigned gpio, unsigned int irq_type)
+{
+ struct gpio_desc *desc;
+ struct device *dev = NULL;
+ int status = -EINVAL;
+ unsigned long trigger_flags = 0;
+
+ if (!gpio_is_valid(gpio))
+ goto done;
+
+ mutex_lock(&sysfs_lock);
+
+ desc = &gpio_desc[gpio];
+
+ if (test_bit(FLAG_EXPORT, &desc->flags)) {
+ dev = class_find_device(&gpio_class, NULL, desc, match_export);
+ if (dev == NULL) {
+ status = -ENODEV;
+ goto unlock;
+ }
+ }
+
+ switch (irq_type) {
+ case IRQ_TYPE_NONE:
+ trigger_flags = 0;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ trigger_flags = BIT(FLAG_TRIG_FALL);
+ break;
+ case IRQ_TYPE_EDGE_RISING:
+ trigger_flags = BIT(FLAG_TRIG_RISE);
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ trigger_flags = BIT(FLAG_TRIG_FALL) | BIT(FLAG_TRIG_RISE);
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ trigger_flags = 0;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ trigger_flags = 0;
+ break;
+ default:
+ trigger_flags = 0;
+ break;
+ }
+
+ gpio_setup_irq(desc, dev, 0);
+ status = gpio_setup_irq(desc, dev, trigger_flags);
+
+unlock:
+ mutex_unlock(&sysfs_lock);
+
+done:
+ if (status)
+ pr_debug("%s: gpio%d status %d\n", __func__, gpio, status);
+
+ return status;
+}
+EXPORT_SYMBOL_GPL(gpio_sysfs_set_edge);
+
+
+
+
+/**
* gpio_sysfs_set_active_low - set the polarity of gpio sysfs value
* @gpio: gpio to change
* @value: non-zero to use active low, i.e. inverted values
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index a9432fc..4827de8 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -252,6 +252,11 @@ static inline int
gpio_sysfs_set_active_low(unsigned gpio, int value)
return -ENOSYS;
}

+static inline int gpio_sysfs_set_edge(unsigned gpio, unsigned int irq_type)
+{
+ return -ENOSYS;
+}
+
static inline void gpio_unexport(unsigned gpio)
{
}
--
1.7.6
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/