diff options
Diffstat (limited to 'drivers/gpio/gpiolib-of.c')
-rw-r--r-- | drivers/gpio/gpiolib-of.c | 140 |
1 files changed, 59 insertions, 81 deletions
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 4fff7258ee41..266352b1a966 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -23,6 +23,47 @@ #include "gpiolib.h" #include "gpiolib-of.h" +/* + * This is Linux-specific flags. By default controllers' and Linux' mapping + * match, but GPIO controllers are free to translate their own flags to + * Linux-specific in their .xlate callback. Though, 1:1 mapping is recommended. + */ +enum of_gpio_flags { + OF_GPIO_ACTIVE_LOW = 0x1, + OF_GPIO_SINGLE_ENDED = 0x2, + OF_GPIO_OPEN_DRAIN = 0x4, + OF_GPIO_TRANSITORY = 0x8, + OF_GPIO_PULL_UP = 0x10, + OF_GPIO_PULL_DOWN = 0x20, + OF_GPIO_PULL_DISABLE = 0x40, +}; + +/** + * of_gpio_named_count() - Count GPIOs for a device + * @np: device node to count GPIOs for + * @propname: property name containing gpio specifier(s) + * + * The function returns the count of GPIOs specified for a node. + * Note that the empty GPIO specifiers count too. Returns either + * Number of gpios defined in property, + * -EINVAL for an incorrectly formed gpios property, or + * -ENOENT for a missing gpios property + * + * Example: + * gpios = <0 + * &gpio1 1 2 + * 0 + * &gpio2 3 4>; + * + * The above example defines four GPIOs, two of which are not specified. + * This function will return '4' + */ +static int of_gpio_named_count(const struct device_node *np, + const char *propname) +{ + return of_count_phandle_with_args(np, propname, "#gpio-cells"); +} + /** * of_gpio_spi_cs_get_count() - special GPIO counting for SPI * @dev: Consuming device @@ -50,12 +91,6 @@ static int of_gpio_spi_cs_get_count(struct device *dev, const char *con_id) return of_gpio_named_count(np, "gpios"); } -/* - * This is used by external users of of_gpio_count() from <linux/of_gpio.h> - * - * FIXME: get rid of those external users by converting them to GPIO - * descriptors and let them all use gpiod_count() - */ int of_gpio_get_count(struct device *dev, const char *con_id) { int ret; @@ -345,19 +380,28 @@ out: return desc; } -int of_get_named_gpio_flags(const struct device_node *np, const char *list_name, - int index, enum of_gpio_flags *flags) +/** + * of_get_named_gpio() - Get a GPIO number to use with GPIO API + * @np: device node to get GPIO from + * @propname: Name of property containing gpio specifier(s) + * @index: index of the GPIO + * + * Returns GPIO number to use with Linux generic GPIO API, or one of the errno + * value on the error condition. + */ +int of_get_named_gpio(const struct device_node *np, const char *propname, + int index) { struct gpio_desc *desc; - desc = of_get_named_gpiod_flags(np, list_name, index, flags); + desc = of_get_named_gpiod_flags(np, propname, index, NULL); if (IS_ERR(desc)) return PTR_ERR(desc); else return desc_to_gpio(desc); } -EXPORT_SYMBOL_GPL(of_get_named_gpio_flags); +EXPORT_SYMBOL_GPL(of_get_named_gpio); /* Converts gpio_lookup_flags into bitmask of GPIO_* values */ static unsigned long of_convert_gpio_flags(enum of_gpio_flags flags) @@ -389,52 +433,6 @@ static unsigned long of_convert_gpio_flags(enum of_gpio_flags flags) return lflags; } -/** - * gpiod_get_from_of_node() - obtain a GPIO from an OF node - * @node: handle of the OF node - * @propname: name of the DT property representing the GPIO - * @index: index of the GPIO to obtain for the consumer - * @dflags: GPIO initialization flags - * @label: label to attach to the requested GPIO - * - * Returns: - * On successful request the GPIO pin is configured in accordance with - * provided @dflags. - * - * In case of error an ERR_PTR() is returned. - */ -struct gpio_desc *gpiod_get_from_of_node(const struct device_node *node, - const char *propname, int index, - enum gpiod_flags dflags, - const char *label) -{ - unsigned long lflags; - struct gpio_desc *desc; - enum of_gpio_flags of_flags; - int ret; - - desc = of_get_named_gpiod_flags(node, propname, index, &of_flags); - if (!desc || IS_ERR(desc)) - return desc; - - ret = gpiod_request(desc, label); - if (ret == -EBUSY && (dflags & GPIOD_FLAGS_BIT_NONEXCLUSIVE)) - return desc; - if (ret) - return ERR_PTR(ret); - - lflags = of_convert_gpio_flags(of_flags); - - ret = gpiod_configure_flags(desc, propname, lflags, dflags); - if (ret < 0) { - gpiod_put(desc); - return ERR_PTR(ret); - } - - return desc; -} -EXPORT_SYMBOL_GPL(gpiod_get_from_of_node); - static struct gpio_desc *of_find_gpio_rename(struct device_node *np, const char *con_id, unsigned int idx, @@ -668,7 +666,7 @@ static struct gpio_desc *of_parse_own_gpio(struct device_node *np, u32 tmp; int ret; - chip_np = chip->of_node; + chip_np = dev_of_node(&chip->gpiodev->dev); if (!chip_np) return ERR_PTR(-EINVAL); @@ -760,7 +758,7 @@ static int of_gpiochip_scan_gpios(struct gpio_chip *chip) struct device_node *np; int ret; - for_each_available_child_of_node(chip->of_node, np) { + for_each_available_child_of_node(dev_of_node(&chip->gpiodev->dev), np) { if (!of_property_read_bool(np, "gpio-hog")) continue; @@ -970,22 +968,18 @@ EXPORT_SYMBOL_GPL(of_mm_gpiochip_remove); #ifdef CONFIG_PINCTRL static int of_gpiochip_add_pin_range(struct gpio_chip *chip) { - struct device_node *np = chip->of_node; struct of_phandle_args pinspec; struct pinctrl_dev *pctldev; + struct device_node *np; int index = 0, ret; const char *name; static const char group_names_propname[] = "gpio-ranges-group-names"; struct property *group_names; + np = dev_of_node(&chip->gpiodev->dev); if (!np) return 0; - if (!of_property_read_bool(np, "gpio-ranges") && - chip->of_gpio_ranges_fallback) { - return chip->of_gpio_ranges_fallback(chip, np); - } - group_names = of_find_property(np, group_names_propname, NULL); for (;; index++) { @@ -1063,7 +1057,7 @@ int of_gpiochip_add(struct gpio_chip *chip) struct device_node *np; int ret; - np = to_of_node(dev_fwnode(&chip->gpiodev->dev)); + np = dev_of_node(&chip->gpiodev->dev); if (!np) return 0; @@ -1092,19 +1086,3 @@ void of_gpiochip_remove(struct gpio_chip *chip) { fwnode_handle_put(chip->fwnode); } - -void of_gpio_dev_init(struct gpio_chip *gc, struct gpio_device *gdev) -{ - /* Set default OF node to parent's one if present */ - if (gc->parent) - gdev->dev.of_node = gc->parent->of_node; - - if (gc->fwnode) - gc->of_node = to_of_node(gc->fwnode); - - /* If the gpiochip has an assigned OF node this takes precedence */ - if (gc->of_node) - gdev->dev.of_node = gc->of_node; - else - gc->of_node = gdev->dev.of_node; -} |