Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+72 -76
+71 -75
drivers/gpio/gpiolib-acpi.c
··· 96 96 * @adev: reference to ACPI device which consumes GPIO resource 97 97 * @flags: GPIO initialization flags 98 98 * @gpioint: if %true this GPIO is of type GpioInt otherwise type is GpioIo 99 + * @wake_capable: wake capability as provided by ACPI 99 100 * @pin_config: pin bias as provided by ACPI 100 101 * @polarity: interrupt polarity as provided by ACPI 101 102 * @triggering: triggering type as provided by ACPI 102 - * @wake_capable: wake capability as provided by ACPI 103 103 * @debounce: debounce timeout as provided by ACPI 104 104 * @quirks: Linux specific quirks as provided by struct acpi_gpio_mapping 105 105 */ ··· 107 107 struct acpi_device *adev; 108 108 enum gpiod_flags flags; 109 109 bool gpioint; 110 + bool wake_capable; 110 111 int pin_config; 111 112 int polarity; 112 113 int triggering; 113 - bool wake_capable; 114 114 unsigned int debounce; 115 115 unsigned int quirks; 116 116 }; ··· 653 653 654 654 for (gm = adev->driver_gpios; gm->name; gm++) 655 655 if (!strcmp(name, gm->name) && gm->data && index < gm->size) { 656 - const struct acpi_gpio_params *par = gm->data + index; 656 + const struct acpi_gpio_params *params = gm->data + index; 657 657 658 658 args->fwnode = acpi_fwnode_handle(adev); 659 - args->args[0] = par->crs_entry_index; 660 - args->args[1] = par->line_index; 661 - args->args[2] = par->active_low; 659 + args->args[0] = params->crs_entry_index; 660 + args->args[1] = params->line_index; 661 + args->args[2] = params->active_low; 662 662 args->nargs = 3; 663 663 664 664 *quirks = gm->quirks; ··· 744 744 745 745 struct acpi_gpio_lookup { 746 746 struct acpi_gpio_info info; 747 - int index; 748 - u16 pin_index; 749 - bool active_low; 747 + struct acpi_gpio_params params; 750 748 struct gpio_desc *desc; 751 749 int n; 752 750 }; ··· 752 754 static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data) 753 755 { 754 756 struct acpi_gpio_lookup *lookup = data; 757 + struct acpi_gpio_params *params = &lookup->params; 755 758 756 759 if (ares->type != ACPI_RESOURCE_TYPE_GPIO) 757 760 return 1; ··· 764 765 u16 pin_index; 765 766 766 767 if (lookup->info.quirks & ACPI_GPIO_QUIRK_ONLY_GPIOIO && gpioint) 767 - lookup->index++; 768 + params->crs_entry_index++; 768 769 769 - if (lookup->n++ != lookup->index) 770 + if (lookup->n++ != params->crs_entry_index) 770 771 return 1; 771 772 772 - pin_index = lookup->pin_index; 773 + pin_index = params->line_index; 773 774 if (pin_index >= agpio->pin_table_length) 774 775 return 1; 775 776 ··· 795 796 lookup->info.polarity = agpio->polarity; 796 797 lookup->info.triggering = agpio->triggering; 797 798 } else { 798 - lookup->info.polarity = lookup->active_low; 799 + lookup->info.polarity = params->active_low; 799 800 } 800 801 801 802 lookup->info.flags = acpi_gpio_to_gpiod_flags(agpio, lookup->info.polarity); ··· 804 805 return 1; 805 806 } 806 807 807 - static int acpi_gpio_resource_lookup(struct acpi_gpio_lookup *lookup, 808 - struct acpi_gpio_info *info) 808 + static int acpi_gpio_resource_lookup(struct acpi_gpio_lookup *lookup) 809 809 { 810 810 struct acpi_device *adev = lookup->info.adev; 811 811 struct list_head res_list; ··· 823 825 if (!lookup->desc) 824 826 return -ENOENT; 825 827 826 - if (info) 827 - *info = lookup->info; 828 828 return 0; 829 829 } 830 830 831 - static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode, 832 - const char *propname, int index, 831 + static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode, const char *propname, 833 832 struct acpi_gpio_lookup *lookup) 834 833 { 835 834 struct fwnode_reference_args args; 835 + struct acpi_gpio_params *params = &lookup->params; 836 + unsigned int index = params->crs_entry_index; 836 837 unsigned int quirks = 0; 837 838 int ret; 838 839 839 840 memset(&args, 0, sizeof(args)); 840 - ret = __acpi_node_get_property_reference(fwnode, propname, index, 3, 841 - &args); 841 + 842 + ret = __acpi_node_get_property_reference(fwnode, propname, index, 3, &args); 842 843 if (ret) { 843 844 struct acpi_device *adev; 844 845 ··· 854 857 if (args.nargs != 3) 855 858 return -EPROTO; 856 859 857 - lookup->index = args.args[0]; 858 - lookup->pin_index = args.args[1]; 859 - lookup->active_low = !!args.args[2]; 860 + params->crs_entry_index = args.args[0]; 861 + params->line_index = args.args[1]; 862 + params->active_low = !!args.args[2]; 860 863 861 864 lookup->info.adev = to_acpi_device_node(args.fwnode); 862 865 lookup->info.quirks = quirks; ··· 868 871 * acpi_get_gpiod_by_index() - get a GPIO descriptor from device resources 869 872 * @adev: pointer to a ACPI device to get GPIO from 870 873 * @propname: Property name of the GPIO (optional) 871 - * @index: index of GpioIo/GpioInt resource (starting from %0) 872 - * @info: info pointer to fill in (optional) 874 + * @lookup: pointer to struct acpi_gpio_lookup to fill in 873 875 * 874 - * Function goes through ACPI resources for @adev and based on @index looks 876 + * Function goes through ACPI resources for @adev and based on @lookup.index looks 875 877 * up a GpioIo/GpioInt resource, translates it to the Linux GPIO descriptor, 876 - * and returns it. @index matches GpioIo/GpioInt resources only so if there 877 - * are total %3 GPIO resources, the index goes from %0 to %2. 878 + * and returns it. @lookup.index matches GpioIo/GpioInt resources only so if there 879 + * are total 3 GPIO resources, the index goes from 0 to 2. 878 880 * 879 881 * If @propname is specified the GPIO is looked using device property. In 880 882 * that case @index is used to select the GPIO entry in the property value 881 883 * (in case of multiple). 882 884 * 883 885 * Returns: 884 - * GPIO descriptor to use with Linux generic GPIO API. 885 - * If the GPIO cannot be translated or there is an error an ERR_PTR is 886 - * returned. 886 + * 0 on success, negative errno on failure. 887 + * 888 + * The @lookup is filled with GPIO descriptor to use with Linux generic GPIO API. 889 + * If the GPIO cannot be translated an error will be returned. 887 890 * 888 891 * Note: if the GPIO resource has multiple entries in the pin list, this 889 892 * function only returns the first. 890 893 */ 891 - static struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev, 892 - const char *propname, 893 - int index, 894 - struct acpi_gpio_info *info) 894 + static int acpi_get_gpiod_by_index(struct acpi_device *adev, const char *propname, 895 + struct acpi_gpio_lookup *lookup) 895 896 { 896 - struct acpi_gpio_lookup lookup; 897 + struct acpi_gpio_info *info = &lookup->info; 898 + struct acpi_gpio_params *params = &lookup->params; 897 899 int ret; 898 - 899 - memset(&lookup, 0, sizeof(lookup)); 900 - lookup.index = index; 901 900 902 901 if (propname) { 903 902 dev_dbg(&adev->dev, "GPIO: looking up %s\n", propname); 904 903 905 - ret = acpi_gpio_property_lookup(acpi_fwnode_handle(adev), 906 - propname, index, &lookup); 904 + ret = acpi_gpio_property_lookup(acpi_fwnode_handle(adev), propname, lookup); 907 905 if (ret) 908 - return ERR_PTR(ret); 906 + return ret; 909 907 910 - dev_dbg(&adev->dev, "GPIO: _DSD returned %s %d %u %u\n", 911 - dev_name(&lookup.info.adev->dev), lookup.index, 912 - lookup.pin_index, lookup.active_low); 908 + dev_dbg(&adev->dev, "GPIO: _DSD returned %s %u %u %u\n", 909 + dev_name(&info->adev->dev), 910 + params->crs_entry_index, params->line_index, params->active_low); 913 911 } else { 914 - dev_dbg(&adev->dev, "GPIO: looking up %d in _CRS\n", index); 915 - lookup.info.adev = adev; 912 + dev_dbg(&adev->dev, "GPIO: looking up %u in _CRS\n", params->crs_entry_index); 913 + info->adev = adev; 916 914 } 917 915 918 - ret = acpi_gpio_resource_lookup(&lookup, info); 919 - return ret ? ERR_PTR(ret) : lookup.desc; 916 + return acpi_gpio_resource_lookup(lookup); 920 917 } 921 918 922 919 /** 923 920 * acpi_get_gpiod_from_data() - get a GPIO descriptor from ACPI data node 924 921 * @fwnode: pointer to an ACPI firmware node to get the GPIO information from 925 922 * @propname: Property name of the GPIO 926 - * @index: index of GpioIo/GpioInt resource (starting from %0) 927 - * @info: info pointer to fill in (optional) 923 + * @lookup: pointer to struct acpi_gpio_lookup to fill in 928 924 * 929 925 * This function uses the property-based GPIO lookup to get to the GPIO 930 926 * resource with the relevant information from a data-only ACPI firmware node 931 927 * and uses that to obtain the GPIO descriptor to return. 932 928 * 933 929 * Returns: 934 - * GPIO descriptor to use with Linux generic GPIO API. 935 - * If the GPIO cannot be translated or there is an error an ERR_PTR is 936 - * returned. 930 + * 0 on success, negative errno on failure. 931 + * 932 + * The @lookup is filled with GPIO descriptor to use with Linux generic GPIO API. 933 + * If the GPIO cannot be translated an error will be returned. 937 934 */ 938 - static struct gpio_desc *acpi_get_gpiod_from_data(struct fwnode_handle *fwnode, 939 - const char *propname, 940 - int index, 941 - struct acpi_gpio_info *info) 935 + static int acpi_get_gpiod_from_data(struct fwnode_handle *fwnode, const char *propname, 936 + struct acpi_gpio_lookup *lookup) 942 937 { 943 - struct acpi_gpio_lookup lookup; 944 938 int ret; 945 939 946 940 if (!is_acpi_data_node(fwnode)) 947 - return ERR_PTR(-ENODEV); 941 + return -ENODEV; 948 942 949 943 if (!propname) 950 - return ERR_PTR(-EINVAL); 944 + return -EINVAL; 951 945 952 - memset(&lookup, 0, sizeof(lookup)); 953 - lookup.index = index; 954 - 955 - ret = acpi_gpio_property_lookup(fwnode, propname, index, &lookup); 946 + ret = acpi_gpio_property_lookup(fwnode, propname, lookup); 956 947 if (ret) 957 - return ERR_PTR(ret); 948 + return ret; 958 949 959 - ret = acpi_gpio_resource_lookup(&lookup, info); 960 - return ret ? ERR_PTR(ret) : lookup.desc; 950 + return acpi_gpio_resource_lookup(lookup); 961 951 } 962 952 963 953 static bool acpi_can_fallback_to_crs(struct acpi_device *adev, ··· 966 982 bool can_fallback, struct acpi_gpio_info *info) 967 983 { 968 984 struct acpi_device *adev = to_acpi_device_node(fwnode); 985 + struct acpi_gpio_lookup lookup; 969 986 struct gpio_desc *desc; 970 987 char propname[32]; 988 + int ret; 989 + 990 + memset(&lookup, 0, sizeof(lookup)); 991 + lookup.params.crs_entry_index = idx; 971 992 972 993 /* Try first from _DSD */ 973 994 for_each_gpio_property_name(propname, con_id) { 974 995 if (adev) 975 - desc = acpi_get_gpiod_by_index(adev, 976 - propname, idx, info); 996 + ret = acpi_get_gpiod_by_index(adev, propname, &lookup); 977 997 else 978 - desc = acpi_get_gpiod_from_data(fwnode, 979 - propname, idx, info); 998 + ret = acpi_get_gpiod_from_data(fwnode, propname, &lookup); 999 + if (ret) 1000 + continue; 1001 + 1002 + desc = lookup.desc; 980 1003 if (PTR_ERR(desc) == -EPROBE_DEFER) 981 1004 return desc; 982 1005 ··· 992 1001 } 993 1002 994 1003 /* Then from plain _CRS GPIOs */ 995 - if (can_fallback) 996 - return acpi_get_gpiod_by_index(adev, NULL, idx, info); 1004 + if (can_fallback) { 1005 + ret = acpi_get_gpiod_by_index(adev, NULL, &lookup); 1006 + if (ret) 1007 + return ERR_PTR(ret); 1008 + 1009 + return lookup.desc; 1010 + } 997 1011 998 1012 return ERR_PTR(-ENOENT); 999 1013 }
+1 -1
include/linux/gpio/consumer.h
··· 587 587 588 588 struct acpi_gpio_params { 589 589 unsigned int crs_entry_index; 590 - unsigned int line_index; 590 + unsigned short line_index; 591 591 bool active_low; 592 592 }; 593 593