Skip to content

Commit 8eb1f71

Browse files
dtorBartosz Golaszewski
authored andcommitted
gpiolib: consolidate GPIO lookups
Ensure that all paths to obtain/look up GPIOD from generic consumer-visible APIs go through the new gpiod_find_and_request() helper, so that we can easily extend it with support for new firmware mechanisms. The only exception is OF-specific [devm_]gpiod_get_from_of_node() API that is still being used by a couple of drivers and will be removed as soon as patches converting them to use generic fwnode/device APIs are accepted. Acked-by: Linus Walleij <[email protected]> Signed-off-by: Dmitry Torokhov <[email protected]> Signed-off-by: Bartosz Golaszewski <[email protected]>
1 parent b7452d6 commit 8eb1f71

File tree

3 files changed

+76
-177
lines changed

3 files changed

+76
-177
lines changed

drivers/gpio/gpiolib-acpi.c

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,45 +1024,6 @@ struct gpio_desc *acpi_find_gpio(struct fwnode_handle *fwnode,
10241024
return desc;
10251025
}
10261026

1027-
/**
1028-
* acpi_node_get_gpiod() - get a GPIO descriptor from ACPI resources
1029-
* @fwnode: pointer to an ACPI firmware node to get the GPIO information from
1030-
* @propname: Property name of the GPIO
1031-
* @index: index of GpioIo/GpioInt resource (starting from %0)
1032-
* @lflags: bitmask of gpio_lookup_flags GPIO_* values
1033-
* @dflags: gpiod initialization flags
1034-
*
1035-
* If @fwnode is an ACPI device object, call acpi_get_gpiod_by_index() for it.
1036-
* Otherwise (i.e. it is a data-only non-device object), use the property-based
1037-
* GPIO lookup to get to the GPIO resource with the relevant information and use
1038-
* that to obtain the GPIO descriptor to return.
1039-
*
1040-
* If the GPIO cannot be translated or there is an error an ERR_PTR is
1041-
* returned.
1042-
*/
1043-
struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
1044-
const char *propname, int index,
1045-
unsigned long *lflags,
1046-
enum gpiod_flags *dflags)
1047-
{
1048-
struct acpi_gpio_info info;
1049-
struct acpi_device *adev;
1050-
struct gpio_desc *desc;
1051-
1052-
adev = to_acpi_device_node(fwnode);
1053-
if (adev)
1054-
desc = acpi_get_gpiod_by_index(adev, propname, index, &info);
1055-
else
1056-
desc = acpi_get_gpiod_from_data(fwnode, propname, index, &info);
1057-
1058-
if (!IS_ERR(desc)) {
1059-
acpi_gpio_update_gpiod_flags(dflags, &info);
1060-
acpi_gpio_update_gpiod_lookup_flags(lflags, &info);
1061-
}
1062-
1063-
return desc;
1064-
}
1065-
10661027
/**
10671028
* acpi_dev_gpio_irq_wake_get_by() - Find GpioInt and translate it to Linux IRQ number
10681029
* @adev: pointer to a ACPI device to get IRQ from

drivers/gpio/gpiolib-acpi.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,6 @@ struct gpio_desc *acpi_find_gpio(struct fwnode_handle *fwnode,
2424
unsigned int idx,
2525
enum gpiod_flags *dflags,
2626
unsigned long *lookupflags);
27-
struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
28-
const char *propname, int index,
29-
unsigned long *lflags,
30-
enum gpiod_flags *dflags);
3127

3228
int acpi_gpio_count(struct device *dev, const char *con_id);
3329
#else
@@ -49,12 +45,6 @@ acpi_find_gpio(struct fwnode_handle *fwnode, const char *con_id,
4945
{
5046
return ERR_PTR(-ENOENT);
5147
}
52-
static inline struct gpio_desc *
53-
acpi_node_get_gpiod(struct fwnode_handle *fwnode, const char *propname,
54-
int index, unsigned long *lflags, enum gpiod_flags *dflags)
55-
{
56-
return ERR_PTR(-ENXIO);
57-
}
5848
static inline int acpi_gpio_count(struct device *dev, const char *con_id)
5949
{
6050
return -ENODEV;

drivers/gpio/gpiolib.c

Lines changed: 76 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ static int gpiochip_set_desc_names(struct gpio_chip *gc)
366366
static int devprop_gpiochip_set_names(struct gpio_chip *chip)
367367
{
368368
struct gpio_device *gdev = chip->gpiodev;
369-
struct fwnode_handle *fwnode = dev_fwnode(&gdev->dev);
369+
const struct fwnode_handle *fwnode = dev_fwnode(&gdev->dev);
370370
const char **names;
371371
int ret, i;
372372
int count;
@@ -3853,58 +3853,84 @@ static int platform_gpio_count(struct device *dev, const char *con_id)
38533853
return count;
38543854
}
38553855

3856-
/**
3857-
* fwnode_get_named_gpiod - obtain a GPIO from firmware node
3858-
* @fwnode: handle of the firmware node
3859-
* @propname: name of the firmware property representing the GPIO
3860-
* @index: index of the GPIO to obtain for the consumer
3861-
* @dflags: GPIO initialization flags
3862-
* @label: label to attach to the requested GPIO
3863-
*
3864-
* This function can be used for drivers that get their configuration
3865-
* from opaque firmware.
3866-
*
3867-
* The function properly finds the corresponding GPIO using whatever is the
3868-
* underlying firmware interface and then makes sure that the GPIO
3869-
* descriptor is requested before it is returned to the caller.
3870-
*
3871-
* Returns:
3872-
* On successful request the GPIO pin is configured in accordance with
3873-
* provided @dflags.
3874-
*
3875-
* In case of error an ERR_PTR() is returned.
3876-
*/
3877-
static struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
3878-
const char *propname, int index,
3879-
enum gpiod_flags dflags,
3880-
const char *label)
3856+
static struct gpio_desc *gpiod_find_by_fwnode(struct fwnode_handle *fwnode,
3857+
struct device *consumer,
3858+
const char *con_id,
3859+
unsigned int idx,
3860+
enum gpiod_flags *flags,
3861+
unsigned long *lookupflags)
38813862
{
3882-
unsigned long lflags = GPIO_LOOKUP_FLAGS_DEFAULT;
3883-
struct gpio_desc *desc = ERR_PTR(-ENODEV);
3884-
int ret;
3863+
struct gpio_desc *desc = ERR_PTR(-ENOENT);
38853864

38863865
if (is_of_node(fwnode)) {
3887-
desc = gpiod_get_from_of_node(to_of_node(fwnode),
3888-
propname, index,
3889-
dflags,
3890-
label);
3891-
return desc;
3866+
dev_dbg(consumer, "using DT '%pfw' for '%s' GPIO lookup\n",
3867+
fwnode, con_id);
3868+
desc = of_find_gpio(to_of_node(fwnode), con_id, idx, lookupflags);
38923869
} else if (is_acpi_node(fwnode)) {
3893-
desc = acpi_node_get_gpiod(fwnode, propname, index,
3894-
&lflags, &dflags);
3895-
if (IS_ERR(desc))
3896-
return desc;
3897-
} else {
3898-
return ERR_PTR(-EINVAL);
3870+
dev_dbg(consumer, "using ACPI '%pfw' for '%s' GPIO lookup\n",
3871+
fwnode, con_id);
3872+
desc = acpi_find_gpio(fwnode, con_id, idx, flags, lookupflags);
38993873
}
39003874

3901-
/* Currently only ACPI takes this path */
3875+
return desc;
3876+
}
3877+
3878+
static struct gpio_desc *gpiod_find_and_request(struct device *consumer,
3879+
struct fwnode_handle *fwnode,
3880+
const char *con_id,
3881+
unsigned int idx,
3882+
enum gpiod_flags flags,
3883+
const char *label,
3884+
bool platform_lookup_allowed)
3885+
{
3886+
struct gpio_desc *desc = ERR_PTR(-ENOENT);
3887+
unsigned long lookupflags;
3888+
int ret;
3889+
3890+
if (!IS_ERR_OR_NULL(fwnode))
3891+
desc = gpiod_find_by_fwnode(fwnode, consumer, con_id, idx,
3892+
&flags, &lookupflags);
3893+
3894+
if (gpiod_not_found(desc) && platform_lookup_allowed) {
3895+
/*
3896+
* Either we are not using DT or ACPI, or their lookup did not
3897+
* return a result. In that case, use platform lookup as a
3898+
* fallback.
3899+
*/
3900+
dev_dbg(consumer, "using lookup tables for GPIO lookup\n");
3901+
desc = gpiod_find(consumer, con_id, idx, &lookupflags);
3902+
}
3903+
3904+
if (IS_ERR(desc)) {
3905+
dev_dbg(consumer, "No GPIO consumer %s found\n", con_id);
3906+
return desc;
3907+
}
3908+
3909+
/*
3910+
* If a connection label was passed use that, else attempt to use
3911+
* the device name as label
3912+
*/
39023913
ret = gpiod_request(desc, label);
3903-
if (ret)
3904-
return ERR_PTR(ret);
3914+
if (ret) {
3915+
if (!(ret == -EBUSY && flags & GPIOD_FLAGS_BIT_NONEXCLUSIVE))
3916+
return ERR_PTR(ret);
3917+
3918+
/*
3919+
* This happens when there are several consumers for
3920+
* the same GPIO line: we just return here without
3921+
* further initialization. It is a bit of a hack.
3922+
* This is necessary to support fixed regulators.
3923+
*
3924+
* FIXME: Make this more sane and safe.
3925+
*/
3926+
dev_info(consumer,
3927+
"nonexclusive access to GPIO for %s\n", con_id);
3928+
return desc;
3929+
}
39053930

3906-
ret = gpiod_configure_flags(desc, propname, lflags, dflags);
3931+
ret = gpiod_configure_flags(desc, con_id, lookupflags, flags);
39073932
if (ret < 0) {
3933+
dev_dbg(consumer, "setup of GPIO %s failed\n", con_id);
39083934
gpiod_put(desc);
39093935
return ERR_PTR(ret);
39103936
}
@@ -3937,29 +3963,12 @@ static struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
39373963
* In case of error an ERR_PTR() is returned.
39383964
*/
39393965
struct gpio_desc *fwnode_gpiod_get_index(struct fwnode_handle *fwnode,
3940-
const char *con_id, int index,
3966+
const char *con_id,
3967+
int index,
39413968
enum gpiod_flags flags,
39423969
const char *label)
39433970
{
3944-
struct gpio_desc *desc;
3945-
char prop_name[32]; /* 32 is max size of property name */
3946-
unsigned int i;
3947-
3948-
for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) {
3949-
if (con_id)
3950-
snprintf(prop_name, sizeof(prop_name), "%s-%s",
3951-
con_id, gpio_suffixes[i]);
3952-
else
3953-
snprintf(prop_name, sizeof(prop_name), "%s",
3954-
gpio_suffixes[i]);
3955-
3956-
desc = fwnode_get_named_gpiod(fwnode, prop_name, index, flags,
3957-
label);
3958-
if (!gpiod_not_found(desc))
3959-
break;
3960-
}
3961-
3962-
return desc;
3971+
return gpiod_find_and_request(NULL, fwnode, con_id, index, flags, label, false);
39633972
}
39643973
EXPORT_SYMBOL_GPL(fwnode_gpiod_get_index);
39653974

