aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpio/gpiolib-acpi.c43
-rw-r--r--include/acpi/acpi_bus.h3
-rw-r--r--include/linux/acpi.h30
3 files changed, 74 insertions, 2 deletions
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
index 8aa6ca473748..5a4d061e787e 100644
--- a/drivers/gpio/gpiolib-acpi.c
+++ b/drivers/gpio/gpiolib-acpi.c
@@ -287,6 +287,41 @@ void acpi_gpiochip_free_interrupts(struct gpio_chip *chip)
287 } 287 }
288} 288}
289 289
290int acpi_dev_add_driver_gpios(struct acpi_device *adev,
291 const struct acpi_gpio_mapping *gpios)
292{
293 if (adev && gpios) {
294 adev->driver_gpios = gpios;
295 return 0;
296 }
297 return -EINVAL;
298}
299EXPORT_SYMBOL_GPL(acpi_dev_add_driver_gpios);
300
301static bool acpi_get_driver_gpio_data(struct acpi_device *adev,
302 const char *name, int index,
303 struct acpi_reference_args *args)
304{
305 const struct acpi_gpio_mapping *gm;
306
307 if (!adev->driver_gpios)
308 return false;
309
310 for (gm = adev->driver_gpios; gm->name; gm++)
311 if (!strcmp(name, gm->name) && gm->data && index < gm->size) {
312 const struct acpi_gpio_params *par = gm->data + index;
313
314 args->adev = adev;
315 args->args[0] = par->crs_entry_index;
316 args->args[1] = par->line_index;
317 args->args[2] = par->active_low;
318 args->nargs = 3;
319 return true;
320 }
321
322 return false;
323}
324
290struct acpi_gpio_lookup { 325struct acpi_gpio_lookup {
291 struct acpi_gpio_info info; 326 struct acpi_gpio_info info;
292 int index; 327 int index;
@@ -372,8 +407,12 @@ struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
372 memset(&args, 0, sizeof(args)); 407 memset(&args, 0, sizeof(args));
373 ret = acpi_dev_get_property_reference(adev, propname, NULL, 408 ret = acpi_dev_get_property_reference(adev, propname, NULL,
374 index, &args); 409 index, &args);
375 if (ret) 410 if (ret) {
376 return ERR_PTR(ret); 411 bool found = acpi_get_driver_gpio_data(adev, propname,
412 index, &args);
413 if (!found)
414 return ERR_PTR(ret);
415 }
377 416
378 /* 417 /*
379 * The property was found and resolved so need to 418 * The property was found and resolved so need to
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index a361f43b1974..7d1ce40e201e 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -345,6 +345,8 @@ struct acpi_device_data {
345 const union acpi_object *of_compatible; 345 const union acpi_object *of_compatible;
346}; 346};
347 347
348struct acpi_gpio_mapping;
349
348/* Device */ 350/* Device */
349struct acpi_device { 351struct acpi_device {
350 int device_type; 352 int device_type;
@@ -366,6 +368,7 @@ struct acpi_device {
366 struct acpi_scan_handler *handler; 368 struct acpi_scan_handler *handler;
367 struct acpi_hotplug_context *hp; 369 struct acpi_hotplug_context *hp;
368 struct acpi_driver *driver; 370 struct acpi_driver *driver;
371 const struct acpi_gpio_mapping *driver_gpios;
369 void *driver_data; 372 void *driver_data;
370 struct device dev; 373 struct device dev;
371 unsigned int physical_node_count; 374 unsigned int physical_node_count;
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 5b8802216a93..0902426c4521 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -673,6 +673,36 @@ do { \
673#endif 673#endif
674#endif 674#endif
675 675
676struct acpi_gpio_params {
677 unsigned int crs_entry_index;
678 unsigned int line_index;
679 bool active_low;
680};
681
682struct acpi_gpio_mapping {
683 const char *name;
684 const struct acpi_gpio_params *data;
685 unsigned int size;
686};
687
688#if defined(CONFIG_ACPI) && defined(CONFIG_GPIOLIB)
689int acpi_dev_add_driver_gpios(struct acpi_device *adev,
690 const struct acpi_gpio_mapping *gpios);
691
692static inline void acpi_dev_remove_driver_gpios(struct acpi_device *adev)
693{
694 if (adev)
695 adev->driver_gpios = NULL;
696}
697#else
698static inline int acpi_dev_add_driver_gpios(struct acpi_device *adev,
699 const struct acpi_gpio_mapping *gpios)
700{
701 return -ENXIO;
702}
703static inline void acpi_dev_remove_driver_gpios(struct acpi_device *adev) {}
704#endif
705
676/* Device properties */ 706/* Device properties */
677 707
678#define MAX_ACPI_REFERENCE_ARGS 8 708#define MAX_ACPI_REFERENCE_ARGS 8