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>
This commit is contained in:
Andy Shevchenko
2025-04-07 09:39:16 +03:00
2 changed files with 72 additions and 76 deletions

View File

@@ -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);
return -EINVAL;
memset(&lookup, 0, sizeof(lookup));
lookup.index = index;
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);
}

View File

@@ -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;
};