diff options
author | Jiri Kosina <jkosina@suse.cz> | 2017-05-02 11:02:41 +0200 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2017-05-02 11:02:41 +0200 |
commit | 4d6ca227c768b50b05cf183974b40abe444e9d0c (patch) | |
tree | bf953d8e895281053548b9967a2c4b58d641df00 /drivers/gpio/gpiolib.c | |
parent | 800f3eef8ebc1264e9c135bfa892c8ae41fa4792 (diff) | |
parent | af22a610bc38508d5ea760507d31be6b6983dfa8 (diff) |
Merge branch 'for-4.12/asus' into for-linus
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r-- | drivers/gpio/gpiolib.c | 55 |
1 files changed, 30 insertions, 25 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index d0478f1853db..8b4d721d6d63 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1,3 +1,4 @@ +#include <linux/bitops.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/interrupt.h> @@ -982,7 +983,7 @@ static int gpio_chrdev_open(struct inode *inode, struct file *filp) struct gpio_device, chrdev); /* Fail on open if the backing gpiochip is gone */ - if (!gdev || !gdev->chip) + if (!gdev->chip) return -ENODEV; get_device(&gdev->dev); filp->private_data = gdev; @@ -1001,8 +1002,6 @@ static int gpio_chrdev_release(struct inode *inode, struct file *filp) struct gpio_device *gdev = container_of(inode->i_cdev, struct gpio_device, chrdev); - if (!gdev) - return -ENODEV; put_device(&gdev->dev); return 0; } @@ -1423,8 +1422,7 @@ void devm_gpiochip_remove(struct device *dev, struct gpio_chip *chip) ret = devres_release(dev, devm_gpio_chip_release, devm_gpio_chip_match, chip); - if (!ret) - WARN_ON(ret); + WARN_ON(ret); } EXPORT_SYMBOL_GPL(devm_gpiochip_remove); @@ -2586,18 +2584,11 @@ static void gpio_chip_set_multiple(struct gpio_chip *chip, if (chip->set_multiple) { chip->set_multiple(chip, mask, bits); } else { - int i; - for (i = 0; i < chip->ngpio; i++) { - if (mask[BIT_WORD(i)] == 0) { - /* no more set bits in this mask word; - * skip ahead to the next word */ - i = (BIT_WORD(i) + 1) * BITS_PER_LONG - 1; - continue; - } - /* set outputs if the corresponding mask bit is set */ - if (__test_and_clear_bit(i, mask)) - chip->set(chip, i, test_bit(i, bits)); - } + unsigned int i; + + /* set outputs if the corresponding mask bit is set */ + for_each_set_bit(i, mask, chip->ngpio) + chip->set(chip, i, test_bit(i, bits)); } } @@ -3325,6 +3316,8 @@ EXPORT_SYMBOL_GPL(gpiod_get_index); * fwnode_get_named_gpiod - obtain a GPIO from firmware node * @fwnode: handle of the firmware node * @propname: name of the firmware property representing the GPIO + * @index: index of the GPIO to obtain in the consumer + * @dflags: GPIO initialization flags * * This function can be used for drivers that get their configuration * from firmware. @@ -3333,12 +3326,18 @@ EXPORT_SYMBOL_GPL(gpiod_get_index); * underlying firmware interface and then makes sure that the GPIO * descriptor is requested before it is returned to the caller. * + * On successfull request the GPIO pin is configured in accordance with + * provided @dflags. + * * In case of error an ERR_PTR() is returned. */ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, - const char *propname) + const char *propname, int index, + enum gpiod_flags dflags, + const char *label) { struct gpio_desc *desc = ERR_PTR(-ENODEV); + unsigned long lflags = 0; bool active_low = false; bool single_ended = false; int ret; @@ -3349,8 +3348,8 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, if (is_of_node(fwnode)) { enum of_gpio_flags flags; - desc = of_get_named_gpiod_flags(to_of_node(fwnode), propname, 0, - &flags); + desc = of_get_named_gpiod_flags(to_of_node(fwnode), propname, + index, &flags); if (!IS_ERR(desc)) { active_low = flags & OF_GPIO_ACTIVE_LOW; single_ended = flags & OF_GPIO_SINGLE_ENDED; @@ -3358,7 +3357,7 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, } else if (is_acpi_node(fwnode)) { struct acpi_gpio_info info; - desc = acpi_node_get_gpiod(fwnode, propname, 0, &info); + desc = acpi_node_get_gpiod(fwnode, propname, index, &info); if (!IS_ERR(desc)) active_low = info.polarity == GPIO_ACTIVE_LOW; } @@ -3366,18 +3365,24 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, if (IS_ERR(desc)) return desc; - ret = gpiod_request(desc, NULL); + ret = gpiod_request(desc, label); if (ret) return ERR_PTR(ret); if (active_low) - set_bit(FLAG_ACTIVE_LOW, &desc->flags); + lflags |= GPIO_ACTIVE_LOW; if (single_ended) { if (active_low) - set_bit(FLAG_OPEN_DRAIN, &desc->flags); + lflags |= GPIO_OPEN_DRAIN; else - set_bit(FLAG_OPEN_SOURCE, &desc->flags); + lflags |= GPIO_OPEN_SOURCE; + } + + ret = gpiod_configure_flags(desc, propname, lflags, dflags); + if (ret < 0) { + gpiod_put(desc); + return ERR_PTR(ret); } return desc; |