1/*
2 * ACPI helpers for GPIO API
3 *
4 * Copyright (C) 2012, Intel Corporation
5 * Authors: Mathias Nyman <mathias.nyman@linux.intel.com>
6 *          Mika Westerberg <mika.westerberg@linux.intel.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/errno.h>
14#include <linux/gpio.h>
15#include <linux/gpio/consumer.h>
16#include <linux/gpio/driver.h>
17#include <linux/export.h>
18#include <linux/acpi.h>
19#include <linux/interrupt.h>
20#include <linux/mutex.h>
21#include <linux/pinctrl/pinctrl.h>
22
23#include "gpiolib.h"
24
25struct acpi_gpio_event {
26	struct list_head node;
27	acpi_handle handle;
28	unsigned int pin;
29	unsigned int irq;
30	struct gpio_desc *desc;
31};
32
33struct acpi_gpio_connection {
34	struct list_head node;
35	unsigned int pin;
36	struct gpio_desc *desc;
37};
38
39struct acpi_gpio_chip {
40	/*
41	 * ACPICA requires that the first field of the context parameter
42	 * passed to acpi_install_address_space_handler() is large enough
43	 * to hold struct acpi_connection_info.
44	 */
45	struct acpi_connection_info conn_info;
46	struct list_head conns;
47	struct mutex conn_lock;
48	struct gpio_chip *chip;
49	struct list_head events;
50};
51
52static int acpi_gpiochip_find(struct gpio_chip *gc, void *data)
53{
54	if (!gc->dev)
55		return false;
56
57	return ACPI_HANDLE(gc->dev) == data;
58}
59
60#ifdef CONFIG_PINCTRL
61/**
62 * acpi_gpiochip_pin_to_gpio_offset() - translates ACPI GPIO to Linux GPIO
63 * @chip: GPIO chip
64 * @pin: ACPI GPIO pin number from GpioIo/GpioInt resource
65 *
66 * Function takes ACPI GpioIo/GpioInt pin number as a parameter and
67 * translates it to a corresponding offset suitable to be passed to a
68 * GPIO controller driver.
69 *
70 * Typically the returned offset is same as @pin, but if the GPIO
71 * controller uses pin controller and the mapping is not contigous the
72 * offset might be different.
73 */
74static int acpi_gpiochip_pin_to_gpio_offset(struct gpio_chip *chip, int pin)
75{
76	struct gpio_pin_range *pin_range;
77
78	/* If there are no ranges in this chip, use 1:1 mapping */
79	if (list_empty(&chip->pin_ranges))
80		return pin;
81
82	list_for_each_entry(pin_range, &chip->pin_ranges, node) {
83		const struct pinctrl_gpio_range *range = &pin_range->range;
84		int i;
85
86		if (range->pins) {
87			for (i = 0; i < range->npins; i++) {
88				if (range->pins[i] == pin)
89					return range->base + i - chip->base;
90			}
91		} else {
92			if (pin >= range->pin_base &&
93			    pin < range->pin_base + range->npins) {
94				unsigned gpio_base;
95
96				gpio_base = range->base - chip->base;
97				return gpio_base + pin - range->pin_base;
98			}
99		}
100	}
101
102	return -EINVAL;
103}
104#else
105static inline int acpi_gpiochip_pin_to_gpio_offset(struct gpio_chip *chip,
106						   int pin)
107{
108	return pin;
109}
110#endif
111
112/**
113 * acpi_get_gpiod() - Translate ACPI GPIO pin to GPIO descriptor usable with GPIO API
114 * @path:	ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1")
115 * @pin:	ACPI GPIO pin number (0-based, controller-relative)
116 *
117 * Returns GPIO descriptor to use with Linux generic GPIO API, or ERR_PTR
118 * error value
119 */
120
121static struct gpio_desc *acpi_get_gpiod(char *path, int pin)
122{
123	struct gpio_chip *chip;
124	acpi_handle handle;
125	acpi_status status;
126	int offset;
127
128	status = acpi_get_handle(NULL, path, &handle);
129	if (ACPI_FAILURE(status))
130		return ERR_PTR(-ENODEV);
131
132	chip = gpiochip_find(handle, acpi_gpiochip_find);
133	if (!chip)
134		return ERR_PTR(-ENODEV);
135
136	offset = acpi_gpiochip_pin_to_gpio_offset(chip, pin);
137	if (offset < 0)
138		return ERR_PTR(offset);
139
140	return gpiochip_get_desc(chip, offset);
141}
142
143static irqreturn_t acpi_gpio_irq_handler(int irq, void *data)
144{
145	struct acpi_gpio_event *event = data;
146
147	acpi_evaluate_object(event->handle, NULL, NULL, NULL);
148
149	return IRQ_HANDLED;
150}
151
152static irqreturn_t acpi_gpio_irq_handler_evt(int irq, void *data)
153{
154	struct acpi_gpio_event *event = data;
155
156	acpi_execute_simple_method(event->handle, NULL, event->pin);
157
158	return IRQ_HANDLED;
159}
160
161static void acpi_gpio_chip_dh(acpi_handle handle, void *data)
162{
163	/* The address of this function is used as a key. */
164}
165
166static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,
167						   void *context)
168{
169	struct acpi_gpio_chip *acpi_gpio = context;
170	struct gpio_chip *chip = acpi_gpio->chip;
171	struct acpi_resource_gpio *agpio;
172	acpi_handle handle, evt_handle;
173	struct acpi_gpio_event *event;
174	irq_handler_t handler = NULL;
175	struct gpio_desc *desc;
176	unsigned long irqflags;
177	int ret, pin, irq;
178
179	if (ares->type != ACPI_RESOURCE_TYPE_GPIO)
180		return AE_OK;
181
182	agpio = &ares->data.gpio;
183	if (agpio->connection_type != ACPI_RESOURCE_GPIO_TYPE_INT)
184		return AE_OK;
185
186	handle = ACPI_HANDLE(chip->dev);
187	pin = agpio->pin_table[0];
188
189	if (pin <= 255) {
190		char ev_name[5];
191		sprintf(ev_name, "_%c%02X",
192			agpio->triggering == ACPI_EDGE_SENSITIVE ? 'E' : 'L',
193			pin);
194		if (ACPI_SUCCESS(acpi_get_handle(handle, ev_name, &evt_handle)))
195			handler = acpi_gpio_irq_handler;
196	}
197	if (!handler) {
198		if (ACPI_SUCCESS(acpi_get_handle(handle, "_EVT", &evt_handle)))
199			handler = acpi_gpio_irq_handler_evt;
200	}
201	if (!handler)
202		return AE_BAD_PARAMETER;
203
204	pin = acpi_gpiochip_pin_to_gpio_offset(chip, pin);
205	if (pin < 0)
206		return AE_BAD_PARAMETER;
207
208	desc = gpiochip_request_own_desc(chip, pin, "ACPI:Event");
209	if (IS_ERR(desc)) {
210		dev_err(chip->dev, "Failed to request GPIO\n");
211		return AE_ERROR;
212	}
213
214	gpiod_direction_input(desc);
215
216	ret = gpiochip_lock_as_irq(chip, pin);
217	if (ret) {
218		dev_err(chip->dev, "Failed to lock GPIO as interrupt\n");
219		goto fail_free_desc;
220	}
221
222	irq = gpiod_to_irq(desc);
223	if (irq < 0) {
224		dev_err(chip->dev, "Failed to translate GPIO to IRQ\n");
225		goto fail_unlock_irq;
226	}
227
228	irqflags = IRQF_ONESHOT;
229	if (agpio->triggering == ACPI_LEVEL_SENSITIVE) {
230		if (agpio->polarity == ACPI_ACTIVE_HIGH)
231			irqflags |= IRQF_TRIGGER_HIGH;
232		else
233			irqflags |= IRQF_TRIGGER_LOW;
234	} else {
235		switch (agpio->polarity) {
236		case ACPI_ACTIVE_HIGH:
237			irqflags |= IRQF_TRIGGER_RISING;
238			break;
239		case ACPI_ACTIVE_LOW:
240			irqflags |= IRQF_TRIGGER_FALLING;
241			break;
242		default:
243			irqflags |= IRQF_TRIGGER_RISING |
244				    IRQF_TRIGGER_FALLING;
245			break;
246		}
247	}
248
249	event = kzalloc(sizeof(*event), GFP_KERNEL);
250	if (!event)
251		goto fail_unlock_irq;
252
253	event->handle = evt_handle;
254	event->irq = irq;
255	event->pin = pin;
256	event->desc = desc;
257
258	ret = request_threaded_irq(event->irq, NULL, handler, irqflags,
259				   "ACPI:Event", event);
260	if (ret) {
261		dev_err(chip->dev, "Failed to setup interrupt handler for %d\n",
262			event->irq);
263		goto fail_free_event;
264	}
265
266	list_add_tail(&event->node, &acpi_gpio->events);
267	return AE_OK;
268
269fail_free_event:
270	kfree(event);
271fail_unlock_irq:
272	gpiochip_unlock_as_irq(chip, pin);
273fail_free_desc:
274	gpiochip_free_own_desc(desc);
275
276	return AE_ERROR;
277}
278
279/**
280 * acpi_gpiochip_request_interrupts() - Register isr for gpio chip ACPI events
281 * @chip:      GPIO chip
282 *
283 * ACPI5 platforms can use GPIO signaled ACPI events. These GPIO interrupts are
284 * handled by ACPI event methods which need to be called from the GPIO
285 * chip's interrupt handler. acpi_gpiochip_request_interrupts finds out which
286 * gpio pins have acpi event methods and assigns interrupt handlers that calls
287 * the acpi event methods for those pins.
288 */
289void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
290{
291	struct acpi_gpio_chip *acpi_gpio;
292	acpi_handle handle;
293	acpi_status status;
294
295	if (!chip->dev || !chip->to_irq)
296		return;
297
298	handle = ACPI_HANDLE(chip->dev);
299	if (!handle)
300		return;
301
302	status = acpi_get_data(handle, acpi_gpio_chip_dh, (void **)&acpi_gpio);
303	if (ACPI_FAILURE(status))
304		return;
305
306	INIT_LIST_HEAD(&acpi_gpio->events);
307	acpi_walk_resources(handle, "_AEI",
308			    acpi_gpiochip_request_interrupt, acpi_gpio);
309}
310
311/**
312 * acpi_gpiochip_free_interrupts() - Free GPIO ACPI event interrupts.
313 * @chip:      GPIO chip
314 *
315 * Free interrupts associated with GPIO ACPI event method for the given
316 * GPIO chip.
317 */
318void acpi_gpiochip_free_interrupts(struct gpio_chip *chip)
319{
320	struct acpi_gpio_chip *acpi_gpio;
321	struct acpi_gpio_event *event, *ep;
322	acpi_handle handle;
323	acpi_status status;
324
325	if (!chip->dev || !chip->to_irq)
326		return;
327
328	handle = ACPI_HANDLE(chip->dev);
329	if (!handle)
330		return;
331
332	status = acpi_get_data(handle, acpi_gpio_chip_dh, (void **)&acpi_gpio);
333	if (ACPI_FAILURE(status))
334		return;
335
336	list_for_each_entry_safe_reverse(event, ep, &acpi_gpio->events, node) {
337		struct gpio_desc *desc;
338
339		free_irq(event->irq, event);
340		desc = event->desc;
341		if (WARN_ON(IS_ERR(desc)))
342			continue;
343		gpiochip_unlock_as_irq(chip, event->pin);
344		gpiochip_free_own_desc(desc);
345		list_del(&event->node);
346		kfree(event);
347	}
348}
349
350int acpi_dev_add_driver_gpios(struct acpi_device *adev,
351			      const struct acpi_gpio_mapping *gpios)
352{
353	if (adev && gpios) {
354		adev->driver_gpios = gpios;
355		return 0;
356	}
357	return -EINVAL;
358}
359EXPORT_SYMBOL_GPL(acpi_dev_add_driver_gpios);
360
361static bool acpi_get_driver_gpio_data(struct acpi_device *adev,
362				      const char *name, int index,
363				      struct acpi_reference_args *args)
364{
365	const struct acpi_gpio_mapping *gm;
366
367	if (!adev->driver_gpios)
368		return false;
369
370	for (gm = adev->driver_gpios; gm->name; gm++)
371		if (!strcmp(name, gm->name) && gm->data && index < gm->size) {
372			const struct acpi_gpio_params *par = gm->data + index;
373
374			args->adev = adev;
375			args->args[0] = par->crs_entry_index;
376			args->args[1] = par->line_index;
377			args->args[2] = par->active_low;
378			args->nargs = 3;
379			return true;
380		}
381
382	return false;
383}
384
385struct acpi_gpio_lookup {
386	struct acpi_gpio_info info;
387	int index;
388	int pin_index;
389	struct gpio_desc *desc;
390	int n;
391};
392
393static int acpi_find_gpio(struct acpi_resource *ares, void *data)
394{
395	struct acpi_gpio_lookup *lookup = data;
396
397	if (ares->type != ACPI_RESOURCE_TYPE_GPIO)
398		return 1;
399
400	if (lookup->n++ == lookup->index && !lookup->desc) {
401		const struct acpi_resource_gpio *agpio = &ares->data.gpio;
402		int pin_index = lookup->pin_index;
403
404		if (pin_index >= agpio->pin_table_length)
405			return 1;
406
407		lookup->desc = acpi_get_gpiod(agpio->resource_source.string_ptr,
408					      agpio->pin_table[pin_index]);
409		lookup->info.gpioint =
410			agpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT;
411
412		/*
413		 * ActiveLow is only specified for GpioInt resource. If
414		 * GpioIo is used then the only way to set the flag is
415		 * to use _DSD "gpios" property.
416		 */
417		if (lookup->info.gpioint)
418			lookup->info.active_low =
419				agpio->polarity == ACPI_ACTIVE_LOW;
420	}
421
422	return 1;
423}
424
425/**
426 * acpi_get_gpiod_by_index() - get a GPIO descriptor from device resources
427 * @adev: pointer to a ACPI device to get GPIO from
428 * @propname: Property name of the GPIO (optional)
429 * @index: index of GpioIo/GpioInt resource (starting from %0)
430 * @info: info pointer to fill in (optional)
431 *
432 * Function goes through ACPI resources for @adev and based on @index looks
433 * up a GpioIo/GpioInt resource, translates it to the Linux GPIO descriptor,
434 * and returns it. @index matches GpioIo/GpioInt resources only so if there
435 * are total %3 GPIO resources, the index goes from %0 to %2.
436 *
437 * If @propname is specified the GPIO is looked using device property. In
438 * that case @index is used to select the GPIO entry in the property value
439 * (in case of multiple).
440 *
441 * If the GPIO cannot be translated or there is an error an ERR_PTR is
442 * returned.
443 *
444 * Note: if the GPIO resource has multiple entries in the pin list, this
445 * function only returns the first.
446 */
447struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
448					  const char *propname, int index,
449					  struct acpi_gpio_info *info)
450{
451	struct acpi_gpio_lookup lookup;
452	struct list_head resource_list;
453	bool active_low = false;
454	int ret;
455
456	if (!adev)
457		return ERR_PTR(-ENODEV);
458
459	memset(&lookup, 0, sizeof(lookup));
460	lookup.index = index;
461
462	if (propname) {
463		struct acpi_reference_args args;
464
465		dev_dbg(&adev->dev, "GPIO: looking up %s\n", propname);
466
467		memset(&args, 0, sizeof(args));
468		ret = acpi_dev_get_property_reference(adev, propname,
469						      index, &args);
470		if (ret) {
471			bool found = acpi_get_driver_gpio_data(adev, propname,
472							       index, &args);
473			if (!found)
474				return ERR_PTR(ret);
475		}
476
477		/*
478		 * The property was found and resolved so need to
479		 * lookup the GPIO based on returned args instead.
480		 */
481		adev = args.adev;
482		if (args.nargs >= 2) {
483			lookup.index = args.args[0];
484			lookup.pin_index = args.args[1];
485			/*
486			 * 3rd argument, if present is used to
487			 * specify active_low.
488			 */
489			if (args.nargs >= 3)
490				active_low = !!args.args[2];
491		}
492
493		dev_dbg(&adev->dev, "GPIO: _DSD returned %s %zd %llu %llu %llu\n",
494			dev_name(&adev->dev), args.nargs,
495			args.args[0], args.args[1], args.args[2]);
496	} else {
497		dev_dbg(&adev->dev, "GPIO: looking up %d in _CRS\n", index);
498	}
499
500	INIT_LIST_HEAD(&resource_list);
501	ret = acpi_dev_get_resources(adev, &resource_list, acpi_find_gpio,
502				     &lookup);
503	if (ret < 0)
504		return ERR_PTR(ret);
505
506	acpi_dev_free_resource_list(&resource_list);
507
508	if (lookup.desc && info) {
509		*info = lookup.info;
510		if (active_low)
511			info->active_low = active_low;
512	}
513
514	return lookup.desc ? lookup.desc : ERR_PTR(-ENOENT);
515}
516
517static acpi_status
518acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
519			    u32 bits, u64 *value, void *handler_context,
520			    void *region_context)
521{
522	struct acpi_gpio_chip *achip = region_context;
523	struct gpio_chip *chip = achip->chip;
524	struct acpi_resource_gpio *agpio;
525	struct acpi_resource *ares;
526	int pin_index = (int)address;
527	acpi_status status;
528	bool pull_up;
529	int length;
530	int i;
531
532	status = acpi_buffer_to_resource(achip->conn_info.connection,
533					 achip->conn_info.length, &ares);
534	if (ACPI_FAILURE(status))
535		return status;
536
537	if (WARN_ON(ares->type != ACPI_RESOURCE_TYPE_GPIO)) {
538		ACPI_FREE(ares);
539		return AE_BAD_PARAMETER;
540	}
541
542	agpio = &ares->data.gpio;
543	pull_up = agpio->pin_config == ACPI_PIN_CONFIG_PULLUP;
544
545	if (WARN_ON(agpio->io_restriction == ACPI_IO_RESTRICT_INPUT &&
546	    function == ACPI_WRITE)) {
547		ACPI_FREE(ares);
548		return AE_BAD_PARAMETER;
549	}
550
551	length = min(agpio->pin_table_length, (u16)(pin_index + bits));
552	for (i = pin_index; i < length; ++i) {
553		int pin = agpio->pin_table[i];
554		struct acpi_gpio_connection *conn;
555		struct gpio_desc *desc;
556		bool found;
557
558		pin = acpi_gpiochip_pin_to_gpio_offset(chip, pin);
559		if (pin < 0) {
560			status = AE_BAD_PARAMETER;
561			goto out;
562		}
563
564		mutex_lock(&achip->conn_lock);
565
566		found = false;
567		list_for_each_entry(conn, &achip->conns, node) {
568			if (conn->pin == pin) {
569				found = true;
570				desc = conn->desc;
571				break;
572			}
573		}
574		if (!found) {
575			desc = gpiochip_request_own_desc(chip, pin,
576							 "ACPI:OpRegion");
577			if (IS_ERR(desc)) {
578				status = AE_ERROR;
579				mutex_unlock(&achip->conn_lock);
580				goto out;
581			}
582
583			switch (agpio->io_restriction) {
584			case ACPI_IO_RESTRICT_INPUT:
585				gpiod_direction_input(desc);
586				break;
587			case ACPI_IO_RESTRICT_OUTPUT:
588				/*
589				 * ACPI GPIO resources don't contain an
590				 * initial value for the GPIO. Therefore we
591				 * deduce that value from the pull field
592				 * instead. If the pin is pulled up we
593				 * assume default to be high, otherwise
594				 * low.
595				 */
596				gpiod_direction_output(desc, pull_up);
597				break;
598			default:
599				/*
600				 * Assume that the BIOS has configured the
601				 * direction and pull accordingly.
602				 */
603				break;
604			}
605
606			conn = kzalloc(sizeof(*conn), GFP_KERNEL);
607			if (!conn) {
608				status = AE_NO_MEMORY;
609				gpiochip_free_own_desc(desc);
610				mutex_unlock(&achip->conn_lock);
611				goto out;
612			}
613
614			conn->pin = pin;
615			conn->desc = desc;
616			list_add_tail(&conn->node, &achip->conns);
617		}
618
619		mutex_unlock(&achip->conn_lock);
620
621		if (function == ACPI_WRITE)
622			gpiod_set_raw_value_cansleep(desc,
623						     !!((1 << i) & *value));
624		else
625			*value |= (u64)gpiod_get_raw_value_cansleep(desc) << i;
626	}
627
628out:
629	ACPI_FREE(ares);
630	return status;
631}
632
633static void acpi_gpiochip_request_regions(struct acpi_gpio_chip *achip)
634{
635	struct gpio_chip *chip = achip->chip;
636	acpi_handle handle = ACPI_HANDLE(chip->dev);
637	acpi_status status;
638
639	INIT_LIST_HEAD(&achip->conns);
640	mutex_init(&achip->conn_lock);
641	status = acpi_install_address_space_handler(handle, ACPI_ADR_SPACE_GPIO,
642						    acpi_gpio_adr_space_handler,
643						    NULL, achip);
644	if (ACPI_FAILURE(status))
645		dev_err(chip->dev, "Failed to install GPIO OpRegion handler\n");
646}
647
648static void acpi_gpiochip_free_regions(struct acpi_gpio_chip *achip)
649{
650	struct gpio_chip *chip = achip->chip;
651	acpi_handle handle = ACPI_HANDLE(chip->dev);
652	struct acpi_gpio_connection *conn, *tmp;
653	acpi_status status;
654
655	status = acpi_remove_address_space_handler(handle, ACPI_ADR_SPACE_GPIO,
656						   acpi_gpio_adr_space_handler);
657	if (ACPI_FAILURE(status)) {
658		dev_err(chip->dev, "Failed to remove GPIO OpRegion handler\n");
659		return;
660	}
661
662	list_for_each_entry_safe_reverse(conn, tmp, &achip->conns, node) {
663		gpiochip_free_own_desc(conn->desc);
664		list_del(&conn->node);
665		kfree(conn);
666	}
667}
668
669void acpi_gpiochip_add(struct gpio_chip *chip)
670{
671	struct acpi_gpio_chip *acpi_gpio;
672	acpi_handle handle;
673	acpi_status status;
674
675	if (!chip || !chip->dev)
676		return;
677
678	handle = ACPI_HANDLE(chip->dev);
679	if (!handle)
680		return;
681
682	acpi_gpio = kzalloc(sizeof(*acpi_gpio), GFP_KERNEL);
683	if (!acpi_gpio) {
684		dev_err(chip->dev,
685			"Failed to allocate memory for ACPI GPIO chip\n");
686		return;
687	}
688
689	acpi_gpio->chip = chip;
690
691	status = acpi_attach_data(handle, acpi_gpio_chip_dh, acpi_gpio);
692	if (ACPI_FAILURE(status)) {
693		dev_err(chip->dev, "Failed to attach ACPI GPIO chip\n");
694		kfree(acpi_gpio);
695		return;
696	}
697
698	acpi_gpiochip_request_regions(acpi_gpio);
699}
700
701void acpi_gpiochip_remove(struct gpio_chip *chip)
702{
703	struct acpi_gpio_chip *acpi_gpio;
704	acpi_handle handle;
705	acpi_status status;
706
707	if (!chip || !chip->dev)
708		return;
709
710	handle = ACPI_HANDLE(chip->dev);
711	if (!handle)
712		return;
713
714	status = acpi_get_data(handle, acpi_gpio_chip_dh, (void **)&acpi_gpio);
715	if (ACPI_FAILURE(status)) {
716		dev_warn(chip->dev, "Failed to retrieve ACPI GPIO chip\n");
717		return;
718	}
719
720	acpi_gpiochip_free_regions(acpi_gpio);
721
722	acpi_detach_data(handle, acpi_gpio_chip_dh);
723	kfree(acpi_gpio);
724}
725
726static unsigned int acpi_gpio_package_count(const union acpi_object *obj)
727{
728	const union acpi_object *element = obj->package.elements;
729	const union acpi_object *end = element + obj->package.count;
730	unsigned int count = 0;
731
732	while (element < end) {
733		if (element->type == ACPI_TYPE_LOCAL_REFERENCE)
734			count++;
735
736		element++;
737	}
738	return count;
739}
740
741static int acpi_find_gpio_count(struct acpi_resource *ares, void *data)
742{
743	unsigned int *count = data;
744
745	if (ares->type == ACPI_RESOURCE_TYPE_GPIO)
746		*count += ares->data.gpio.pin_table_length;
747
748	return 1;
749}
750
751/**
752 * acpi_gpio_count - return the number of GPIOs associated with a
753 *		device / function or -ENOENT if no GPIO has been
754 *		assigned to the requested function.
755 * @dev:	GPIO consumer, can be NULL for system-global GPIOs
756 * @con_id:	function within the GPIO consumer
757 */
758int acpi_gpio_count(struct device *dev, const char *con_id)
759{
760	struct acpi_device *adev = ACPI_COMPANION(dev);
761	const union acpi_object *obj;
762	const struct acpi_gpio_mapping *gm;
763	int count = -ENOENT;
764	int ret;
765	char propname[32];
766	unsigned int i;
767
768	/* Try first from _DSD */
769	for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) {
770		if (con_id && strcmp(con_id, "gpios"))
771			snprintf(propname, sizeof(propname), "%s-%s",
772				 con_id, gpio_suffixes[i]);
773		else
774			snprintf(propname, sizeof(propname), "%s",
775				 gpio_suffixes[i]);
776
777		ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_ANY,
778					    &obj);
779		if (ret == 0) {
780			if (obj->type == ACPI_TYPE_LOCAL_REFERENCE)
781				count = 1;
782			else if (obj->type == ACPI_TYPE_PACKAGE)
783				count = acpi_gpio_package_count(obj);
784		} else if (adev->driver_gpios) {
785			for (gm = adev->driver_gpios; gm->name; gm++)
786				if (strcmp(propname, gm->name) == 0) {
787					count = gm->size;
788					break;
789				}
790		}
791		if (count >= 0)
792			break;
793	}
794
795	/* Then from plain _CRS GPIOs */
796	if (count < 0) {
797		struct list_head resource_list;
798		unsigned int crs_count = 0;
799
800		INIT_LIST_HEAD(&resource_list);
801		acpi_dev_get_resources(adev, &resource_list,
802				       acpi_find_gpio_count, &crs_count);
803		acpi_dev_free_resource_list(&resource_list);
804		if (crs_count > 0)
805			count = crs_count;
806	}
807	return count;
808}
809