gpiolib: add gpiod_get_array and gpiod_put_array functions
Subsystems (2)
PATCH v4 2/4 gpiolib: add gpiod_get_array and gpiod_put_array functions
Introduce new functions for conveniently obtaining and disposing of an entire array of GPIOs with one function call.
---
Change log:
v4: - use shorter names for members of struct gpio_descs
- rename lut_gpio_count to platform_gpio_count for clarity
- add check for successful memory allocation
- use ERR_CAST()
v3: - rebase on current linux-gpio devel branch
- fix ACPI GPIO counting
- allow for zero-sized arrays
- make the flags argument mandatory for the new functions
- clarify documentation
v2: change interface
Documentation/gpio/consumer.txt | 33 +++++ drivers/gpio/gpiolib.c | 233 ++++++++++++++++++++++++++++++++++++++++ include/linux/gpio/consumer.h | 46 +++++++ 3 files changed, 309 insertions(+), 3 deletions(-)
Documentation/gpio/consumer.txt +30 -3
@@ -58,7 +58,6 @@ pattern where a GPIO is optional, the gpiod_get_optional() and gpiod_get_index_optional() functions can be used. These functions return NULL instead of -ENOENT if no GPIO has been assigned to the requested function: - struct gpio_desc *gpiod_get_optional(struct device *dev, const char *con_id, enum gpiod_flags flags)
@@ -68,6 +67,27 @@ instead of -ENOENT if no GPIO has been assigned to the requested function: unsigned int index, enum gpiod_flags flags) +For a function using multiple GPIOs all of those can be obtained with one call: + + struct gpio_descs *gpiod_get_array(struct device *dev, + const char *con_id, + enum gpiod_flags flags) + +This function returns a struct gpio_descs which contains an array of +descriptors: + + struct gpio_descs { + unsigned int ndescs; + struct gpio_desc *desc[]; + } + +The following function returns NULL instead of -ENOENT if no GPIOs have been +assigned to the requested function: + + struct gpio_descs *gpiod_get_array_optional(struct device *dev, + const char *con_id, + enum gpiod_flags flags) + Device-managed variants of these functions are also defined: struct gpio_desc *devm_gpiod_get(struct device *dev, const char *con_id,
@@ -91,8 +111,15 @@ A GPIO descriptor can be disposed of using the gpiod_put() function: void gpiod_put(struct gpio_desc *desc) -It is strictly forbidden to use a descriptor after calling this function. The -device-managed variant is, unsurprisingly: +For an array of GPIOs this function can be used: + + void gpiod_put_array(struct gpio_descs *descs) + +It is strictly forbidden to use a descriptor after calling these functions. +It is also not allowed to individually release descriptors (using gpiod_put()) +from an array acquired with gpiod_get_array(). + +The device-managed variant is, unsurprisingly: void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
drivers/gpio/gpiolib.c +233 -0
251 lines not on this page · raw message
include/linux/gpio/consumer.h +46 -0
83 lines not on this page · raw message
Signature · 1 line
2.0.5
Quoted 77 lines · Rojhalat Ibrahim
drivers/gpio/gpiolib.c +77
-0+#ifdef CONFIG_ACPI + +static unsigned int acpi_gpio_package_count (const union acpi_object *obj) +{ +const union acpi_object *element = obj->package.elements; +const union acpi_object *end = element + obj->package.count; +unsigned int count =0 ; + +while (element < end) { +if (element->type ==ACPI_TYPE_LOCAL_REFERENCE ) + count++; + + element++; + } +return count; +} + +static int acpi_find_gpio_count (struct acpi_resource *ares,void *data) +{ +unsigned int *count = data; + +if (ares->type ==ACPI_RESOURCE_TYPE_GPIO ) + *count += ares->data.gpio.pin_table_length; + +return 1 ; +} + +static int acpi_gpio_count (struct device *dev,const char *con_id) +{ +struct acpi_device *adev =ACPI_COMPANION (dev); +const union acpi_object *obj; +const struct acpi_gpio_mapping *gm; +int count = -ENOENT ; +int ret; +char propname[32 ]; +unsigned int i; + +/* Try first from _DSD */ +for (i =0 ; i <ARRAY_SIZE (gpio_suffixes); i++) { +if (con_id &&strcmp (con_id,"gpios" )) +snprintf (propname,sizeof (propname),"%s-%s" , + con_id, gpio_suffixes[i]); +else +snprintf (propname,sizeof (propname),"%s" , + gpio_suffixes[i]); + + ret =acpi_dev_get_property (adev, propname,ACPI_TYPE_ANY , + &obj); +if (ret ==0 ) { +if (obj->type ==ACPI_TYPE_LOCAL_REFERENCE ) + count =1 ; +else if (obj->type ==ACPI_TYPE_PACKAGE ) + count =acpi_gpio_package_count (obj); + }else if (adev->driver_gpios) { +for (gm = adev->driver_gpios; gm->name; gm++) +if (strcmp (propname, gm->name) ==0 ) { + count = gm->size; +break ; + } + } +if (count >=0 ) +break ; + } + +/* Then from plain _CRS GPIOs */ +if (count <0 ) { +struct list_head resource_list; +unsigned int crs_count =0 ; + +INIT_LIST_HEAD (&resource_list); +acpi_dev_get_resources (adev, &resource_list, + acpi_find_gpio_count, &crs_count); +acpi_dev_free_resource_list (&resource_list); +if (crs_count >0 ) + count = crs_count; + } +return count;
drivers/gpio/gpiolib.c static struct gpio_desc *gpiod_find(struct device *dev, const char *con_id, · line 1914
Quoted 10 lines
drivers/gpio/gpiolib.c +10
-0+} + +#else + +static int acpi_gpio_count (struct device *dev,const char *con_id) +{ +return -ENODEV ; +} + +#endif
It just occured to me that it would be better to put this code to gpiolib-acpi.c and declare acpi_gpio_count() in drivers/gpio/gpiolib.h.
That said, I tested this code on Lenovo Thinkpad10 by converting drivers/input/misc/soc_button_array.c to fetch its GPIOs using this new API -- it works just fine (and looks better).
Once you have done the above change you can add for the ACPI parts,
Quoted 83 lines · On Wednesday 11 February 2015 12:30:01 Mika Westerberg wrote:
Quoted 82 lines · Rojhalat Ibrahim
drivers/gpio/gpiolib.c +82
-0+#ifdef CONFIG_ACPI + +static unsigned int acpi_gpio_package_count (const union acpi_object *obj) +{ +const union acpi_object *element = obj->package.elements; +const union acpi_object *end = element + obj->package.count; +unsigned int count =0 ; + +while (element < end) { +if (element->type ==ACPI_TYPE_LOCAL_REFERENCE ) + count++; + + element++; + } +return count; +} + +static int acpi_find_gpio_count (struct acpi_resource *ares,void *data) +{ +unsigned int *count = data; + +if (ares->type ==ACPI_RESOURCE_TYPE_GPIO ) + *count += ares->data.gpio.pin_table_length; + +return 1 ; +} + +static int acpi_gpio_count (struct device *dev,const char *con_id) +{ +struct acpi_device *adev =ACPI_COMPANION (dev); +const union acpi_object *obj; +const struct acpi_gpio_mapping *gm; +int count = -ENOENT ; +int ret; +char propname[32 ]; +unsigned int i; + +/* Try first from _DSD */ +for (i =0 ; i <ARRAY_SIZE (gpio_suffixes); i++) { +if (con_id &&strcmp (con_id,"gpios" )) +snprintf (propname,sizeof (propname),"%s-%s" , + con_id, gpio_suffixes[i]); +else +snprintf (propname,sizeof (propname),"%s" , + gpio_suffixes[i]); + + ret =acpi_dev_get_property (adev, propname,ACPI_TYPE_ANY , + &obj); +if (ret ==0 ) { +if (obj->type ==ACPI_TYPE_LOCAL_REFERENCE ) + count =1 ; +else if (obj->type ==ACPI_TYPE_PACKAGE ) + count =acpi_gpio_package_count (obj); + }else if (adev->driver_gpios) { +for (gm = adev->driver_gpios; gm->name; gm++) +if (strcmp (propname, gm->name) ==0 ) { + count = gm->size; +break ; + } + } +if (count >=0 ) +break ; + } + +/* Then from plain _CRS GPIOs */ +if (count <0 ) { +struct list_head resource_list; +unsigned int crs_count =0 ; + +INIT_LIST_HEAD (&resource_list); +acpi_dev_get_resources (adev, &resource_list, + acpi_find_gpio_count, &crs_count); +acpi_dev_free_resource_list (&resource_list); +if (crs_count >0 ) + count = crs_count; + } +return count; +} + +#else + +static int acpi_gpio_count (struct device *dev,const char *con_id)
Quoted 9 lines
drivers/gpio/gpiolib.c static struct gpio_desc *gpiod_find(struct device *dev, const char *con_id, · line 1914
Quoted 5 lines
drivers/gpio/gpiolib.c +5
-0+{ +return -ENODEV ; +} + +#endif It just occured to me that it would be better to put this code to
gpiolib-acpi.cand declareacpi_gpio_count()indrivers/gpio/gpiolib.h.
Ok. I will also have to move the definition of gpio_suffixes[] (PATCH 1/4) to drivers/gpio/gpiolib.h since it is needed by both the OF and the ACPI portions of the code.
Quoted 9 lines
That said, I tested this code on Lenovo Thinkpad10 by converting
drivers/input/misc/soc_button_array.cto fetch its GPIOs using this new API -- it works just fine (and looks better).Once you have done the above change you can add for the ACPI parts,
Reviewed-by Mika Westerberg <[email protected]>Tested-by Mika Westerberg <[email protected]>
Great. Thanks.
Quoted 94 lines · Rojhalat Ibrahim
Quoted 83 lines · On Wednesday 11 February 2015 12:30:01 Mika Westerberg wrote:
Quoted 82 lines · Rojhalat Ibrahim
drivers/gpio/gpiolib.c +82
-0+#ifdef CONFIG_ACPI + +static unsigned int acpi_gpio_package_count (const union acpi_object *obj) +{ +const union acpi_object *element = obj->package.elements; +const union acpi_object *end = element + obj->package.count; +unsigned int count =0 ; + +while (element < end) { +if (element->type ==ACPI_TYPE_LOCAL_REFERENCE ) + count++; + + element++; + } +return count; +} + +static int acpi_find_gpio_count (struct acpi_resource *ares,void *data) +{ +unsigned int *count = data; + +if (ares->type ==ACPI_RESOURCE_TYPE_GPIO ) + *count += ares->data.gpio.pin_table_length; + +return 1 ; +} + +static int acpi_gpio_count (struct device *dev,const char *con_id) +{ +struct acpi_device *adev =ACPI_COMPANION (dev); +const union acpi_object *obj; +const struct acpi_gpio_mapping *gm; +int count = -ENOENT ; +int ret; +char propname[32 ]; +unsigned int i; + +/* Try first from _DSD */ +for (i =0 ; i <ARRAY_SIZE (gpio_suffixes); i++) { +if (con_id &&strcmp (con_id,"gpios" )) +snprintf (propname,sizeof (propname),"%s-%s" , + con_id, gpio_suffixes[i]); +else +snprintf (propname,sizeof (propname),"%s" , + gpio_suffixes[i]); + + ret =acpi_dev_get_property (adev, propname,ACPI_TYPE_ANY , + &obj); +if (ret ==0 ) { +if (obj->type ==ACPI_TYPE_LOCAL_REFERENCE ) + count =1 ; +else if (obj->type ==ACPI_TYPE_PACKAGE ) + count =acpi_gpio_package_count (obj); + }else if (adev->driver_gpios) { +for (gm = adev->driver_gpios; gm->name; gm++) +if (strcmp (propname, gm->name) ==0 ) { + count = gm->size; +break ; + } + } +if (count >=0 ) +break ; + } + +/* Then from plain _CRS GPIOs */ +if (count <0 ) { +struct list_head resource_list; +unsigned int crs_count =0 ; + +INIT_LIST_HEAD (&resource_list); +acpi_dev_get_resources (adev, &resource_list, + acpi_find_gpio_count, &crs_count); +acpi_dev_free_resource_list (&resource_list); +if (crs_count >0 ) + count = crs_count; + } +return count; +} + +#else + +static int acpi_gpio_count (struct device *dev,const char *con_id)Quoted 9 lines
drivers/gpio/gpiolib.c static struct gpio_desc *gpiod_find(struct device *dev, const char *con_id, · line 1914
Quoted 5 lines
drivers/gpio/gpiolib.c +5
-0+{ +return -ENODEV ; +} + +#endif It just occured to me that it would be better to put this code to
gpiolib-acpi.cand declareacpi_gpio_count()indrivers/gpio/gpiolib.h.
Quoted 3 lines
Ok. I will also have to move the definition of gpio_suffixes[] (PATCH 1/4) to
drivers/gpio/gpiolib.hsince it is needed by both the OF and the ACPI portions of the code.
We will really need to factorize this lookup code. I will give it a look, but first I'd like to merge this good stuff.
I am mixed about moving these declarations into gpiolib.h - maybe have one static declaration per file instead, especially since lookup on ACPI is not necessarily the same as lookup on DT. It makes sense to have it that way.
Quoted 5 lines
Quoted 5 lines
That said, I tested this code on Lenovo Thinkpad10 by converting
drivers/input/misc/soc_button_array.cto fetch its GPIOs using this new API -- it works just fine (and looks better).
Quoted 7 lines
Quoted 5 lines
Once you have done the above change you can add for the ACPI parts,
Reviewed-by Mika Westerberg <[email protected]>Tested-by Mika Westerberg <[email protected]>Great. Thanks.
Hopefully the next revision will be the right one! :)
Quoted 99 lines · On Wednesday 11 February 2015 22:31:12 Alexandre Courbot wrote:
Quoted 94 lines · Rojhalat Ibrahim
Quoted 83 lines · On Wednesday 11 February 2015 12:30:01 Mika Westerberg wrote:
Quoted 82 lines · Rojhalat Ibrahim
drivers/gpio/gpiolib.c +82
-0+#ifdef CONFIG_ACPI + +static unsigned int acpi_gpio_package_count (const union acpi_object *obj) +{ +const union acpi_object *element = obj->package.elements; +const union acpi_object *end = element + obj->package.count; +unsigned int count =0 ; + +while (element < end) { +if (element->type ==ACPI_TYPE_LOCAL_REFERENCE ) + count++; + + element++; + } +return count; +} + +static int acpi_find_gpio_count (struct acpi_resource *ares,void *data) +{ +unsigned int *count = data; + +if (ares->type ==ACPI_RESOURCE_TYPE_GPIO ) + *count += ares->data.gpio.pin_table_length; + +return 1 ; +} + +static int acpi_gpio_count (struct device *dev,const char *con_id) +{ +struct acpi_device *adev =ACPI_COMPANION (dev); +const union acpi_object *obj; +const struct acpi_gpio_mapping *gm; +int count = -ENOENT ; +int ret; +char propname[32 ]; +unsigned int i; + +/* Try first from _DSD */ +for (i =0 ; i <ARRAY_SIZE (gpio_suffixes); i++) { +if (con_id &&strcmp (con_id,"gpios" )) +snprintf (propname,sizeof (propname),"%s-%s" , + con_id, gpio_suffixes[i]); +else +snprintf (propname,sizeof (propname),"%s" , + gpio_suffixes[i]); + + ret =acpi_dev_get_property (adev, propname,ACPI_TYPE_ANY , + &obj); +if (ret ==0 ) { +if (obj->type ==ACPI_TYPE_LOCAL_REFERENCE ) + count =1 ; +else if (obj->type ==ACPI_TYPE_PACKAGE ) + count =acpi_gpio_package_count (obj); + }else if (adev->driver_gpios) { +for (gm = adev->driver_gpios; gm->name; gm++) +if (strcmp (propname, gm->name) ==0 ) { + count = gm->size; +break ; + } + } +if (count >=0 ) +break ; + } + +/* Then from plain _CRS GPIOs */ +if (count <0 ) { +struct list_head resource_list; +unsigned int crs_count =0 ; + +INIT_LIST_HEAD (&resource_list); +acpi_dev_get_resources (adev, &resource_list, + acpi_find_gpio_count, &crs_count); +acpi_dev_free_resource_list (&resource_list); +if (crs_count >0 ) + count = crs_count; + } +return count; +} + +#else + +static int acpi_gpio_count (struct device *dev,const char *con_id)Quoted 9 lines
drivers/gpio/gpiolib.c static struct gpio_desc *gpiod_find(struct device *dev, const char *con_id, · line 1914
Quoted 5 lines
drivers/gpio/gpiolib.c +5
-0+{ +return -ENODEV ; +} + +#endif It just occured to me that it would be better to put this code to
gpiolib-acpi.cand declareacpi_gpio_count()indrivers/gpio/gpiolib.h.Quoted 3 lines
Ok. I will also have to move the definition of gpio_suffixes[] (PATCH 1/4) to
drivers/gpio/gpiolib.hsince it is needed by both the OF and the ACPI portions of the code.
Quoted 8 lines
We will really need to factorize this lookup code. I will give it a look, but first I'd like to merge this good stuff.
I am mixed about moving these declarations into
gpiolib.h- maybe have one static declaration per file instead, especially since lookup on ACPI is not necessarily the same as lookup on DT. It makes sense to have it that way.
If we do one static declaration per file then acpi_find_gpio() in gpiolib.c is going to use potentially different suffixes from acpi_gpio_count() in gpiolib-acpi.c. That can't be good.
Furthermore it seems to me that while the suffixes do not necessarily have to be the same for ACPI and DT, they are now, and it may even be desirable to keep them consistent as long as there is no reason for not doing so.
Quoted 15 lines
Quoted 5 lines
Quoted 5 lines
That said, I tested this code on Lenovo Thinkpad10 by converting
drivers/input/misc/soc_button_array.cto fetch its GPIOs using this new API -- it works just fine (and looks better).Quoted 7 lines
Quoted 5 lines
Once you have done the above change you can add for the ACPI parts,
Reviewed-by Mika Westerberg <[email protected]>Tested-by Mika Westerberg <[email protected]>Great. Thanks.
Hopefully the next revision will be the right one! :)
Quoted 109 lines · Rojhalat Ibrahim
Quoted 99 lines · On Wednesday 11 February 2015 22:31:12 Alexandre Courbot wrote:
Quoted 94 lines · Rojhalat Ibrahim
Quoted 83 lines · On Wednesday 11 February 2015 12:30:01 Mika Westerberg wrote:
Quoted 82 lines · Rojhalat Ibrahim
drivers/gpio/gpiolib.c +82
-0+#ifdef CONFIG_ACPI + +static unsigned int acpi_gpio_package_count (const union acpi_object *obj) +{ +const union acpi_object *element = obj->package.elements; +const union acpi_object *end = element + obj->package.count; +unsigned int count =0 ; + +while (element < end) { +if (element->type ==ACPI_TYPE_LOCAL_REFERENCE ) + count++; + + element++; + } +return count; +} + +static int acpi_find_gpio_count (struct acpi_resource *ares,void *data) +{ +unsigned int *count = data; + +if (ares->type ==ACPI_RESOURCE_TYPE_GPIO ) + *count += ares->data.gpio.pin_table_length; + +return 1 ; +} + +static int acpi_gpio_count (struct device *dev,const char *con_id) +{ +struct acpi_device *adev =ACPI_COMPANION (dev); +const union acpi_object *obj; +const struct acpi_gpio_mapping *gm; +int count = -ENOENT ; +int ret; +char propname[32 ]; +unsigned int i; + +/* Try first from _DSD */ +for (i =0 ; i <ARRAY_SIZE (gpio_suffixes); i++) { +if (con_id &&strcmp (con_id,"gpios" )) +snprintf (propname,sizeof (propname),"%s-%s" , + con_id, gpio_suffixes[i]); +else +snprintf (propname,sizeof (propname),"%s" , + gpio_suffixes[i]); + + ret =acpi_dev_get_property (adev, propname,ACPI_TYPE_ANY , + &obj); +if (ret ==0 ) { +if (obj->type ==ACPI_TYPE_LOCAL_REFERENCE ) + count =1 ; +else if (obj->type ==ACPI_TYPE_PACKAGE ) + count =acpi_gpio_package_count (obj); + }else if (adev->driver_gpios) { +for (gm = adev->driver_gpios; gm->name; gm++) +if (strcmp (propname, gm->name) ==0 ) { + count = gm->size; +break ; + } + } +if (count >=0 ) +break ; + } + +/* Then from plain _CRS GPIOs */ +if (count <0 ) { +struct list_head resource_list; +unsigned int crs_count =0 ; + +INIT_LIST_HEAD (&resource_list); +acpi_dev_get_resources (adev, &resource_list, + acpi_find_gpio_count, &crs_count); +acpi_dev_free_resource_list (&resource_list); +if (crs_count >0 ) + count = crs_count; + } +return count; +} + +#else + +static int acpi_gpio_count (struct device *dev,const char *con_id)Quoted 9 lines
drivers/gpio/gpiolib.c static struct gpio_desc *gpiod_find(struct device *dev, const char *con_id, · line 1914
Quoted 5 lines
drivers/gpio/gpiolib.c +5
-0+{ +return -ENODEV ; +} + +#endif It just occured to me that it would be better to put this code to
gpiolib-acpi.cand declareacpi_gpio_count()indrivers/gpio/gpiolib.h.Quoted 3 lines
Ok. I will also have to move the definition of gpio_suffixes[] (PATCH 1/4) to
drivers/gpio/gpiolib.hsince it is needed by both the OF and the ACPI portions of the code.Quoted 8 lines
We will really need to factorize this lookup code. I will give it a look, but first I'd like to merge this good stuff.
I am mixed about moving these declarations into
gpiolib.h- maybe have one static declaration per file instead, especially since lookup on ACPI is not necessarily the same as lookup on DT. It makes sense to have it that way.
Quoted 7 lines
If we do one static declaration per file then
acpi_find_gpio()ingpiolib.cis going to use potentially different suffixes fromacpi_gpio_count()ingpiolib-acpi.c. That can't be good.Furthermore it seems to me that while the suffixes do not necessarily have to be the same for ACPI and DT, they are now, and it may even be desirable to keep them consistent as long as there is no reason for not doing so.
Yeah, I didn't realize that by moving stuff to gpiolib-acpi.c you need to duplicate gpio_suffixes as well.
So either leave it as is now or then we can have a bit stricter suffixes for ACPI (which I would prefer). In other words we only accept "foo-gpios" or "gpios". The only user currently is rfkill-gpio.c and that already has "-gpios" there.
I think Alexandre suggested that already some time ago when we were discussing about ACPI properties wrt. GPIOs.
Quoted 109 lines · Rojhalat Ibrahim
Quoted 99 lines · On Wednesday 11 February 2015 22:31:12 Alexandre Courbot wrote:
Quoted 94 lines · Rojhalat Ibrahim
Quoted 83 lines · On Wednesday 11 February 2015 12:30:01 Mika Westerberg wrote:
Quoted 82 lines · Rojhalat Ibrahim
drivers/gpio/gpiolib.c +82
-0+#ifdef CONFIG_ACPI + +static unsigned int acpi_gpio_package_count (const union acpi_object *obj) +{ +const union acpi_object *element = obj->package.elements; +const union acpi_object *end = element + obj->package.count; +unsigned int count =0 ; + +while (element < end) { +if (element->type ==ACPI_TYPE_LOCAL_REFERENCE ) + count++; + + element++; + } +return count; +} + +static int acpi_find_gpio_count (struct acpi_resource *ares,void *data) +{ +unsigned int *count = data; + +if (ares->type ==ACPI_RESOURCE_TYPE_GPIO ) + *count += ares->data.gpio.pin_table_length; + +return 1 ; +} + +static int acpi_gpio_count (struct device *dev,const char *con_id) +{ +struct acpi_device *adev =ACPI_COMPANION (dev); +const union acpi_object *obj; +const struct acpi_gpio_mapping *gm; +int count = -ENOENT ; +int ret; +char propname[32 ]; +unsigned int i; + +/* Try first from _DSD */ +for (i =0 ; i <ARRAY_SIZE (gpio_suffixes); i++) { +if (con_id &&strcmp (con_id,"gpios" )) +snprintf (propname,sizeof (propname),"%s-%s" , + con_id, gpio_suffixes[i]); +else +snprintf (propname,sizeof (propname),"%s" , + gpio_suffixes[i]); + + ret =acpi_dev_get_property (adev, propname,ACPI_TYPE_ANY , + &obj); +if (ret ==0 ) { +if (obj->type ==ACPI_TYPE_LOCAL_REFERENCE ) + count =1 ; +else if (obj->type ==ACPI_TYPE_PACKAGE ) + count =acpi_gpio_package_count (obj); + }else if (adev->driver_gpios) { +for (gm = adev->driver_gpios; gm->name; gm++) +if (strcmp (propname, gm->name) ==0 ) { + count = gm->size; +break ; + } + } +if (count >=0 ) +break ; + } + +/* Then from plain _CRS GPIOs */ +if (count <0 ) { +struct list_head resource_list; +unsigned int crs_count =0 ; + +INIT_LIST_HEAD (&resource_list); +acpi_dev_get_resources (adev, &resource_list, + acpi_find_gpio_count, &crs_count); +acpi_dev_free_resource_list (&resource_list); +if (crs_count >0 ) + count = crs_count; + } +return count; +} + +#else + +static int acpi_gpio_count (struct device *dev,const char *con_id)Quoted 9 lines
drivers/gpio/gpiolib.c static struct gpio_desc *gpiod_find(struct device *dev, const char *con_id, · line 1914
Quoted 5 lines
drivers/gpio/gpiolib.c +5
-0+{ +return -ENODEV ; +} + +#endif It just occured to me that it would be better to put this code to
gpiolib-acpi.cand declareacpi_gpio_count()indrivers/gpio/gpiolib.h.Quoted 3 lines
Ok. I will also have to move the definition of gpio_suffixes[] (PATCH 1/4) to
drivers/gpio/gpiolib.hsince it is needed by both the OF and the ACPI portions of the code.Quoted 8 lines
We will really need to factorize this lookup code. I will give it a look, but first I'd like to merge this good stuff.
I am mixed about moving these declarations into
gpiolib.h- maybe have one static declaration per file instead, especially since lookup on ACPI is not necessarily the same as lookup on DT. It makes sense to have it that way.
Quoted 3 lines
If we do one static declaration per file then
acpi_find_gpio()ingpiolib.cis going to use potentially different suffixes fromacpi_gpio_count()ingpiolib-acpi.c. That can't be good.
Yeah it's a bit of a mess, I really need to reorganize that code...
I'm not going to mind how you do it - just do whatever seems good to you, I will revisit it later anyway. For now I'd like this well-implemented and tested interface to be merged for everyone to enjoy.