mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-10 15:13:44 -04:00
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:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user