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); | ||