diff options
author | Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 2025-04-07 09:39:16 +0300 |
---|---|---|
committer | Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 2025-04-07 09:39:16 +0300 |
commit | 71114cd1d386988bc90dca1d1f1fee5fb23817ad (patch) | |
tree | 275c605f2053379a0de8e1afabc267afc3630c2c | |
parent | 0af2f6be1b4281385b618cb86ad946eded089ac8 (diff) | |
parent | 8b4f52ef7a412dd8e0b390ad4815bd74323f6f99 (diff) | |
download | linux-71114cd1d386988bc90dca1d1f1fee5fb23817ad.tar.xz |
Merge patch series "gpiolib: acpi: Refactor to shrink the code by ~8%"
Andy Shevchenko <andriy.shevchenko@linux.intel.com> says:
A simple refactoring of the GPIO ACPI library parts to get an impressive
~8% code shrink on x86_64 and ~2% on x86_32. Also reduces a C code a bit.
add/remove: 0/2 grow/shrink: 0/5 up/down: 0/-1221 (-1221)
Function old new delta
acpi_gpio_property_lookup 425 414 -11
acpi_find_gpio.__UNIQUE_ID_ddebug478 56 - -56
acpi_dev_gpio_irq_wake_get_by.__UNIQUE_ID_ddebug480 56 - -56
acpi_find_gpio 354 216 -138
acpi_get_gpiod_by_index 462 307 -155
__acpi_find_gpio 877 638 -239
acpi_dev_gpio_irq_wake_get_by 695 129 -566
Total: Before=15375, After=14154, chg -7.94%
Link: https://lore.kernel.org/r/20250403160034.2680485-1-andriy.shevchenko@linux.intel.com
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-rw-r--r-- | drivers/gpio/gpiolib-acpi.c | 146 | ||||
-rw-r--r-- | include/linux/gpio/consumer.h | 2 |
2 files changed, 72 insertions, 76 deletions
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 69caa35c58df..b3fcb9d5a39f 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -96,10 +96,10 @@ struct acpi_gpio_chip { * @adev: reference to ACPI device which consumes GPIO resource * @flags: GPIO initialization flags * @gpioint: if %true this GPIO is of type GpioInt otherwise type is GpioIo + * @wake_capable: wake capability as provided by ACPI * @pin_config: pin bias as provided by ACPI * @polarity: interrupt polarity as provided by ACPI * @triggering: triggering type as provided by ACPI - * @wake_capable: wake capability as provided by ACPI * @debounce: debounce timeout as provided by ACPI * @quirks: Linux specific quirks as provided by struct acpi_gpio_mapping */ @@ -107,10 +107,10 @@ struct acpi_gpio_info { struct acpi_device *adev; enum gpiod_flags flags; bool gpioint; + bool wake_capable; int pin_config; int polarity; int triggering; - bool wake_capable; unsigned int debounce; unsigned int quirks; }; @@ -653,12 +653,12 @@ static bool acpi_get_driver_gpio_data(struct acpi_device *adev, for (gm = adev->driver_gpios; gm->name; gm++) if (!strcmp(name, gm->name) && gm->data && index < gm->size) { - const struct acpi_gpio_params *par = gm->data + index; + const struct acpi_gpio_params *params = gm->data + index; args->fwnode = acpi_fwnode_handle(adev); - args->args[0] = par->crs_entry_index; - args->args[1] = par->line_index; - args->args[2] = par->active_low; + args->args[0] = params->crs_entry_index; + args->args[1] = params->line_index; + args->args[2] = params->active_low; args->nargs = 3; *quirks = gm->quirks; @@ -744,9 +744,7 @@ static int acpi_gpio_update_gpiod_lookup_flags(unsigned long *lookupflags, struct acpi_gpio_lookup { struct acpi_gpio_info info; - int index; - u16 pin_index; - bool active_low; + struct acpi_gpio_params params; struct gpio_desc *desc; int n; }; @@ -754,6 +752,7 @@ struct acpi_gpio_lookup { static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data) { struct acpi_gpio_lookup *lookup = data; + struct acpi_gpio_params *params = &lookup->params; if (ares->type != ACPI_RESOURCE_TYPE_GPIO) return 1; @@ -765,12 +764,12 @@ static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data) u16 pin_index; if (lookup->info.quirks & ACPI_GPIO_QUIRK_ONLY_GPIOIO && gpioint) - lookup->index++; + params->crs_entry_index++; - if (lookup->n++ != lookup->index) + if (lookup->n++ != params->crs_entry_index) return 1; - pin_index = lookup->pin_index; + pin_index = params->line_index; if (pin_index >= agpio->pin_table_length) return 1; @@ -796,7 +795,7 @@ static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data) lookup->info.polarity = agpio->polarity; lookup->info.triggering = agpio->triggering; } else { - lookup->info.polarity = lookup->active_low; + lookup->info.polarity = params->active_low; } lookup->info.flags = acpi_gpio_to_gpiod_flags(agpio, lookup->info.polarity); @@ -805,8 +804,7 @@ static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data) return 1; } -static int acpi_gpio_resource_lookup(struct acpi_gpio_lookup *lookup, - struct acpi_gpio_info *info) +static int acpi_gpio_resource_lookup(struct acpi_gpio_lookup *lookup) { struct acpi_device *adev = lookup->info.adev; struct list_head res_list; @@ -825,22 +823,21 @@ static int acpi_gpio_resource_lookup(struct acpi_gpio_lookup *lookup, if (!lookup->desc) return -ENOENT; - if (info) - *info = lookup->info; return 0; } -static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode, - const char *propname, int index, +static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode, const char *propname, struct acpi_gpio_lookup *lookup) { struct fwnode_reference_args args; + struct acpi_gpio_params *params = &lookup->params; + unsigned int index = params->crs_entry_index; unsigned int quirks = 0; int ret; memset(&args, 0, sizeof(args)); - ret = __acpi_node_get_property_reference(fwnode, propname, index, 3, - &args); + + ret = __acpi_node_get_property_reference(fwnode, propname, index, 3, &args); if (ret) { struct acpi_device *adev; @@ -857,9 +854,9 @@ static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode, if (args.nargs != 3) return -EPROTO; - lookup->index = args.args[0]; - lookup->pin_index = args.args[1]; - lookup->active_low = !!args.args[2]; + params->crs_entry_index = args.args[0]; + params->line_index = args.args[1]; + params->active_low = !!args.args[2]; lookup->info.adev = to_acpi_device_node(args.fwnode); lookup->info.quirks = quirks; @@ -871,96 +868,83 @@ static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode, * acpi_get_gpiod_by_index() - get a GPIO descriptor from device resources * @adev: pointer to a ACPI device to get GPIO from * @propname: Property name of the GPIO (optional) - * @index: index of GpioIo/GpioInt resource (starting from %0) - * @info: info pointer to fill in (optional) + * @lookup: pointer to struct acpi_gpio_lookup to fill in * - * Function goes through ACPI resources for @adev and based on @index looks + * Function goes through ACPI resources for @adev and based on @lookup.index looks * up a GpioIo/GpioInt resource, translates it to the Linux GPIO descriptor, - * and returns it. @index matches GpioIo/GpioInt resources only so if there - * are total %3 GPIO resources, the index goes from %0 to %2. + * and returns it. @lookup.index matches GpioIo/GpioInt resources only so if there + * are total 3 GPIO resources, the index goes from 0 to 2. * * If @propname is specified the GPIO is looked using device property. In * that case @index is used to select the GPIO entry in the property value * (in case of multiple). * * Returns: - * GPIO descriptor to use with Linux generic GPIO API. - * If the GPIO cannot be translated or there is an error an ERR_PTR is - * returned. + * 0 on success, negative errno on failure. + * + * The @lookup is filled with GPIO descriptor to use with Linux generic GPIO API. + * If the GPIO cannot be translated an error will be returned. * * Note: if the GPIO resource has multiple entries in the pin list, this * function only returns the first. */ -static struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev, - const char *propname, - int index, - struct acpi_gpio_info *info) +static int acpi_get_gpiod_by_index(struct acpi_device *adev, const char *propname, + struct acpi_gpio_lookup *lookup) { - struct acpi_gpio_lookup lookup; + struct acpi_gpio_info *info = &lookup->info; + struct acpi_gpio_params *params = &lookup->params; int ret; - memset(&lookup, 0, sizeof(lookup)); - lookup.index = index; - if (propname) { dev_dbg(&adev->dev, "GPIO: looking up %s\n", propname); - ret = acpi_gpio_property_lookup(acpi_fwnode_handle(adev), - propname, index, &lookup); + ret = acpi_gpio_property_lookup(acpi_fwnode_handle(adev), propname, lookup); if (ret) - return ERR_PTR(ret); + return ret; - dev_dbg(&adev->dev, "GPIO: _DSD returned %s %d %u %u\n", - dev_name(&lookup.info.adev->dev), lookup.index, - lookup.pin_index, lookup.active_low); + dev_dbg(&adev->dev, "GPIO: _DSD returned %s %u %u %u\n", + dev_name(&info->adev->dev), + params->crs_entry_index, params->line_index, params->active_low); } else { - dev_dbg(&adev->dev, "GPIO: looking up %d in _CRS\n", index); - lookup.info.adev = adev; + dev_dbg(&adev->dev, "GPIO: looking up %u in _CRS\n", params->crs_entry_index); + info->adev = adev; } - ret = acpi_gpio_resource_lookup(&lookup, info); - return ret ? ERR_PTR(ret) : lookup.desc; + return acpi_gpio_resource_lookup(lookup); } /** * acpi_get_gpiod_from_data() - get a GPIO descriptor from ACPI data node * @fwnode: pointer to an ACPI firmware node to get the GPIO information from * @propname: Property name of the GPIO - * @index: index of GpioIo/GpioInt resource (starting from %0) - * @info: info pointer to fill in (optional) + * @lookup: pointer to struct acpi_gpio_lookup to fill in * * This function uses the property-based GPIO lookup to get to the GPIO * resource with the relevant information from a data-only ACPI firmware node * and uses that to obtain the GPIO descriptor to return. * * Returns: - * GPIO descriptor to use with Linux generic GPIO API. - * If the GPIO cannot be translated or there is an error an ERR_PTR is - * returned. + * 0 on success, negative errno on failure. + * + * The @lookup is filled with GPIO descriptor to use with Linux generic GPIO API. + * If the GPIO cannot be translated an error will be returned. */ -static struct gpio_desc *acpi_get_gpiod_from_data(struct fwnode_handle *fwnode, - const char *propname, - int index, - struct acpi_gpio_info *info) +static int acpi_get_gpiod_from_data(struct fwnode_handle *fwnode, const char *propname, + struct acpi_gpio_lookup *lookup) { - struct acpi_gpio_lookup lookup; int ret; if (!is_acpi_data_node(fwnode)) - return ERR_PTR(-ENODEV); + return -ENODEV; if (!propname) - return ERR_PTR(-EINVAL); - - memset(&lookup, 0, sizeof(lookup)); - lookup.index = index; + return -EINVAL; - ret = acpi_gpio_property_lookup(fwnode, propname, index, &lookup); + ret = acpi_gpio_property_lookup(fwnode, propname, lookup); if (ret) - return ERR_PTR(ret); + return ret; - ret = acpi_gpio_resource_lookup(&lookup, info); - return ret ? ERR_PTR(ret) : lookup.desc; + return acpi_gpio_resource_lookup(lookup); } static bool acpi_can_fallback_to_crs(struct acpi_device *adev, @@ -982,17 +966,24 @@ __acpi_find_gpio(struct fwnode_handle *fwnode, const char *con_id, unsigned int bool can_fallback, struct acpi_gpio_info *info) { struct acpi_device *adev = to_acpi_device_node(fwnode); + struct acpi_gpio_lookup lookup; struct gpio_desc *desc; char propname[32]; + int ret; + + memset(&lookup, 0, sizeof(lookup)); + lookup.params.crs_entry_index = idx; /* Try first from _DSD */ for_each_gpio_property_name(propname, con_id) { if (adev) - desc = acpi_get_gpiod_by_index(adev, - propname, idx, info); + ret = acpi_get_gpiod_by_index(adev, propname, &lookup); else - desc = acpi_get_gpiod_from_data(fwnode, - propname, idx, info); + ret = acpi_get_gpiod_from_data(fwnode, propname, &lookup); + if (ret) + continue; + + desc = lookup.desc; if (PTR_ERR(desc) == -EPROBE_DEFER) return desc; @@ -1001,8 +992,13 @@ __acpi_find_gpio(struct fwnode_handle *fwnode, const char *con_id, unsigned int } /* Then from plain _CRS GPIOs */ - if (can_fallback) - return acpi_get_gpiod_by_index(adev, NULL, idx, info); + if (can_fallback) { + ret = acpi_get_gpiod_by_index(adev, NULL, &lookup); + if (ret) + return ERR_PTR(ret); + + return lookup.desc; + } return ERR_PTR(-ENOENT); } diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index 45b651c05b9c..899179972bec 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -587,7 +587,7 @@ struct gpio_desc *devm_fwnode_gpiod_get(struct device *dev, struct acpi_gpio_params { unsigned int crs_entry_index; - unsigned int line_index; + unsigned short line_index; bool active_low; }; |