Skip to content

Commit 61f7f7c

Browse files
jwrdegoedelinusw
authored andcommitted
gpiolib: acpi: Add gpiolib_acpi_run_edge_events_on_boot option and blacklist
Another day; another DSDT bug we need to workaround... Since commit ca876c7 ("gpiolib-acpi: make sure we trigger edge events at least once on boot") we call _AEI edge handlers at boot. In some rare cases this causes problems. One example of this is the Minix Neo Z83-4 mini PC, this device has a clear DSDT bug where it has some copy and pasted code for dealing with Micro USB-B connector host/device role switching, while the mini PC does not even have a micro-USB connector. This code, which should not be there, messes with the DDC data pin from the HDMI connector (switching it to GPIO mode) breaking HDMI support. To avoid problems like this, this commit adds a new gpiolib_acpi.run_edge_events_on_boot kernel commandline option, which allows disabling the running of _AEI edge event handlers at boot. The default value is -1/auto which uses a DMI based blacklist, the initial version of this blacklist contains the Neo Z83-4 fixing the HDMI breakage. Cc: [email protected] Cc: Daniel Drake <[email protected]> Cc: Ian W MORRISON <[email protected]> Reported-by: Ian W MORRISON <[email protected]> Suggested-by: Ian W MORRISON <[email protected]> Fixes: ca876c7 ("gpiolib-acpi: make sure we trigger edge events at least once on boot") Signed-off-by: Hans de Goede <[email protected]> Link: https://lore.kernel.org/r/[email protected] Acked-by: Mika Westerberg <[email protected]> Reviewed-by: Andy Shevchenko <[email protected]> Tested-by: Ian W MORRISON <[email protected]> Signed-off-by: Linus Walleij <[email protected]>
1 parent 1dea33e commit 61f7f7c

File tree

1 file changed

+38
-4
lines changed

1 file changed

+38
-4
lines changed

drivers/gpio/gpiolib-acpi.c

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* Mika Westerberg <[email protected]>
88
*/
99

10+
#include <linux/dmi.h>
1011
#include <linux/errno.h>
1112
#include <linux/gpio/consumer.h>
1213
#include <linux/gpio/driver.h>
@@ -19,6 +20,11 @@
1920

2021
#include "gpiolib.h"
2122

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+
2228
/**
2329
* struct acpi_gpio_event - ACPI GPIO event handler data
2430
*
@@ -170,10 +176,13 @@ static void acpi_gpiochip_request_irq(struct acpi_gpio_chip *acpi_gpio,
170176
event->irq_requested = true;
171177

172178
/* Make sure we trigger the initial state of edge-triggered IRQs */
173-
value = gpiod_get_raw_value_cansleep(event->desc);
174-
if (((event->irqflags & IRQF_TRIGGER_RISING) && value == 1) ||
175-
((event->irqflags & IRQF_TRIGGER_FALLING) && value == 0))
176-
event->handler(event->irq, event);
179+
if (run_edge_events_on_boot &&
180+
(event->irqflags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))) {
181+
value = gpiod_get_raw_value_cansleep(event->desc);
182+
if (((event->irqflags & IRQF_TRIGGER_RISING) && value == 1) ||
183+
((event->irqflags & IRQF_TRIGGER_FALLING) && value == 0))
184+
event->handler(event->irq, event);
185+
}
177186
}
178187

179188
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)
12831292
}
12841293
/* We must use _sync so that this runs after the first deferred_probe run */
12851294
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);

0 commit comments

Comments
 (0)