summaryrefslogtreecommitdiff
path: root/drivers/gpio/gpiolib.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r--drivers/gpio/gpiolib.c217
1 files changed, 138 insertions, 79 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index cd8800ba5825..91e0c384f34a 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -37,6 +37,7 @@
#include "gpiolib-acpi.h"
#include "gpiolib-cdev.h"
#include "gpiolib-of.h"
+#include "gpiolib-shared.h"
#include "gpiolib-swnode.h"
#include "gpiolib-sysfs.h"
#include "gpiolib.h"
@@ -235,6 +236,19 @@ int desc_to_gpio(const struct gpio_desc *desc)
}
EXPORT_SYMBOL_GPL(desc_to_gpio);
+/**
+ * gpiod_hwgpio - Return the GPIO number of the passed descriptor relative to
+ * its chip.
+ * @desc: GPIO descriptor
+ *
+ * Returns:
+ * Hardware offset of the GPIO represented by the descriptor.
+ */
+int gpiod_hwgpio(const struct gpio_desc *desc)
+{
+ return desc - &desc->gdev->descs[0];
+}
+EXPORT_SYMBOL_GPL(gpiod_hwgpio);
/**
* gpiod_to_chip - Return the GPIO chip to which a GPIO descriptor belongs
@@ -443,7 +457,7 @@ int gpiod_get_direction(struct gpio_desc *desc)
if (!guard.gc)
return -ENODEV;
- offset = gpio_chip_hwgpio(desc);
+ offset = gpiod_hwgpio(desc);
flags = READ_ONCE(desc->flags);
/*
@@ -921,8 +935,8 @@ static void gpiochip_machine_hog(struct gpio_chip *gc, struct gpiod_hog *hog)
desc = gpiochip_get_desc(gc, hog->chip_hwnum);
if (IS_ERR(desc)) {
- chip_err(gc, "%s: unable to get GPIO desc: %ld\n", __func__,
- PTR_ERR(desc));
+ gpiochip_err(gc, "%s: unable to get GPIO desc: %ld\n",
+ __func__, PTR_ERR(desc));
return;
}
@@ -1124,7 +1138,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
ret = gpiodev_add_to_list_unlocked(gdev);
if (ret) {
- chip_err(gc, "GPIO integer space overlap, cannot add chip\n");
+ gpiochip_err(gc, "GPIO integer space overlap, cannot add chip\n");
goto err_free_label;
}
}
@@ -1200,6 +1214,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
if (ret)
goto err_remove_irqchip_mask;
+ ret = gpio_device_setup_shared(gdev);
+ if (ret)
+ goto err_remove_irqchip;
+
/*
* By first adding the chardev, and then adding the device,
* we get a device node entry in sysfs under
@@ -1211,10 +1229,13 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
if (gpiolib_initialized) {
ret = gpiochip_setup_dev(gdev);
if (ret)
- goto err_remove_irqchip;
+ goto err_teardown_shared;
}
+
return 0;
+err_teardown_shared:
+ gpio_device_teardown_shared(gdev);
err_remove_irqchip:
gpiochip_irqchip_remove(gc);
err_remove_irqchip_mask:
@@ -1283,6 +1304,7 @@ void gpiochip_remove(struct gpio_chip *gc)
/* Numb the device, cancelling all outstanding operations */
rcu_assign_pointer(gdev->chip, NULL);
synchronize_srcu(&gdev->srcu);
+ gpio_device_teardown_shared(gdev);
gpiochip_irqchip_remove(gc);
acpi_gpiochip_remove(gc);
of_gpiochip_remove(gc);
@@ -1528,8 +1550,7 @@ static void gpiochip_set_hierarchical_irqchip(struct gpio_chip *gc,
&parent_hwirq,
&parent_type);
if (ret) {
- chip_err(gc, "skip set-up on hwirq %d\n",
- i);
+ gpiochip_err(gc, "skip set-up on hwirq %d\n", i);
continue;
}
@@ -1542,15 +1563,14 @@ static void gpiochip_set_hierarchical_irqchip(struct gpio_chip *gc,
ret = irq_domain_alloc_irqs(gc->irq.domain, 1,
NUMA_NO_NODE, &fwspec);
if (ret < 0) {
- chip_err(gc,
- "can not allocate irq for GPIO line %d parent hwirq %d in hierarchy domain: %d\n",
- i, parent_hwirq,
- ret);
+ gpiochip_err(gc,
+ "can not allocate irq for GPIO line %d parent hwirq %d in hierarchy domain: %d\n",
+ i, parent_hwirq, ret);
}
}
}
- chip_err(gc, "%s unknown fwnode type proceed anyway\n", __func__);
+ gpiochip_err(gc, "%s unknown fwnode type proceed anyway\n", __func__);
return;
}
@@ -1602,15 +1622,15 @@ static int gpiochip_hierarchy_irq_domain_alloc(struct irq_domain *d,
if (ret)
return ret;
- chip_dbg(gc, "allocate IRQ %d, hwirq %lu\n", irq, hwirq);
+ gpiochip_dbg(gc, "allocate IRQ %d, hwirq %lu\n", irq, hwirq);
ret = girq->child_to_parent_hwirq(gc, hwirq, type,
&parent_hwirq, &parent_type);
if (ret) {
- chip_err(gc, "can't look up hwirq %lu\n", hwirq);
+ gpiochip_err(gc, "can't look up hwirq %lu\n", hwirq);
return ret;
}
- chip_dbg(gc, "found parent hwirq %u\n", parent_hwirq);
+ gpiochip_dbg(gc, "found parent hwirq %u\n", parent_hwirq);
/*
* We set handle_bad_irq because the .set_type() should
@@ -1631,8 +1651,8 @@ static int gpiochip_hierarchy_irq_domain_alloc(struct irq_domain *d,
if (ret)
return ret;
- chip_dbg(gc, "alloc_irqs_parent for %d parent hwirq %d\n",
- irq, parent_hwirq);
+ gpiochip_dbg(gc, "alloc_irqs_parent for %d parent hwirq %d\n",
+ irq, parent_hwirq);
irq_set_lockdep_class(irq, gc->irq.lock_key, gc->irq.request_key);
ret = irq_domain_alloc_irqs_parent(d, irq, 1, &gpio_parent_fwspec);
/*
@@ -1642,9 +1662,9 @@ static int gpiochip_hierarchy_irq_domain_alloc(struct irq_domain *d,
if (irq_domain_is_msi(d->parent) && (ret == -EEXIST))
ret = 0;
if (ret)
- chip_err(gc,
- "failed to allocate parent hwirq %d for hwirq %lu\n",
- parent_hwirq, hwirq);
+ gpiochip_err(gc,
+ "failed to allocate parent hwirq %d for hwirq %lu\n",
+ parent_hwirq, hwirq);
return ret;
}
@@ -1720,7 +1740,7 @@ static struct irq_domain *gpiochip_hierarchy_create_domain(struct gpio_chip *gc)
if (!gc->irq.child_to_parent_hwirq ||
!gc->irq.fwnode) {
- chip_err(gc, "missing irqdomain vital data\n");
+ gpiochip_err(gc, "missing irqdomain vital data\n");
return ERR_PTR(-EINVAL);
}
@@ -1993,7 +2013,7 @@ static void gpiochip_set_irq_hooks(struct gpio_chip *gc)
if (irqchip->flags & IRQCHIP_IMMUTABLE)
return;
- chip_warn(gc, "not an immutable chip, please consider fixing it!\n");
+ gpiochip_warn(gc, "not an immutable chip, please consider fixing it!\n");
if (!irqchip->irq_request_resources &&
!irqchip->irq_release_resources) {
@@ -2009,8 +2029,8 @@ static void gpiochip_set_irq_hooks(struct gpio_chip *gc)
* ...and if so, give a gentle warning that this is bad
* practice.
*/
- chip_info(gc,
- "detected irqchip that is shared with multiple gpiochips: please fix the driver.\n");
+ gpiochip_info(gc,
+ "detected irqchip that is shared with multiple gpiochips: please fix the driver.\n");
return;
}
@@ -2039,7 +2059,8 @@ static int gpiochip_irqchip_add_allocated_domain(struct gpio_chip *gc,
return -EINVAL;
if (gc->to_irq)
- chip_warn(gc, "to_irq is redefined in %s and you shouldn't rely on it\n", __func__);
+ gpiochip_warn(gc, "to_irq is redefined in %s and you shouldn't rely on it\n",
+ __func__);
gc->to_irq = gpiochip_to_irq;
gc->irq.domain = domain;
@@ -2080,7 +2101,7 @@ static int gpiochip_add_irqchip(struct gpio_chip *gc,
return 0;
if (gc->irq.parent_handler && gc->can_sleep) {
- chip_err(gc, "you cannot have chained interrupts on a chip that may sleep\n");
+ gpiochip_err(gc, "you cannot have chained interrupts on a chip that may sleep\n");
return -EINVAL;
}
@@ -2316,10 +2337,8 @@ int gpiochip_add_pingroup_range(struct gpio_chip *gc,
int ret;
pin_range = kzalloc(sizeof(*pin_range), GFP_KERNEL);
- if (!pin_range) {
- chip_err(gc, "failed to allocate pin ranges\n");
+ if (!pin_range)
return -ENOMEM;
- }
/* Use local offset as range ID */
pin_range->range.id = gpio_offset;
@@ -2338,7 +2357,7 @@ int gpiochip_add_pingroup_range(struct gpio_chip *gc,
pinctrl_add_gpio_range(pctldev, &pin_range->range);
- chip_dbg(gc, "created GPIO range %d->%d ==> %s PINGRP %s\n",
+ gpiochip_dbg(gc, "created GPIO range %d->%d ==> %s PINGRP %s\n",
gpio_offset, gpio_offset + pin_range->range.npins - 1,
pinctrl_dev_get_devname(pctldev), pin_group);
@@ -2379,10 +2398,8 @@ int gpiochip_add_pin_range_with_pins(struct gpio_chip *gc,
int ret;
pin_range = kzalloc(sizeof(*pin_range), GFP_KERNEL);
- if (!pin_range) {
- chip_err(gc, "failed to allocate pin ranges\n");
+ if (!pin_range)
return -ENOMEM;
- }
/* Use local offset as range ID */
pin_range->range.id = gpio_offset;
@@ -2396,19 +2413,18 @@ int gpiochip_add_pin_range_with_pins(struct gpio_chip *gc,
&pin_range->range);
if (IS_ERR(pin_range->pctldev)) {
ret = PTR_ERR(pin_range->pctldev);
- chip_err(gc, "could not create pin range\n");
+ gpiochip_err(gc, "could not create pin range\n");
kfree(pin_range);
return ret;
}
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]);
+ gpiochip_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);
+ gpiochip_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);
@@ -2452,7 +2468,7 @@ static int gpiod_request_commit(struct gpio_desc *desc, const char *label)
if (test_and_set_bit(GPIOD_FLAG_REQUESTED, &desc->flags))
return -EBUSY;
- offset = gpio_chip_hwgpio(desc);
+ offset = gpiod_hwgpio(desc);
if (!gpiochip_line_is_valid(guard.gc, offset))
return -EINVAL;
@@ -2514,7 +2530,7 @@ static void gpiod_free_commit(struct gpio_desc *desc)
if (guard.gc && test_bit(GPIOD_FLAG_REQUESTED, &flags)) {
if (guard.gc->free)
- guard.gc->free(guard.gc, gpio_chip_hwgpio(desc));
+ guard.gc->free(guard.gc, gpiod_hwgpio(desc));
clear_bit(GPIOD_FLAG_ACTIVE_LOW, &flags);
clear_bit(GPIOD_FLAG_REQUESTED, &flags);
@@ -2618,7 +2634,7 @@ struct gpio_desc *gpiochip_request_own_desc(struct gpio_chip *gc,
int ret;
if (IS_ERR(desc)) {
- chip_err(gc, "failed to get GPIO %s descriptor\n", name);
+ gpiochip_err(gc, "failed to get GPIO %s descriptor\n", name);
return desc;
}
@@ -2629,7 +2645,7 @@ struct gpio_desc *gpiochip_request_own_desc(struct gpio_chip *gc,
ret = gpiod_configure_flags(desc, label, lflags, dflags);
if (ret) {
gpiod_free_commit(desc);
- chip_err(gc, "setup of own GPIO %s failed\n", name);
+ gpiochip_err(gc, "setup of own GPIO %s failed\n", name);
return ERR_PTR(ret);
}
@@ -2674,7 +2690,7 @@ int gpio_do_set_config(struct gpio_desc *desc, unsigned long config)
if (!guard.gc->set_config)
return -ENOTSUPP;
- ret = guard.gc->set_config(guard.gc, gpio_chip_hwgpio(desc), config);
+ ret = guard.gc->set_config(guard.gc, gpiod_hwgpio(desc), config);
if (ret > 0)
ret = -EBADE;
@@ -2705,7 +2721,7 @@ static int gpio_set_config_with_argument_optional(struct gpio_desc *desc,
u32 argument)
{
struct device *dev = &desc->gdev->dev;
- int gpio = gpio_chip_hwgpio(desc);
+ int gpio = gpiod_hwgpio(desc);
int ret;
ret = gpio_set_config_with_argument(desc, mode, argument);
@@ -2868,9 +2884,9 @@ int gpiod_direction_input_nonotify(struct gpio_desc *desc)
*/
if (guard.gc->direction_input) {
ret = gpiochip_direction_input(guard.gc,
- gpio_chip_hwgpio(desc));
+ gpiod_hwgpio(desc));
} else if (guard.gc->get_direction) {
- dir = gpiochip_get_direction(guard.gc, gpio_chip_hwgpio(desc));
+ dir = gpiochip_get_direction(guard.gc, gpiod_hwgpio(desc));
if (dir < 0)
return dir;
@@ -2929,12 +2945,12 @@ static int gpiod_direction_output_raw_commit(struct gpio_desc *desc, int value)
if (guard.gc->direction_output) {
ret = gpiochip_direction_output(guard.gc,
- gpio_chip_hwgpio(desc), val);
+ gpiod_hwgpio(desc), val);
} else {
/* Check that we are in output mode if we can */
if (guard.gc->get_direction) {
dir = gpiochip_get_direction(guard.gc,
- gpio_chip_hwgpio(desc));
+ gpiod_hwgpio(desc));
if (dir < 0)
return dir;
@@ -2949,7 +2965,7 @@ static int gpiod_direction_output_raw_commit(struct gpio_desc *desc, int value)
* If we can't actively set the direction, we are some
* output-only chip, so just drive the output as desired.
*/
- ret = gpiochip_set(guard.gc, gpio_chip_hwgpio(desc), val);
+ ret = gpiochip_set(guard.gc, gpiod_hwgpio(desc), val);
if (ret)
return ret;
}
@@ -3100,7 +3116,7 @@ int gpiod_enable_hw_timestamp_ns(struct gpio_desc *desc, unsigned long flags)
}
ret = guard.gc->en_hw_timestamp(guard.gc,
- gpio_chip_hwgpio(desc), flags);
+ gpiod_hwgpio(desc), flags);
if (ret)
gpiod_warn(desc, "%s: hw ts request failed\n", __func__);
@@ -3132,7 +3148,7 @@ int gpiod_disable_hw_timestamp_ns(struct gpio_desc *desc, unsigned long flags)
return -ENOTSUPP;
}
- ret = guard.gc->dis_hw_timestamp(guard.gc, gpio_chip_hwgpio(desc),
+ ret = guard.gc->dis_hw_timestamp(guard.gc, gpiod_hwgpio(desc),
flags);
if (ret)
gpiod_warn(desc, "%s: hw ts release failed\n", __func__);
@@ -3263,7 +3279,7 @@ static int gpiochip_get(struct gpio_chip *gc, unsigned int offset)
static int gpio_chip_get_value(struct gpio_chip *gc, const struct gpio_desc *desc)
{
- return gc->get ? gpiochip_get(gc, gpio_chip_hwgpio(desc)) : -EIO;
+ return gc->get ? gpiochip_get(gc, gpiod_hwgpio(desc)) : -EIO;
}
/* I/O calls are only valid after configuration completed; the relevant
@@ -3423,7 +3439,7 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
first = i;
do {
const struct gpio_desc *desc = desc_array[i];
- int hwgpio = gpio_chip_hwgpio(desc);
+ int hwgpio = gpiod_hwgpio(desc);
__set_bit(hwgpio, mask);
i++;
@@ -3445,7 +3461,7 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
for (j = first; j < i; ) {
const struct gpio_desc *desc = desc_array[j];
- int hwgpio = gpio_chip_hwgpio(desc);
+ int hwgpio = gpiod_hwgpio(desc);
int value = test_bit(hwgpio, bits);
if (!raw && test_bit(GPIOD_FLAG_ACTIVE_LOW, &desc->flags))
@@ -3582,7 +3598,7 @@ EXPORT_SYMBOL_GPL(gpiod_get_array_value);
*/
static int gpio_set_open_drain_value_commit(struct gpio_desc *desc, bool value)
{
- int ret = 0, offset = gpio_chip_hwgpio(desc);
+ int ret = 0, offset = gpiod_hwgpio(desc);
CLASS(gpio_chip_guard, guard)(desc);
if (!guard.gc)
@@ -3611,7 +3627,7 @@ static int gpio_set_open_drain_value_commit(struct gpio_desc *desc, bool value)
*/
static int gpio_set_open_source_value_commit(struct gpio_desc *desc, bool value)
{
- int ret = 0, offset = gpio_chip_hwgpio(desc);
+ int ret = 0, offset = gpiod_hwgpio(desc);
CLASS(gpio_chip_guard, guard)(desc);
if (!guard.gc)
@@ -3643,7 +3659,7 @@ static int gpiod_set_raw_value_commit(struct gpio_desc *desc, bool value)
return -ENODEV;
trace_gpio_value(desc_to_gpio(desc), 0, value);
- return gpiochip_set(guard.gc, gpio_chip_hwgpio(desc), value);
+ return gpiochip_set(guard.gc, gpiod_hwgpio(desc), value);
}
/*
@@ -3766,7 +3782,7 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
do {
struct gpio_desc *desc = desc_array[i];
- int hwgpio = gpio_chip_hwgpio(desc);
+ int hwgpio = gpiod_hwgpio(desc);
int value = test_bit(i, value_bitmap);
if (unlikely(!test_bit(GPIOD_FLAG_IS_OUT, &desc->flags)))
@@ -3982,6 +3998,26 @@ int gpiod_set_consumer_name(struct gpio_desc *desc, const char *name)
EXPORT_SYMBOL_GPL(gpiod_set_consumer_name);
/**
+ * gpiod_is_shared() - check if this GPIO can be shared by multiple consumers
+ * @desc: GPIO to inspect
+ *
+ * Returns:
+ * True if this GPIO can be shared by multiple consumers at once. False if it's
+ * a regular, exclusive GPIO.
+ *
+ * Note:
+ * This function returning true does not mean that this GPIO is currently being
+ * shared. It means the GPIO core has registered the fact that the firmware
+ * configuration indicates that it can be shared by multiple consumers and is
+ * in charge of arbitrating the access.
+ */
+bool gpiod_is_shared(const struct gpio_desc *desc)
+{
+ return test_bit(GPIOD_FLAG_SHARED_PROXY, &desc->flags);
+}
+EXPORT_SYMBOL_GPL(gpiod_is_shared);
+
+/**
* gpiod_to_irq() - return the IRQ corresponding to a GPIO
* @desc: gpio whose IRQ will be returned (already requested)
*
@@ -4006,7 +4042,7 @@ int gpiod_to_irq(const struct gpio_desc *desc)
if (!gc)
return -ENODEV;
- offset = gpio_chip_hwgpio(desc);
+ offset = gpiod_hwgpio(desc);
if (gc->to_irq) {
ret = gc->to_irq(gc, offset);
if (ret)
@@ -4056,8 +4092,8 @@ int gpiochip_lock_as_irq(struct gpio_chip *gc, unsigned int offset)
int dir = gpiod_get_direction(desc);
if (dir < 0) {
- chip_err(gc, "%s: cannot get GPIO direction\n",
- __func__);
+ gpiochip_err(gc, "%s: cannot get GPIO direction\n",
+ __func__);
return dir;
}
}
@@ -4065,9 +4101,9 @@ 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(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__);
+ gpiochip_err(gc,
+ "%s: tried to flag a GPIO set as output for IRQ\n",
+ __func__);
return -EIO;
}
@@ -4144,7 +4180,7 @@ int gpiochip_reqres_irq(struct gpio_chip *gc, unsigned int offset)
ret = gpiochip_lock_as_irq(gc, offset);
if (ret) {
- chip_err(gc, "unable to lock HW IRQ %u for IRQ\n", offset);
+ gpiochip_err(gc, "unable to lock HW IRQ %u for IRQ\n", offset);
module_put(gc->gpiodev->owner);
return ret;
}
@@ -4652,11 +4688,29 @@ struct gpio_desc *gpiod_find_and_request(struct device *consumer,
scoped_guard(srcu, &gpio_devices_srcu) {
desc = gpiod_fwnode_lookup(fwnode, consumer, con_id, idx,
&flags, &lookupflags);
+ if (!IS_ERR_OR_NULL(desc) &&
+ test_bit(GPIOD_FLAG_SHARED, &desc->flags)) {
+ /*
+ * We're dealing with a GPIO shared by multiple
+ * consumers. This is the moment to add the machine
+ * lookup table for the proxy device as previously
+ * we only knew the consumer's fwnode.
+ */
+ ret = gpio_shared_add_proxy_lookup(consumer, lookupflags);
+ if (ret)
+ return ERR_PTR(ret);
+
+ /* Trigger platform lookup for shared GPIO proxy. */
+ desc = ERR_PTR(-ENOENT);
+ /* Trigger it even for fwnode-only gpiod_get(). */
+ platform_lookup_allowed = true;
+ }
+
if (gpiod_not_found(desc) && platform_lookup_allowed) {
/*
* Either we are not using DT or ACPI, or their lookup
- * did not return a result. In that case, use platform
- * lookup as a fallback.
+ * did not return a result or this is a shared GPIO. In
+ * that case, use platform lookup as a fallback.
*/
dev_dbg(consumer,
"using lookup tables for GPIO lookup\n");
@@ -4679,14 +4733,19 @@ struct gpio_desc *gpiod_find_and_request(struct device *consumer,
return ERR_PTR(ret);
/*
- * This happens when there are several consumers for
- * the same GPIO line: we just return here without
- * further initialization. It is a bit of a hack.
- * This is necessary to support fixed regulators.
+ * This happens when there are several consumers for the same
+ * GPIO line: we just return here without further
+ * initialization. It's a hack introduced long ago to support
+ * fixed regulators. We now have a better solution with
+ * automated scanning where affected platforms just need to
+ * select the provided Kconfig option.
*
- * FIXME: Make this more sane and safe.
+ * FIXME: Remove the GPIOD_FLAGS_BIT_NONEXCLUSIVE flag after
+ * making sure all platforms use the new mechanism.
*/
- dev_info(consumer, "nonexclusive access to GPIO for %s\n", name);
+ dev_info(consumer,
+ "nonexclusive access to GPIO for %s, consider updating your code to using gpio-shared-proxy\n",
+ name);
return desc;
}
@@ -4963,7 +5022,7 @@ int gpiod_hog(struct gpio_desc *desc, const char *name,
if (test_and_set_bit(GPIOD_FLAG_IS_HOGGED, &desc->flags))
return 0;
- hwnum = gpio_chip_hwgpio(desc);
+ hwnum = gpiod_hwgpio(desc);
local_desc = gpiochip_request_own_desc(guard.gc, hwnum, name,
lflags, dflags);
@@ -5044,7 +5103,7 @@ struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
* If pin hardware number of array member 0 is also 0, select
* its chip as a candidate for fast bitmap processing path.
*/
- if (descs->ndescs == 0 && gpio_chip_hwgpio(desc) == 0) {
+ if (descs->ndescs == 0 && gpiod_hwgpio(desc) == 0) {
struct gpio_descs *array;
bitmap_size = BITS_TO_LONGS(gdev->ngpio > count ?
@@ -5089,7 +5148,7 @@ struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
* Detect array members which belong to the 'fast' chip
* but their pins are not in hardware order.
*/
- else if (gpio_chip_hwgpio(desc) != descs->ndescs) {
+ else if (gpiod_hwgpio(desc) != descs->ndescs) {
/*
* Don't use fast path if all array members processed so
* far belong to the same chip as this one but its pin