diff options
Diffstat (limited to 'drivers/gpio/gpiolib-acpi.c')
| -rw-r--r-- | drivers/gpio/gpiolib-acpi.c | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 39f2f9035c11..bda28eb82c3f 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | * Mika Westerberg <mika.westerberg@linux.intel.com> | 7 | * Mika Westerberg <mika.westerberg@linux.intel.com> |
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #include <linux/dmi.h> | ||
| 10 | #include <linux/errno.h> | 11 | #include <linux/errno.h> |
| 11 | #include <linux/gpio/consumer.h> | 12 | #include <linux/gpio/consumer.h> |
| 12 | #include <linux/gpio/driver.h> | 13 | #include <linux/gpio/driver.h> |
| @@ -19,6 +20,11 @@ | |||
| 19 | 20 | ||
| 20 | #include "gpiolib.h" | 21 | #include "gpiolib.h" |
| 21 | 22 | ||
| 23 | static int run_edge_events_on_boot = -1; | ||
| 24 | module_param(run_edge_events_on_boot, int, 0444); | ||
| 25 | MODULE_PARM_DESC(run_edge_events_on_boot, | ||
| 26 | "Run edge _AEI event-handlers at boot: 0=no, 1=yes, -1=auto"); | ||
| 27 | |||
| 22 | /** | 28 | /** |
| 23 | * struct acpi_gpio_event - ACPI GPIO event handler data | 29 | * struct acpi_gpio_event - ACPI GPIO event handler data |
| 24 | * | 30 | * |
| @@ -170,10 +176,13 @@ static void acpi_gpiochip_request_irq(struct acpi_gpio_chip *acpi_gpio, | |||
| 170 | event->irq_requested = true; | 176 | event->irq_requested = true; |
| 171 | 177 | ||
| 172 | /* Make sure we trigger the initial state of edge-triggered IRQs */ | 178 | /* Make sure we trigger the initial state of edge-triggered IRQs */ |
| 173 | value = gpiod_get_raw_value_cansleep(event->desc); | 179 | if (run_edge_events_on_boot && |
| 174 | if (((event->irqflags & IRQF_TRIGGER_RISING) && value == 1) || | 180 | (event->irqflags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))) { |
| 175 | ((event->irqflags & IRQF_TRIGGER_FALLING) && value == 0)) | 181 | value = gpiod_get_raw_value_cansleep(event->desc); |
| 176 | event->handler(event->irq, event); | 182 | if (((event->irqflags & IRQF_TRIGGER_RISING) && value == 1) || |
| 183 | ((event->irqflags & IRQF_TRIGGER_FALLING) && value == 0)) | ||
| 184 | event->handler(event->irq, event); | ||
| 185 | } | ||
| 177 | } | 186 | } |
| 178 | 187 | ||
| 179 | static void acpi_gpiochip_request_irqs(struct acpi_gpio_chip *acpi_gpio) | 188 | static void acpi_gpiochip_request_irqs(struct acpi_gpio_chip *acpi_gpio) |
| @@ -1283,3 +1292,28 @@ static int acpi_gpio_handle_deferred_request_irqs(void) | |||
| 1283 | } | 1292 | } |
| 1284 | /* We must use _sync so that this runs after the first deferred_probe run */ | 1293 | /* We must use _sync so that this runs after the first deferred_probe run */ |
| 1285 | late_initcall_sync(acpi_gpio_handle_deferred_request_irqs); | 1294 | late_initcall_sync(acpi_gpio_handle_deferred_request_irqs); |
| 1295 | |||
| 1296 | static const struct dmi_system_id run_edge_events_on_boot_blacklist[] = { | ||
| 1297 | { | ||
| 1298 | .matches = { | ||
| 1299 | DMI_MATCH(DMI_SYS_VENDOR, "MINIX"), | ||
| 1300 | DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"), | ||
| 1301 | } | ||
| 1302 | }, | ||
| 1303 | {} /* Terminating entry */ | ||
| 1304 | }; | ||
| 1305 | |||
| 1306 | static int acpi_gpio_setup_params(void) | ||
| 1307 | { | ||
| 1308 | if (run_edge_events_on_boot < 0) { | ||
| 1309 | if (dmi_check_system(run_edge_events_on_boot_blacklist)) | ||
| 1310 | run_edge_events_on_boot = 0; | ||
| 1311 | else | ||
| 1312 | run_edge_events_on_boot = 1; | ||
| 1313 | } | ||
| 1314 | |||
| 1315 | return 0; | ||
| 1316 | } | ||
| 1317 | |||
| 1318 | /* Directly after dmi_setup() which runs as core_initcall() */ | ||
| 1319 | postcore_initcall(acpi_gpio_setup_params); | ||
