gpio: Update gfp/slab.h includes for rdc321x
[safe/jmp/linux-2.6] / drivers / gpio / gpiolib.c
index bb11a42..3ca3654 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/seq_file.h>
 #include <linux/gpio.h>
 #include <linux/idr.h>
+#include <linux/slab.h>
 
 
 /* Optional implementation infrastructure for GPIO interfaces.
@@ -53,6 +54,7 @@ struct gpio_desc {
 #define FLAG_SYSFS     4       /* exported via /sys/class/gpio/control */
 #define FLAG_TRIG_FALL 5       /* trigger on falling edge */
 #define FLAG_TRIG_RISE 6       /* trigger on rising edge */
+#define FLAG_ACTIVE_LOW        7       /* sysfs value has active low */
 
 #define PDESC_ID_SHIFT 16      /* add new flags before this one */
 
@@ -210,6 +212,11 @@ static DEFINE_MUTEX(sysfs_lock);
  *      * configures behavior of poll(2) on /value
  *      * available only if pin can generate IRQs on input
  *      * is read/write as "none", "falling", "rising", or "both"
+ *   /active_low
+ *      * configures polarity of /value
+ *      * is read/write as zero/nonzero
+ *      * also affects existing and subsequent "falling" and "rising"
+ *        /edge configuration
  */
 
 static ssize_t gpio_direction_show(struct device *dev,
@@ -255,7 +262,7 @@ static ssize_t gpio_direction_store(struct device *dev,
        return status ? : size;
 }
 
-static const DEVICE_ATTR(direction, 0644,
+static /* const */ DEVICE_ATTR(direction, 0644,
                gpio_direction_show, gpio_direction_store);
 
 static ssize_t gpio_value_show(struct device *dev,
@@ -267,10 +274,17 @@ static ssize_t gpio_value_show(struct device *dev,
 
        mutex_lock(&sysfs_lock);
 
-       if (!test_bit(FLAG_EXPORT, &desc->flags))
+       if (!test_bit(FLAG_EXPORT, &desc->flags)) {
                status = -EIO;
-       else
-               status = sprintf(buf, "%d\n", !!gpio_get_value_cansleep(gpio));
+       } else {
+               int value;
+
+               value = !!gpio_get_value_cansleep(gpio);
+               if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
+                       value = !value;
+
+               status = sprintf(buf, "%d\n", value);
+       }
 
        mutex_unlock(&sysfs_lock);
        return status;
@@ -294,6 +308,8 @@ static ssize_t gpio_value_store(struct device *dev,
 
                status = strict_strtol(buf, 0, &value);
                if (status == 0) {
+                       if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
+                               value = !value;
                        gpio_set_value_cansleep(gpio, value != 0);
                        status = size;
                }
@@ -303,7 +319,7 @@ static ssize_t gpio_value_store(struct device *dev,
        return status;
 }
 
-static /*const*/ DEVICE_ATTR(value, 0644,
+static const DEVICE_ATTR(value, 0644,
                gpio_value_show, gpio_value_store);
 
 static irqreturn_t gpio_sysfs_irq(int irq, void *priv)
@@ -352,9 +368,11 @@ static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev,
 
        irq_flags = IRQF_SHARED;
        if (test_bit(FLAG_TRIG_FALL, &gpio_flags))
-               irq_flags |= IRQF_TRIGGER_FALLING;
+               irq_flags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ?
+                       IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING;
        if (test_bit(FLAG_TRIG_RISE, &gpio_flags))
-               irq_flags |= IRQF_TRIGGER_RISING;
+               irq_flags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ?
+                       IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING;
 
        if (!pdesc) {
                pdesc = kmalloc(sizeof(*pdesc), GFP_KERNEL);
@@ -381,7 +399,7 @@ static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev,
                        goto free_id;
                }
 
-               pdesc->value_sd = sysfs_get_dirent(dev->kobj.sd, "value");
+               pdesc->value_sd = sysfs_get_dirent(dev->kobj.sd, NULL, "value");
                if (!pdesc->value_sd) {
                        ret = -ENODEV;
                        goto free_id;
@@ -398,7 +416,8 @@ static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev,
        return 0;
 
 free_sd:
-       sysfs_put(pdesc->value_sd);
+       if (pdesc)
+               sysfs_put(pdesc->value_sd);
 free_id:
        idr_remove(&pdesc_idr, id);
        desc->flags &= GPIO_FLAGS_MASK;
@@ -475,9 +494,79 @@ found:
 
 static DEVICE_ATTR(edge, 0644, gpio_edge_show, gpio_edge_store);
 
+static int sysfs_set_active_low(struct gpio_desc *desc, struct device *dev,
+                               int value)
+{
+       int                     status = 0;
+
+       if (!!test_bit(FLAG_ACTIVE_LOW, &desc->flags) == !!value)
+               return 0;
+
+       if (value)
+               set_bit(FLAG_ACTIVE_LOW, &desc->flags);
+       else
+               clear_bit(FLAG_ACTIVE_LOW, &desc->flags);
+
+       /* reconfigure poll(2) support if enabled on one edge only */
+       if (dev != NULL && (!!test_bit(FLAG_TRIG_RISE, &desc->flags) ^
+                               !!test_bit(FLAG_TRIG_FALL, &desc->flags))) {
+               unsigned long trigger_flags = desc->flags & GPIO_TRIGGER_MASK;
+
+               gpio_setup_irq(desc, dev, 0);
+               status = gpio_setup_irq(desc, dev, trigger_flags);
+       }
+
+       return status;
+}
+
+static ssize_t gpio_active_low_show(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       const struct gpio_desc  *desc = dev_get_drvdata(dev);
+       ssize_t                 status;
+
+       mutex_lock(&sysfs_lock);
+
+       if (!test_bit(FLAG_EXPORT, &desc->flags))
+               status = -EIO;
+       else
+               status = sprintf(buf, "%d\n",
+                               !!test_bit(FLAG_ACTIVE_LOW, &desc->flags));
+
+       mutex_unlock(&sysfs_lock);
+
+       return status;
+}
+
+static ssize_t gpio_active_low_store(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t size)
+{
+       struct gpio_desc        *desc = dev_get_drvdata(dev);
+       ssize_t                 status;
+
+       mutex_lock(&sysfs_lock);
+
+       if (!test_bit(FLAG_EXPORT, &desc->flags)) {
+               status = -EIO;
+       } else {
+               long            value;
+
+               status = strict_strtol(buf, 0, &value);
+               if (status == 0)
+                       status = sysfs_set_active_low(desc, dev, value != 0);
+       }
+
+       mutex_unlock(&sysfs_lock);
+
+       return status ? : size;
+}
+
+static const DEVICE_ATTR(active_low, 0644,
+               gpio_active_low_show, gpio_active_low_store);
+
 static const struct attribute *gpio_attrs[] = {
-       &dev_attr_direction.attr,
        &dev_attr_value.attr,
+       &dev_attr_active_low.attr,
        NULL,
 };
 
@@ -536,7 +625,9 @@ static const struct attribute_group gpiochip_attr_group = {
  * /sys/class/gpio/unexport ... write-only
  *     integer N ... number of GPIO to unexport
  */
-static ssize_t export_store(struct class *class, const char *buf, size_t len)
+static ssize_t export_store(struct class *class,
+                               struct class_attribute *attr,
+                               const char *buf, size_t len)
 {
        long    gpio;
        int     status;
@@ -566,7 +657,9 @@ done:
        return status ? : len;
 }
 
-static ssize_t unexport_store(struct class *class, const char *buf, size_t len)
+static ssize_t unexport_store(struct class *class,
+                               struct class_attribute *attr,
+                               const char *buf, size_t len)
 {
        long    gpio;
        int     status;
@@ -629,7 +722,7 @@ int gpio_export(unsigned gpio, bool direction_may_change)
        unsigned long           flags;
        struct gpio_desc        *desc;
        int                     status = -EINVAL;
-       char                    *ioname = NULL;
+       const char              *ioname = NULL;
 
        /* can't export until sysfs is available ... */
        if (!gpio_class.p) {
@@ -660,14 +753,14 @@ int gpio_export(unsigned gpio, bool direction_may_change)
                struct device   *dev;
 
                dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0),
-                               desc, ioname ? ioname : "gpio%d", gpio);
-               if (dev) {
-                       if (direction_may_change)
-                               status = sysfs_create_group(&dev->kobj,
+                               desc, ioname ? ioname : "gpio%u", gpio);
+               if (!IS_ERR(dev)) {
+                       status = sysfs_create_group(&dev->kobj,
                                                &gpio_attr_group);
-                       else
+
+                       if (!status && direction_may_change)
                                status = device_create_file(dev,
-                                               &dev_attr_value);
+                                               &dev_attr_direction);
 
                        if (!status && gpio_to_irq(gpio) >= 0
                                        && (direction_may_change
@@ -679,7 +772,7 @@ int gpio_export(unsigned gpio, bool direction_may_change)
                        if (status != 0)
                                device_unregister(dev);
                } else
-                       status = -ENODEV;
+                       status = PTR_ERR(dev);
                if (status == 0)
                        set_bit(FLAG_EXPORT, &desc->flags);
        }
@@ -744,6 +837,53 @@ done:
 }
 EXPORT_SYMBOL_GPL(gpio_export_link);
 
+
+/**
+ * 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
+ *
+ * Set the polarity of /sys/class/gpio/gpioN/value sysfs attribute.
+ * The GPIO does not have to be exported yet.  If poll(2) support has
+ * been enabled for either rising or falling edge, it will be
+ * reconfigured to follow the new polarity.
+ *
+ * Returns zero on success, else an error.
+ */
+int gpio_sysfs_set_active_low(unsigned gpio, int value)
+{
+       struct gpio_desc        *desc;
+       struct device           *dev = NULL;
+       int                     status = -EINVAL;
+
+       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;
+               }
+       }
+
+       status = sysfs_set_active_low(desc, dev, value);
+
+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_active_low);
+
 /**
  * gpio_unexport - reverse effect of gpio_export()
  * @gpio: gpio to make unavailable
@@ -800,11 +940,11 @@ static int gpiochip_export(struct gpio_chip *chip)
        mutex_lock(&sysfs_lock);
        dev = device_create(&gpio_class, chip->dev, MKDEV(0, 0), chip,
                                "gpiochip%d", chip->base);
-       if (dev) {
+       if (!IS_ERR(dev)) {
                status = sysfs_create_group(&dev->kobj,
                                &gpiochip_attr_group);
        } else
-               status = -ENODEV;
+               status = PTR_ERR(dev);
        chip->exported = (status == 0);
        mutex_unlock(&sysfs_lock);
 
@@ -966,7 +1106,7 @@ unlock:
 fail:
        /* failures here can mean systems won't boot... */
        if (status)
-               pr_err("gpiochip_add: gpios %d..%d (%s) not registered\n",
+               pr_err("gpiochip_add: gpios %d..%d (%s) failed to register\n",
                        chip->base, chip->base + chip->ngpio - 1,
                        chip->label ? : "generic");
        return status;
@@ -1094,6 +1234,7 @@ void gpio_free(unsigned gpio)
                }
                desc_set_label(desc, NULL);
                module_put(desc->chip->owner);
+               clear_bit(FLAG_ACTIVE_LOW, &desc->flags);
                clear_bit(FLAG_REQUESTED, &desc->flags);
        } else
                WARN_ON(extra_checks);
@@ -1102,6 +1243,64 @@ void gpio_free(unsigned gpio)
 }
 EXPORT_SYMBOL_GPL(gpio_free);
 
+/**
+ * gpio_request_one - request a single GPIO with initial configuration
+ * @gpio:      the GPIO number
+ * @flags:     GPIO configuration as specified by GPIOF_*
+ * @label:     a literal description string of this GPIO
+ */
+int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
+{
+       int err;
+
+       err = gpio_request(gpio, label);
+       if (err)
+               return err;
+
+       if (flags & GPIOF_DIR_IN)
+               err = gpio_direction_input(gpio);
+       else
+               err = gpio_direction_output(gpio,
+                               (flags & GPIOF_INIT_HIGH) ? 1 : 0);
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(gpio_request_one);
+
+/**
+ * gpio_request_array - request multiple GPIOs in a single call
+ * @array:     array of the 'struct gpio'
+ * @num:       how many GPIOs in the array
+ */
+int gpio_request_array(struct gpio *array, size_t num)
+{
+       int i, err;
+
+       for (i = 0; i < num; i++, array++) {
+               err = gpio_request_one(array->gpio, array->flags, array->label);
+               if (err)
+                       goto err_free;
+       }
+       return 0;
+
+err_free:
+       while (i--)
+               gpio_free((--array)->gpio);
+       return err;
+}
+EXPORT_SYMBOL_GPL(gpio_request_array);
+
+/**
+ * gpio_free_array - release multiple GPIOs in a single call
+ * @array:     array of the 'struct gpio'
+ * @num:       how many GPIOs in the array
+ */
+void gpio_free_array(struct gpio *array, size_t num)
+{
+       while (num--)
+               gpio_free((array++)->gpio);
+}
+EXPORT_SYMBOL_GPL(gpio_free_array);
 
 /**
  * gpiochip_is_requested - return string iff signal was requested
@@ -1248,6 +1447,49 @@ fail:
 }
 EXPORT_SYMBOL_GPL(gpio_direction_output);
 
+/**
+ * gpio_set_debounce - sets @debounce time for a @gpio
+ * @gpio: the gpio to set debounce time
+ * @debounce: debounce time is microseconds
+ */
+int gpio_set_debounce(unsigned gpio, unsigned debounce)
+{
+       unsigned long           flags;
+       struct gpio_chip        *chip;
+       struct gpio_desc        *desc = &gpio_desc[gpio];
+       int                     status = -EINVAL;
+
+       spin_lock_irqsave(&gpio_lock, flags);
+
+       if (!gpio_is_valid(gpio))
+               goto fail;
+       chip = desc->chip;
+       if (!chip || !chip->set || !chip->set_debounce)
+               goto fail;
+       gpio -= chip->base;
+       if (gpio >= chip->ngpio)
+               goto fail;
+       status = gpio_ensure_requested(desc, gpio);
+       if (status < 0)
+               goto fail;
+
+       /* now we know the gpio is valid and chip won't vanish */
+
+       spin_unlock_irqrestore(&gpio_lock, flags);
+
+       might_sleep_if(extra_checks && chip->can_sleep);
+
+       return chip->set_debounce(chip, gpio, debounce);
+
+fail:
+       spin_unlock_irqrestore(&gpio_lock, flags);
+       if (status)
+               pr_debug("%s: gpio-%d status %d\n",
+                       __func__, gpio, status);
+
+       return status;
+}
+EXPORT_SYMBOL_GPL(gpio_set_debounce);
 
 /* I/O calls are only valid after configuration completed; the relevant
  * "is this a valid GPIO" error checks should already have been done.
@@ -1487,7 +1729,7 @@ static int gpiolib_open(struct inode *inode, struct file *file)
        return single_open(file, gpiolib_show, NULL);
 }
 
-static struct file_operations gpiolib_operations = {
+static const struct file_operations gpiolib_operations = {
        .open           = gpiolib_open,
        .read           = seq_read,
        .llseek         = seq_lseek,