@@ -4113,72 +4122,11 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
41134122
unsigned int idx,
41144123
enum gpiod_flags flags)
41154124
{
4116-
unsigned long lookupflags = GPIO_LOOKUP_FLAGS_DEFAULT;
4117-
struct gpio_desc *desc = NULL;
4118-
int ret;
4119-
/* Maybe we have a device name, maybe not */
4120-
const char *devname = dev ? dev_name(dev) : "?";
41214125
struct fwnode_handle *fwnode = dev ? dev_fwnode(dev) : NULL;
4126+
const char *devname = dev ? dev_name(dev) : "?";
4127+
const char *label = con_id ?: devname;
41224128

4123-
dev_dbg(dev, "GPIO lookup for consumer %s\n", con_id);
4124-
4125-
/* Using device tree? */
4126-
if (is_of_node(fwnode)) {
4127-
dev_dbg(dev, "using device tree for GPIO lookup\n");
4128-
desc = of_find_gpio(to_of_node(fwnode),
4129-
con_id, idx, &lookupflags);
4130-
} else if (is_acpi_node(fwnode)) {
4131-
dev_dbg(dev, "using ACPI for GPIO lookup\n");
4132-
desc = acpi_find_gpio(fwnode,
4133-
con_id, idx, &flags, &lookupflags);
4134-
}
4135-
4136-
/*
4137-
* Either we are not using DT or ACPI, or their lookup did not return
4138-
* a result. In that case, use platform lookup as a fallback.
4139-
*/
4140-
if (!desc || gpiod_not_found(desc)) {
4141-
dev_dbg(dev, "using lookup tables for GPIO lookup\n");
4142-
desc = gpiod_find(dev, con_id, idx, &lookupflags);
4143-
}
4144-
4145-
if (IS_ERR(desc)) {
4146-
dev_dbg(dev, "No GPIO consumer %s found\n", con_id);
4147-
return desc;
4148-
}
4149-
4150-
/*
4151-
* If a connection label was passed use that, else attempt to use
4152-
* the device name as label
4153-
*/
4154-
ret = gpiod_request(desc, con_id ?: devname);
4155-
if (ret) {
4156-
if (!(ret == -EBUSY && flags & GPIOD_FLAGS_BIT_NONEXCLUSIVE))
4157-
return ERR_PTR(ret);
4158-
4159-
/*
4160-
* This happens when there are several consumers for
4161-
* the same GPIO line: we just return here without
4162-
* further initialization. It is a bit of a hack.
4163-
* This is necessary to support fixed regulators.
4164-
*
4165-
* FIXME: Make this more sane and safe.
4166-
*/
4167-
dev_info(dev, "nonexclusive access to GPIO for %s\n", con_id ?: devname);
4168-
return desc;
4169-
}
4170-
4171-
ret = gpiod_configure_flags(desc, con_id, lookupflags, flags);
4172-
if (ret < 0) {
4173-
dev_dbg(dev, "setup of GPIO %s failed\n", con_id);
4174-
gpiod_put(desc);
4175-
return ERR_PTR(ret);
4176-
}
4177-
4178-
blocking_notifier_call_chain(&desc->gdev->notifier,
4179-
GPIOLINE_CHANGED_REQUESTED, desc);
4180-
4181-
return desc;
4129+
return gpiod_find_and_request(dev, fwnode, con_id, idx, flags, label, true);
41824130
}
41834131
EXPORT_SYMBOL_GPL(gpiod_get_index);
41844132

0 commit comments

Comments
 (0)