diff options
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r-- | drivers/gpio/gpiolib.c | 247 |
1 files changed, 130 insertions, 117 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index a93d2a9355e2..9952e412da50 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -127,10 +127,10 @@ const char *gpiod_get_label(struct gpio_desc *desc) label = srcu_dereference_check(desc->label, &desc->gdev->desc_srcu, srcu_read_lock_held(&desc->gdev->desc_srcu)); - if (test_bit(FLAG_USED_AS_IRQ, &flags)) + if (test_bit(GPIOD_FLAG_USED_AS_IRQ, &flags)) return label ? label->str : "interrupt"; - if (!test_bit(FLAG_REQUESTED, &flags)) + if (!test_bit(GPIOD_FLAG_REQUESTED, &flags)) return NULL; return label ? label->str : NULL; @@ -450,8 +450,8 @@ int gpiod_get_direction(struct gpio_desc *desc) * Open drain emulation using input mode may incorrectly report * input here, fix that up. */ - if (test_bit(FLAG_OPEN_DRAIN, &flags) && - test_bit(FLAG_IS_OUT, &flags)) + if (test_bit(GPIOD_FLAG_OPEN_DRAIN, &flags) && + test_bit(GPIOD_FLAG_IS_OUT, &flags)) return 0; if (!guard.gc->get_direction) @@ -468,7 +468,7 @@ int gpiod_get_direction(struct gpio_desc *desc) if (ret > 0) ret = 1; - assign_bit(FLAG_IS_OUT, &flags, !ret); + assign_bit(GPIOD_FLAG_IS_OUT, &flags, !ret); WRITE_ONCE(desc->flags, flags); return ret; @@ -846,7 +846,7 @@ static void gpiochip_free_remaining_irqs(struct gpio_chip *gc) { struct gpio_desc *desc; - for_each_gpio_desc_with_flag(gc, desc, FLAG_USED_AS_IRQ) + for_each_gpio_desc_with_flag(gc, desc, GPIOD_FLAG_USED_AS_IRQ) gpiod_free_irqs(desc); } @@ -1037,11 +1037,6 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, int base = 0; int ret; - /* Only allow one set() and one set_multiple(). */ - if ((gc->set && gc->set_rv) || - (gc->set_multiple && gc->set_multiple_rv)) - return -EINVAL; - /* * First: allocate and populate the internal stat container, and * set up the struct device. @@ -1174,10 +1169,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, * lock here. */ if (gc->get_direction && gpiochip_line_is_valid(gc, desc_index)) - assign_bit(FLAG_IS_OUT, &desc->flags, + assign_bit(GPIOD_FLAG_IS_OUT, &desc->flags, !gc->get_direction(gc, desc_index)); else - assign_bit(FLAG_IS_OUT, + assign_bit(GPIOD_FLAG_IS_OUT, &desc->flags, !gc->direction_input); } @@ -2354,11 +2349,13 @@ int gpiochip_add_pingroup_range(struct gpio_chip *gc, EXPORT_SYMBOL_GPL(gpiochip_add_pingroup_range); /** - * gpiochip_add_pin_range() - add a range for GPIO <-> pin mapping + * gpiochip_add_pin_range_with_pins() - add a range for GPIO <-> pin mapping * @gc: the gpiochip to add the range for * @pinctl_name: the dev_name() of the pin controller to map to * @gpio_offset: the start offset in the current gpio_chip number space * @pin_offset: the start offset in the pin controller number space + * @pins: the list of non consecutive pins to accumulate in this range (if not + * NULL, pin_offset is ignored by pinctrl core) * @npins: the number of pins from the offset of each pin space (GPIO and * pin controller) to accumulate in this range * @@ -2370,9 +2367,12 @@ EXPORT_SYMBOL_GPL(gpiochip_add_pingroup_range); * Returns: * 0 on success, or a negative errno on failure. */ -int gpiochip_add_pin_range(struct gpio_chip *gc, const char *pinctl_name, - unsigned int gpio_offset, unsigned int pin_offset, - unsigned int npins) +int gpiochip_add_pin_range_with_pins(struct gpio_chip *gc, + const char *pinctl_name, + unsigned int gpio_offset, + unsigned int pin_offset, + unsigned int const *pins, + unsigned int npins) { struct gpio_pin_range *pin_range; struct gpio_device *gdev = gc->gpiodev; @@ -2390,6 +2390,7 @@ int gpiochip_add_pin_range(struct gpio_chip *gc, const char *pinctl_name, pin_range->range.name = gc->label; pin_range->range.base = gdev->base + gpio_offset; pin_range->range.pin_base = pin_offset; + pin_range->range.pins = pins; pin_range->range.npins = npins; pin_range->pctldev = pinctrl_find_and_add_gpio_range(pinctl_name, &pin_range->range); @@ -2399,16 +2400,21 @@ int gpiochip_add_pin_range(struct gpio_chip *gc, const char *pinctl_name, kfree(pin_range); return ret; } - chip_dbg(gc, "created GPIO range %d->%d ==> %s PIN %d->%d\n", - gpio_offset, gpio_offset + npins - 1, - pinctl_name, - pin_offset, pin_offset + npins - 1); + if (pin_range->range.pins) + chip_dbg(gc, "created GPIO range %d->%d ==> %s %d sparse PIN range { %d, ... }", + gpio_offset, gpio_offset + npins - 1, + pinctl_name, npins, pins[0]); + else + chip_dbg(gc, "created GPIO range %d->%d ==> %s PIN %d->%d\n", + gpio_offset, gpio_offset + npins - 1, + pinctl_name, + pin_offset, pin_offset + npins - 1); list_add_tail(&pin_range->node, &gdev->pin_ranges); return 0; } -EXPORT_SYMBOL_GPL(gpiochip_add_pin_range); +EXPORT_SYMBOL_GPL(gpiochip_add_pin_range_with_pins); /** * gpiochip_remove_pin_ranges() - remove all the GPIO <-> pin mappings @@ -2443,7 +2449,7 @@ static int gpiod_request_commit(struct gpio_desc *desc, const char *label) if (!guard.gc) return -ENODEV; - if (test_and_set_bit(FLAG_REQUESTED, &desc->flags)) + if (test_and_set_bit(GPIOD_FLAG_REQUESTED, &desc->flags)) return -EBUSY; offset = gpio_chip_hwgpio(desc); @@ -2472,7 +2478,7 @@ static int gpiod_request_commit(struct gpio_desc *desc, const char *label) return 0; out_clear_bit: - clear_bit(FLAG_REQUESTED, &desc->flags); + clear_bit(GPIOD_FLAG_REQUESTED, &desc->flags); return ret; } @@ -2506,20 +2512,20 @@ static void gpiod_free_commit(struct gpio_desc *desc) flags = READ_ONCE(desc->flags); - if (guard.gc && test_bit(FLAG_REQUESTED, &flags)) { + if (guard.gc && test_bit(GPIOD_FLAG_REQUESTED, &flags)) { if (guard.gc->free) guard.gc->free(guard.gc, gpio_chip_hwgpio(desc)); - clear_bit(FLAG_ACTIVE_LOW, &flags); - clear_bit(FLAG_REQUESTED, &flags); - clear_bit(FLAG_OPEN_DRAIN, &flags); - clear_bit(FLAG_OPEN_SOURCE, &flags); - clear_bit(FLAG_PULL_UP, &flags); - clear_bit(FLAG_PULL_DOWN, &flags); - clear_bit(FLAG_BIAS_DISABLE, &flags); - clear_bit(FLAG_EDGE_RISING, &flags); - clear_bit(FLAG_EDGE_FALLING, &flags); - clear_bit(FLAG_IS_HOGGED, &flags); + clear_bit(GPIOD_FLAG_ACTIVE_LOW, &flags); + clear_bit(GPIOD_FLAG_REQUESTED, &flags); + clear_bit(GPIOD_FLAG_OPEN_DRAIN, &flags); + clear_bit(GPIOD_FLAG_OPEN_SOURCE, &flags); + clear_bit(GPIOD_FLAG_PULL_UP, &flags); + clear_bit(GPIOD_FLAG_PULL_DOWN, &flags); + clear_bit(GPIOD_FLAG_BIAS_DISABLE, &flags); + clear_bit(GPIOD_FLAG_EDGE_RISING, &flags); + clear_bit(GPIOD_FLAG_EDGE_FALLING, &flags); + clear_bit(GPIOD_FLAG_IS_HOGGED, &flags); #ifdef CONFIG_OF_DYNAMIC WRITE_ONCE(desc->hog, NULL); #endif @@ -2562,7 +2568,7 @@ char *gpiochip_dup_line_label(struct gpio_chip *gc, unsigned int offset) if (IS_ERR(desc)) return NULL; - if (!test_bit(FLAG_REQUESTED, &desc->flags)) + if (!test_bit(GPIOD_FLAG_REQUESTED, &desc->flags)) return NULL; guard(srcu)(&desc->gdev->desc_srcu); @@ -2730,11 +2736,11 @@ static int gpio_set_bias(struct gpio_desc *desc) flags = READ_ONCE(desc->flags); - if (test_bit(FLAG_BIAS_DISABLE, &flags)) + if (test_bit(GPIOD_FLAG_BIAS_DISABLE, &flags)) bias = PIN_CONFIG_BIAS_DISABLE; - else if (test_bit(FLAG_PULL_UP, &flags)) + else if (test_bit(GPIOD_FLAG_PULL_UP, &flags)) bias = PIN_CONFIG_BIAS_PULL_UP; - else if (test_bit(FLAG_PULL_DOWN, &flags)) + else if (test_bit(GPIOD_FLAG_PULL_DOWN, &flags)) bias = PIN_CONFIG_BIAS_PULL_DOWN; else return 0; @@ -2876,7 +2882,7 @@ int gpiod_direction_input_nonotify(struct gpio_desc *desc) } } if (ret == 0) { - clear_bit(FLAG_IS_OUT, &desc->flags); + clear_bit(GPIOD_FLAG_IS_OUT, &desc->flags); ret = gpio_set_bias(desc); } @@ -2891,19 +2897,14 @@ static int gpiochip_set(struct gpio_chip *gc, unsigned int offset, int value) lockdep_assert_held(&gc->gpiodev->srcu); - if (WARN_ON(unlikely(!gc->set && !gc->set_rv))) + if (WARN_ON(unlikely(!gc->set))) return -EOPNOTSUPP; - if (gc->set_rv) { - ret = gc->set_rv(gc, offset, value); - if (ret > 0) - ret = -EBADE; - - return ret; - } + ret = gc->set(gc, offset, value); + if (ret > 0) + ret = -EBADE; - gc->set(gc, offset, value); - return 0; + return ret; } static int gpiod_direction_output_raw_commit(struct gpio_desc *desc, int value) @@ -2919,7 +2920,7 @@ static int gpiod_direction_output_raw_commit(struct gpio_desc *desc, int value) * output-only, but if there is then not even a .set() operation it * is pretty tricky to drive the output line. */ - if (!guard.gc->set && !guard.gc->set_rv && !guard.gc->direction_output) { + if (!guard.gc->set && !guard.gc->direction_output) { gpiod_warn(desc, "%s: missing set() and direction_output() operations\n", __func__); @@ -2954,7 +2955,7 @@ static int gpiod_direction_output_raw_commit(struct gpio_desc *desc, int value) } if (!ret) - set_bit(FLAG_IS_OUT, &desc->flags); + set_bit(GPIOD_FLAG_IS_OUT, &desc->flags); trace_gpio_value(desc_to_gpio(desc), 0, val); trace_gpio_direction(desc_to_gpio(desc), 0, ret); return ret; @@ -3020,21 +3021,21 @@ int gpiod_direction_output_nonotify(struct gpio_desc *desc, int value) flags = READ_ONCE(desc->flags); - if (test_bit(FLAG_ACTIVE_LOW, &flags)) + if (test_bit(GPIOD_FLAG_ACTIVE_LOW, &flags)) value = !value; else value = !!value; /* GPIOs used for enabled IRQs shall not be set as output */ - if (test_bit(FLAG_USED_AS_IRQ, &flags) && - test_bit(FLAG_IRQ_IS_ENABLED, &flags)) { + if (test_bit(GPIOD_FLAG_USED_AS_IRQ, &flags) && + test_bit(GPIOD_FLAG_IRQ_IS_ENABLED, &flags)) { gpiod_err(desc, "%s: tried to set a GPIO tied to an IRQ as output\n", __func__); return -EIO; } - if (test_bit(FLAG_OPEN_DRAIN, &flags)) { + if (test_bit(GPIOD_FLAG_OPEN_DRAIN, &flags)) { /* First see if we can enable open drain in hardware */ ret = gpio_set_config(desc, PIN_CONFIG_DRIVE_OPEN_DRAIN); if (!ret) @@ -3042,7 +3043,7 @@ int gpiod_direction_output_nonotify(struct gpio_desc *desc, int value) /* Emulate open drain by not actively driving the line high */ if (value) goto set_output_flag; - } else if (test_bit(FLAG_OPEN_SOURCE, &flags)) { + } else if (test_bit(GPIOD_FLAG_OPEN_SOURCE, &flags)) { ret = gpio_set_config(desc, PIN_CONFIG_DRIVE_OPEN_SOURCE); if (!ret) goto set_output_value; @@ -3069,7 +3070,7 @@ set_output_flag: * set the IS_OUT flag or otherwise we won't be able to set the line * value anymore. */ - set_bit(FLAG_IS_OUT, &desc->flags); + set_bit(GPIOD_FLAG_IS_OUT, &desc->flags); return 0; } @@ -3209,10 +3210,10 @@ int gpiod_set_transitory(struct gpio_desc *desc, bool transitory) { VALIDATE_DESC(desc); /* - * Handle FLAG_TRANSITORY first, enabling queries to gpiolib for + * Handle GPIOD_FLAG_TRANSITORY first, enabling queries to gpiolib for * persistence state. */ - assign_bit(FLAG_TRANSITORY, &desc->flags, transitory); + assign_bit(GPIOD_FLAG_TRANSITORY, &desc->flags, transitory); /* If the driver supports it, set the persistence state now */ return gpio_set_config_with_argument_optional(desc, @@ -3230,7 +3231,7 @@ int gpiod_set_transitory(struct gpio_desc *desc, bool transitory) int gpiod_is_active_low(const struct gpio_desc *desc) { VALIDATE_DESC(desc); - return test_bit(FLAG_ACTIVE_LOW, &desc->flags); + return test_bit(GPIOD_FLAG_ACTIVE_LOW, &desc->flags); } EXPORT_SYMBOL_GPL(gpiod_is_active_low); @@ -3241,7 +3242,7 @@ EXPORT_SYMBOL_GPL(gpiod_is_active_low); void gpiod_toggle_active_low(struct gpio_desc *desc) { VALIDATE_DESC_VOID(desc); - change_bit(FLAG_ACTIVE_LOW, &desc->flags); + change_bit(GPIOD_FLAG_ACTIVE_LOW, &desc->flags); gpiod_line_state_notify(desc, GPIO_V2_LINE_CHANGED_CONFIG); } EXPORT_SYMBOL_GPL(gpiod_toggle_active_low); @@ -3447,7 +3448,7 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep, int hwgpio = gpio_chip_hwgpio(desc); int value = test_bit(hwgpio, bits); - if (!raw && test_bit(FLAG_ACTIVE_LOW, &desc->flags)) + if (!raw && test_bit(GPIOD_FLAG_ACTIVE_LOW, &desc->flags)) value = !value; __assign_bit(j, value_bitmap, value); trace_gpio_value(desc_to_gpio(desc), 1, value); @@ -3509,7 +3510,7 @@ int gpiod_get_value(const struct gpio_desc *desc) if (value < 0) return value; - if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) + if (test_bit(GPIOD_FLAG_ACTIVE_LOW, &desc->flags)) value = !value; return value; @@ -3592,7 +3593,7 @@ static int gpio_set_open_drain_value_commit(struct gpio_desc *desc, bool value) } else { ret = gpiochip_direction_output(guard.gc, offset, 0); if (!ret) - set_bit(FLAG_IS_OUT, &desc->flags); + set_bit(GPIOD_FLAG_IS_OUT, &desc->flags); } trace_gpio_direction(desc_to_gpio(desc), value, ret); if (ret < 0) @@ -3619,7 +3620,7 @@ static int gpio_set_open_source_value_commit(struct gpio_desc *desc, bool value) if (value) { ret = gpiochip_direction_output(guard.gc, offset, 1); if (!ret) - set_bit(FLAG_IS_OUT, &desc->flags); + set_bit(GPIOD_FLAG_IS_OUT, &desc->flags); } else { ret = gpiochip_direction_input(guard.gc, offset); } @@ -3634,7 +3635,7 @@ static int gpio_set_open_source_value_commit(struct gpio_desc *desc, bool value) static int gpiod_set_raw_value_commit(struct gpio_desc *desc, bool value) { - if (unlikely(!test_bit(FLAG_IS_OUT, &desc->flags))) + if (unlikely(!test_bit(GPIOD_FLAG_IS_OUT, &desc->flags))) return -EPERM; CLASS(gpio_chip_guard, guard)(desc); @@ -3665,19 +3666,14 @@ static int gpiochip_set_multiple(struct gpio_chip *gc, lockdep_assert_held(&gc->gpiodev->srcu); - if (gc->set_multiple_rv) { - ret = gc->set_multiple_rv(gc, mask, bits); + if (gc->set_multiple) { + ret = gc->set_multiple(gc, mask, bits); if (ret > 0) ret = -EBADE; return ret; } - if (gc->set_multiple) { - gc->set_multiple(gc, mask, bits); - return 0; - } - /* set outputs if the corresponding mask bit is set */ for_each_set_bit(i, mask, gc->ngpio) { ret = gpiochip_set(gc, i, test_bit(i, bits)); @@ -3709,7 +3705,7 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep, WARN_ON(array_info->gdev->can_sleep); for (i = 0; i < array_size; i++) { - if (unlikely(!test_bit(FLAG_IS_OUT, + if (unlikely(!test_bit(GPIOD_FLAG_IS_OUT, &desc_array[i]->flags))) return -EPERM; } @@ -3773,7 +3769,7 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep, int hwgpio = gpio_chip_hwgpio(desc); int value = test_bit(i, value_bitmap); - if (unlikely(!test_bit(FLAG_IS_OUT, &desc->flags))) + if (unlikely(!test_bit(GPIOD_FLAG_IS_OUT, &desc->flags))) return -EPERM; /* @@ -3783,16 +3779,16 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep, */ if (!raw && !(array_info && test_bit(i, array_info->invert_mask)) && - test_bit(FLAG_ACTIVE_LOW, &desc->flags)) + test_bit(GPIOD_FLAG_ACTIVE_LOW, &desc->flags)) value = !value; trace_gpio_value(desc_to_gpio(desc), 0, value); /* * collect all normal outputs belonging to the same chip * open drain and open source outputs are set individually */ - if (test_bit(FLAG_OPEN_DRAIN, &desc->flags) && !raw) { + if (test_bit(GPIOD_FLAG_OPEN_DRAIN, &desc->flags) && !raw) { gpio_set_open_drain_value_commit(desc, value); - } else if (test_bit(FLAG_OPEN_SOURCE, &desc->flags) && !raw) { + } else if (test_bit(GPIOD_FLAG_OPEN_SOURCE, &desc->flags) && !raw) { gpio_set_open_source_value_commit(desc, value); } else { __set_bit(hwgpio, mask); @@ -3858,12 +3854,12 @@ EXPORT_SYMBOL_GPL(gpiod_set_raw_value); */ static int gpiod_set_value_nocheck(struct gpio_desc *desc, int value) { - if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) + if (test_bit(GPIOD_FLAG_ACTIVE_LOW, &desc->flags)) value = !value; - if (test_bit(FLAG_OPEN_DRAIN, &desc->flags)) + if (test_bit(GPIOD_FLAG_OPEN_DRAIN, &desc->flags)) return gpio_set_open_drain_value_commit(desc, value); - else if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) + else if (test_bit(GPIOD_FLAG_OPEN_SOURCE, &desc->flags)) return gpio_set_open_source_value_commit(desc, value); return gpiod_set_raw_value_commit(desc, value); @@ -4067,16 +4063,16 @@ int gpiochip_lock_as_irq(struct gpio_chip *gc, unsigned int offset) } /* To be valid for IRQ the line needs to be input or open drain */ - if (test_bit(FLAG_IS_OUT, &desc->flags) && - !test_bit(FLAG_OPEN_DRAIN, &desc->flags)) { + if (test_bit(GPIOD_FLAG_IS_OUT, &desc->flags) && + !test_bit(GPIOD_FLAG_OPEN_DRAIN, &desc->flags)) { chip_err(gc, "%s: tried to flag a GPIO set as output for IRQ\n", __func__); return -EIO; } - set_bit(FLAG_USED_AS_IRQ, &desc->flags); - set_bit(FLAG_IRQ_IS_ENABLED, &desc->flags); + set_bit(GPIOD_FLAG_USED_AS_IRQ, &desc->flags); + set_bit(GPIOD_FLAG_IRQ_IS_ENABLED, &desc->flags); return 0; } @@ -4098,8 +4094,8 @@ void gpiochip_unlock_as_irq(struct gpio_chip *gc, unsigned int offset) if (IS_ERR(desc)) return; - clear_bit(FLAG_USED_AS_IRQ, &desc->flags); - clear_bit(FLAG_IRQ_IS_ENABLED, &desc->flags); + clear_bit(GPIOD_FLAG_USED_AS_IRQ, &desc->flags); + clear_bit(GPIOD_FLAG_IRQ_IS_ENABLED, &desc->flags); } EXPORT_SYMBOL_GPL(gpiochip_unlock_as_irq); @@ -4108,8 +4104,8 @@ void gpiochip_disable_irq(struct gpio_chip *gc, unsigned int offset) struct gpio_desc *desc = gpiochip_get_desc(gc, offset); if (!IS_ERR(desc) && - !WARN_ON(!test_bit(FLAG_USED_AS_IRQ, &desc->flags))) - clear_bit(FLAG_IRQ_IS_ENABLED, &desc->flags); + !WARN_ON(!test_bit(GPIOD_FLAG_USED_AS_IRQ, &desc->flags))) + clear_bit(GPIOD_FLAG_IRQ_IS_ENABLED, &desc->flags); } EXPORT_SYMBOL_GPL(gpiochip_disable_irq); @@ -4118,14 +4114,14 @@ void gpiochip_enable_irq(struct gpio_chip *gc, unsigned int offset) struct gpio_desc *desc = gpiochip_get_desc(gc, offset); if (!IS_ERR(desc) && - !WARN_ON(!test_bit(FLAG_USED_AS_IRQ, &desc->flags))) { + !WARN_ON(!test_bit(GPIOD_FLAG_USED_AS_IRQ, &desc->flags))) { /* * We must not be output when using IRQ UNLESS we are * open drain. */ - WARN_ON(test_bit(FLAG_IS_OUT, &desc->flags) && - !test_bit(FLAG_OPEN_DRAIN, &desc->flags)); - set_bit(FLAG_IRQ_IS_ENABLED, &desc->flags); + WARN_ON(test_bit(GPIOD_FLAG_IS_OUT, &desc->flags) && + !test_bit(GPIOD_FLAG_OPEN_DRAIN, &desc->flags)); + set_bit(GPIOD_FLAG_IRQ_IS_ENABLED, &desc->flags); } } EXPORT_SYMBOL_GPL(gpiochip_enable_irq); @@ -4135,7 +4131,7 @@ bool gpiochip_line_is_irq(struct gpio_chip *gc, unsigned int offset) if (offset >= gc->ngpio) return false; - return test_bit(FLAG_USED_AS_IRQ, &gc->gpiodev->descs[offset].flags); + return test_bit(GPIOD_FLAG_USED_AS_IRQ, &gc->gpiodev->descs[offset].flags); } EXPORT_SYMBOL_GPL(gpiochip_line_is_irq); @@ -4168,7 +4164,7 @@ bool gpiochip_line_is_open_drain(struct gpio_chip *gc, unsigned int offset) if (offset >= gc->ngpio) return false; - return test_bit(FLAG_OPEN_DRAIN, &gc->gpiodev->descs[offset].flags); + return test_bit(GPIOD_FLAG_OPEN_DRAIN, &gc->gpiodev->descs[offset].flags); } EXPORT_SYMBOL_GPL(gpiochip_line_is_open_drain); @@ -4177,7 +4173,7 @@ bool gpiochip_line_is_open_source(struct gpio_chip *gc, unsigned int offset) if (offset >= gc->ngpio) return false; - return test_bit(FLAG_OPEN_SOURCE, &gc->gpiodev->descs[offset].flags); + return test_bit(GPIOD_FLAG_OPEN_SOURCE, &gc->gpiodev->descs[offset].flags); } EXPORT_SYMBOL_GPL(gpiochip_line_is_open_source); @@ -4186,7 +4182,7 @@ bool gpiochip_line_is_persistent(struct gpio_chip *gc, unsigned int offset) if (offset >= gc->ngpio) return false; - return !test_bit(FLAG_TRANSITORY, &gc->gpiodev->descs[offset].flags); + return !test_bit(GPIOD_FLAG_TRANSITORY, &gc->gpiodev->descs[offset].flags); } EXPORT_SYMBOL_GPL(gpiochip_line_is_persistent); @@ -4228,7 +4224,7 @@ int gpiod_get_value_cansleep(const struct gpio_desc *desc) if (value < 0) return value; - if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) + if (test_bit(GPIOD_FLAG_ACTIVE_LOW, &desc->flags)) value = !value; return value; @@ -4619,6 +4615,23 @@ static struct gpio_desc *gpiod_find_by_fwnode(struct fwnode_handle *fwnode, return desc; } +static struct gpio_desc *gpiod_fwnode_lookup(struct fwnode_handle *fwnode, + struct device *consumer, + const char *con_id, + unsigned int idx, + enum gpiod_flags *flags, + unsigned long *lookupflags) +{ + struct gpio_desc *desc; + + desc = gpiod_find_by_fwnode(fwnode, consumer, con_id, idx, flags, lookupflags); + if (gpiod_not_found(desc) && !IS_ERR_OR_NULL(fwnode)) + desc = gpiod_find_by_fwnode(fwnode->secondary, consumer, con_id, + idx, flags, lookupflags); + + return desc; +} + struct gpio_desc *gpiod_find_and_request(struct device *consumer, struct fwnode_handle *fwnode, const char *con_id, @@ -4637,8 +4650,8 @@ struct gpio_desc *gpiod_find_and_request(struct device *consumer, int ret = 0; scoped_guard(srcu, &gpio_devices_srcu) { - desc = gpiod_find_by_fwnode(fwnode, consumer, con_id, idx, - &flags, &lookupflags); + desc = gpiod_fwnode_lookup(fwnode, consumer, con_id, idx, + &flags, &lookupflags); if (gpiod_not_found(desc) && platform_lookup_allowed) { /* * Either we are not using DT or ACPI, or their lookup @@ -4810,10 +4823,10 @@ int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id, int ret; if (lflags & GPIO_ACTIVE_LOW) - set_bit(FLAG_ACTIVE_LOW, &desc->flags); + set_bit(GPIOD_FLAG_ACTIVE_LOW, &desc->flags); if (lflags & GPIO_OPEN_DRAIN) - set_bit(FLAG_OPEN_DRAIN, &desc->flags); + set_bit(GPIOD_FLAG_OPEN_DRAIN, &desc->flags); else if (dflags & GPIOD_FLAGS_BIT_OPEN_DRAIN) { /* * This enforces open drain mode from the consumer side. @@ -4821,13 +4834,13 @@ int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id, * should *REALLY* have specified them as open drain in the * first place, so print a little warning here. */ - set_bit(FLAG_OPEN_DRAIN, &desc->flags); + set_bit(GPIOD_FLAG_OPEN_DRAIN, &desc->flags); gpiod_warn(desc, "enforced open drain please flag it properly in DT/ACPI DSDT/board file\n"); } if (lflags & GPIO_OPEN_SOURCE) - set_bit(FLAG_OPEN_SOURCE, &desc->flags); + set_bit(GPIOD_FLAG_OPEN_SOURCE, &desc->flags); if (((lflags & GPIO_PULL_UP) && (lflags & GPIO_PULL_DOWN)) || ((lflags & GPIO_PULL_UP) && (lflags & GPIO_PULL_DISABLE)) || @@ -4838,11 +4851,11 @@ int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id, } if (lflags & GPIO_PULL_UP) - set_bit(FLAG_PULL_UP, &desc->flags); + set_bit(GPIOD_FLAG_PULL_UP, &desc->flags); else if (lflags & GPIO_PULL_DOWN) - set_bit(FLAG_PULL_DOWN, &desc->flags); + set_bit(GPIOD_FLAG_PULL_DOWN, &desc->flags); else if (lflags & GPIO_PULL_DISABLE) - set_bit(FLAG_BIAS_DISABLE, &desc->flags); + set_bit(GPIOD_FLAG_BIAS_DISABLE, &desc->flags); ret = gpiod_set_transitory(desc, (lflags & GPIO_TRANSITORY)); if (ret < 0) @@ -4947,7 +4960,7 @@ int gpiod_hog(struct gpio_desc *desc, const char *name, if (!guard.gc) return -ENODEV; - if (test_and_set_bit(FLAG_IS_HOGGED, &desc->flags)) + if (test_and_set_bit(GPIOD_FLAG_IS_HOGGED, &desc->flags)) return 0; hwnum = gpio_chip_hwgpio(desc); @@ -4955,7 +4968,7 @@ int gpiod_hog(struct gpio_desc *desc, const char *name, local_desc = gpiochip_request_own_desc(guard.gc, hwnum, name, lflags, dflags); if (IS_ERR(local_desc)) { - clear_bit(FLAG_IS_HOGGED, &desc->flags); + clear_bit(GPIOD_FLAG_IS_HOGGED, &desc->flags); ret = PTR_ERR(local_desc); pr_err("requesting hog GPIO %s (chip %s, offset %d) failed, %d\n", name, gdev->label, hwnum, ret); @@ -4978,7 +4991,7 @@ static void gpiochip_free_hogs(struct gpio_chip *gc) { struct gpio_desc *desc; - for_each_gpio_desc_with_flag(gc, desc, FLAG_IS_HOGGED) + for_each_gpio_desc_with_flag(gc, desc, GPIOD_FLAG_IS_HOGGED) gpiochip_free_own_desc(desc); } @@ -5093,8 +5106,8 @@ struct gpio_descs *__must_check gpiod_get_array(struct device *dev, } else { dflags = READ_ONCE(desc->flags); /* Exclude open drain or open source from fast output */ - if (test_bit(FLAG_OPEN_DRAIN, &dflags) || - test_bit(FLAG_OPEN_SOURCE, &dflags)) + if (test_bit(GPIOD_FLAG_OPEN_DRAIN, &dflags) || + test_bit(GPIOD_FLAG_OPEN_SOURCE, &dflags)) __clear_bit(descs->ndescs, array_info->set_mask); /* Identify 'fast' pins which require invertion */ @@ -5252,12 +5265,12 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_device *gdev) for_each_gpio_desc(gc, desc) { guard(srcu)(&desc->gdev->desc_srcu); flags = READ_ONCE(desc->flags); - is_irq = test_bit(FLAG_USED_AS_IRQ, &flags); - if (is_irq || test_bit(FLAG_REQUESTED, &flags)) { + is_irq = test_bit(GPIOD_FLAG_USED_AS_IRQ, &flags); + if (is_irq || test_bit(GPIOD_FLAG_REQUESTED, &flags)) { gpiod_get_direction(desc); - is_out = test_bit(FLAG_IS_OUT, &flags); + is_out = test_bit(GPIOD_FLAG_IS_OUT, &flags); value = gpio_chip_get_value(gc, desc); - active_low = test_bit(FLAG_ACTIVE_LOW, &flags); + active_low = test_bit(GPIOD_FLAG_ACTIVE_LOW, &flags); seq_printf(s, " gpio-%-3u (%-20.20s|%-20.20s) %s %s %s%s\n", gpio, desc->name ?: "", gpiod_get_label(desc), is_out ? "out" : "in ", |