1*92dc5728SAndy Shevchenko // SPDX-License-Identifier: GPL-2.0
2*92dc5728SAndy Shevchenko /*
3*92dc5728SAndy Shevchenko * ACPI quirks for GPIO ACPI helpers
4*92dc5728SAndy Shevchenko *
5*92dc5728SAndy Shevchenko * Author: Hans de Goede <hdegoede@redhat.com>
6*92dc5728SAndy Shevchenko */
7*92dc5728SAndy Shevchenko
8*92dc5728SAndy Shevchenko #include <linux/dmi.h>
9*92dc5728SAndy Shevchenko #include <linux/kstrtox.h>
10*92dc5728SAndy Shevchenko #include <linux/list.h>
11*92dc5728SAndy Shevchenko #include <linux/module.h>
12*92dc5728SAndy Shevchenko #include <linux/mutex.h>
13*92dc5728SAndy Shevchenko #include <linux/printk.h>
14*92dc5728SAndy Shevchenko #include <linux/string.h>
15*92dc5728SAndy Shevchenko #include <linux/types.h>
16*92dc5728SAndy Shevchenko
17*92dc5728SAndy Shevchenko #include "gpiolib-acpi.h"
18*92dc5728SAndy Shevchenko
19*92dc5728SAndy Shevchenko static int run_edge_events_on_boot = -1;
20*92dc5728SAndy Shevchenko module_param(run_edge_events_on_boot, int, 0444);
21*92dc5728SAndy Shevchenko MODULE_PARM_DESC(run_edge_events_on_boot,
22*92dc5728SAndy Shevchenko "Run edge _AEI event-handlers at boot: 0=no, 1=yes, -1=auto");
23*92dc5728SAndy Shevchenko
24*92dc5728SAndy Shevchenko static char *ignore_wake;
25*92dc5728SAndy Shevchenko module_param(ignore_wake, charp, 0444);
26*92dc5728SAndy Shevchenko MODULE_PARM_DESC(ignore_wake,
27*92dc5728SAndy Shevchenko "controller@pin combos on which to ignore the ACPI wake flag "
28*92dc5728SAndy Shevchenko "ignore_wake=controller@pin[,controller@pin[,...]]");
29*92dc5728SAndy Shevchenko
30*92dc5728SAndy Shevchenko static char *ignore_interrupt;
31*92dc5728SAndy Shevchenko module_param(ignore_interrupt, charp, 0444);
32*92dc5728SAndy Shevchenko MODULE_PARM_DESC(ignore_interrupt,
33*92dc5728SAndy Shevchenko "controller@pin combos on which to ignore interrupt "
34*92dc5728SAndy Shevchenko "ignore_interrupt=controller@pin[,controller@pin[,...]]");
35*92dc5728SAndy Shevchenko
36*92dc5728SAndy Shevchenko /*
37*92dc5728SAndy Shevchenko * For GPIO chips which call acpi_gpiochip_request_interrupts() before late_init
38*92dc5728SAndy Shevchenko * (so builtin drivers) we register the ACPI GpioInt IRQ handlers from a
39*92dc5728SAndy Shevchenko * late_initcall_sync() handler, so that other builtin drivers can register their
40*92dc5728SAndy Shevchenko * OpRegions before the event handlers can run. This list contains GPIO chips
41*92dc5728SAndy Shevchenko * for which the acpi_gpiochip_request_irqs() call has been deferred.
42*92dc5728SAndy Shevchenko */
43*92dc5728SAndy Shevchenko static DEFINE_MUTEX(acpi_gpio_deferred_req_irqs_lock);
44*92dc5728SAndy Shevchenko static LIST_HEAD(acpi_gpio_deferred_req_irqs_list);
45*92dc5728SAndy Shevchenko static bool acpi_gpio_deferred_req_irqs_done;
46*92dc5728SAndy Shevchenko
acpi_gpio_add_to_deferred_list(struct list_head * list)47*92dc5728SAndy Shevchenko bool acpi_gpio_add_to_deferred_list(struct list_head *list)
48*92dc5728SAndy Shevchenko {
49*92dc5728SAndy Shevchenko bool defer;
50*92dc5728SAndy Shevchenko
51*92dc5728SAndy Shevchenko mutex_lock(&acpi_gpio_deferred_req_irqs_lock);
52*92dc5728SAndy Shevchenko defer = !acpi_gpio_deferred_req_irqs_done;
53*92dc5728SAndy Shevchenko if (defer)
54*92dc5728SAndy Shevchenko list_add(list, &acpi_gpio_deferred_req_irqs_list);
55*92dc5728SAndy Shevchenko mutex_unlock(&acpi_gpio_deferred_req_irqs_lock);
56*92dc5728SAndy Shevchenko
57*92dc5728SAndy Shevchenko return defer;
58*92dc5728SAndy Shevchenko }
59*92dc5728SAndy Shevchenko
acpi_gpio_remove_from_deferred_list(struct list_head * list)60*92dc5728SAndy Shevchenko void acpi_gpio_remove_from_deferred_list(struct list_head *list)
61*92dc5728SAndy Shevchenko {
62*92dc5728SAndy Shevchenko mutex_lock(&acpi_gpio_deferred_req_irqs_lock);
63*92dc5728SAndy Shevchenko if (!list_empty(list))
64*92dc5728SAndy Shevchenko list_del_init(list);
65*92dc5728SAndy Shevchenko mutex_unlock(&acpi_gpio_deferred_req_irqs_lock);
66*92dc5728SAndy Shevchenko }
67*92dc5728SAndy Shevchenko
acpi_gpio_need_run_edge_events_on_boot(void)68*92dc5728SAndy Shevchenko int acpi_gpio_need_run_edge_events_on_boot(void)
69*92dc5728SAndy Shevchenko {
70*92dc5728SAndy Shevchenko return run_edge_events_on_boot;
71*92dc5728SAndy Shevchenko }
72*92dc5728SAndy Shevchenko
acpi_gpio_in_ignore_list(enum acpi_gpio_ignore_list list,const char * controller_in,unsigned int pin_in)73*92dc5728SAndy Shevchenko bool acpi_gpio_in_ignore_list(enum acpi_gpio_ignore_list list,
74*92dc5728SAndy Shevchenko const char *controller_in, unsigned int pin_in)
75*92dc5728SAndy Shevchenko {
76*92dc5728SAndy Shevchenko const char *ignore_list, *controller, *pin_str;
77*92dc5728SAndy Shevchenko unsigned int pin;
78*92dc5728SAndy Shevchenko char *endp;
79*92dc5728SAndy Shevchenko int len;
80*92dc5728SAndy Shevchenko
81*92dc5728SAndy Shevchenko switch (list) {
82*92dc5728SAndy Shevchenko case ACPI_GPIO_IGNORE_WAKE:
83*92dc5728SAndy Shevchenko ignore_list = ignore_wake;
84*92dc5728SAndy Shevchenko break;
85*92dc5728SAndy Shevchenko case ACPI_GPIO_IGNORE_INTERRUPT:
86*92dc5728SAndy Shevchenko ignore_list = ignore_interrupt;
87*92dc5728SAndy Shevchenko break;
88*92dc5728SAndy Shevchenko default:
89*92dc5728SAndy Shevchenko return false;
90*92dc5728SAndy Shevchenko }
91*92dc5728SAndy Shevchenko
92*92dc5728SAndy Shevchenko controller = ignore_list;
93*92dc5728SAndy Shevchenko while (controller) {
94*92dc5728SAndy Shevchenko pin_str = strchr(controller, '@');
95*92dc5728SAndy Shevchenko if (!pin_str)
96*92dc5728SAndy Shevchenko goto err;
97*92dc5728SAndy Shevchenko
98*92dc5728SAndy Shevchenko len = pin_str - controller;
99*92dc5728SAndy Shevchenko if (len == strlen(controller_in) &&
100*92dc5728SAndy Shevchenko strncmp(controller, controller_in, len) == 0) {
101*92dc5728SAndy Shevchenko pin = simple_strtoul(pin_str + 1, &endp, 10);
102*92dc5728SAndy Shevchenko if (*endp != 0 && *endp != ',')
103*92dc5728SAndy Shevchenko goto err;
104*92dc5728SAndy Shevchenko
105*92dc5728SAndy Shevchenko if (pin == pin_in)
106*92dc5728SAndy Shevchenko return true;
107*92dc5728SAndy Shevchenko }
108*92dc5728SAndy Shevchenko
109*92dc5728SAndy Shevchenko controller = strchr(controller, ',');
110*92dc5728SAndy Shevchenko if (controller)
111*92dc5728SAndy Shevchenko controller++;
112*92dc5728SAndy Shevchenko }
113*92dc5728SAndy Shevchenko
114*92dc5728SAndy Shevchenko return false;
115*92dc5728SAndy Shevchenko err:
116*92dc5728SAndy Shevchenko pr_err_once("Error: Invalid value for gpiolib_acpi.ignore_...: %s\n", ignore_list);
117*92dc5728SAndy Shevchenko return false;
118*92dc5728SAndy Shevchenko }
119*92dc5728SAndy Shevchenko
120*92dc5728SAndy Shevchenko /* Run deferred acpi_gpiochip_request_irqs() */
acpi_gpio_handle_deferred_request_irqs(void)121*92dc5728SAndy Shevchenko static int __init acpi_gpio_handle_deferred_request_irqs(void)
122*92dc5728SAndy Shevchenko {
123*92dc5728SAndy Shevchenko mutex_lock(&acpi_gpio_deferred_req_irqs_lock);
124*92dc5728SAndy Shevchenko acpi_gpio_process_deferred_list(&acpi_gpio_deferred_req_irqs_list);
125*92dc5728SAndy Shevchenko acpi_gpio_deferred_req_irqs_done = true;
126*92dc5728SAndy Shevchenko mutex_unlock(&acpi_gpio_deferred_req_irqs_lock);
127*92dc5728SAndy Shevchenko
128*92dc5728SAndy Shevchenko return 0;
129*92dc5728SAndy Shevchenko }
130*92dc5728SAndy Shevchenko /* We must use _sync so that this runs after the first deferred_probe run */
131*92dc5728SAndy Shevchenko late_initcall_sync(acpi_gpio_handle_deferred_request_irqs);
132*92dc5728SAndy Shevchenko
133*92dc5728SAndy Shevchenko struct acpi_gpiolib_dmi_quirk {
134*92dc5728SAndy Shevchenko bool no_edge_events_on_boot;
135*92dc5728SAndy Shevchenko char *ignore_wake;
136*92dc5728SAndy Shevchenko char *ignore_interrupt;
137*92dc5728SAndy Shevchenko };
138*92dc5728SAndy Shevchenko
139*92dc5728SAndy Shevchenko static const struct dmi_system_id gpiolib_acpi_quirks[] __initconst = {
140*92dc5728SAndy Shevchenko {
141*92dc5728SAndy Shevchenko /*
142*92dc5728SAndy Shevchenko * The Minix Neo Z83-4 has a micro-USB-B id-pin handler for
143*92dc5728SAndy Shevchenko * a non existing micro-USB-B connector which puts the HDMI
144*92dc5728SAndy Shevchenko * DDC pins in GPIO mode, breaking HDMI support.
145*92dc5728SAndy Shevchenko */
146*92dc5728SAndy Shevchenko .matches = {
147*92dc5728SAndy Shevchenko DMI_MATCH(DMI_SYS_VENDOR, "MINIX"),
148*92dc5728SAndy Shevchenko DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"),
149*92dc5728SAndy Shevchenko },
150*92dc5728SAndy Shevchenko .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
151*92dc5728SAndy Shevchenko .no_edge_events_on_boot = true,
152*92dc5728SAndy Shevchenko },
153*92dc5728SAndy Shevchenko },
154*92dc5728SAndy Shevchenko {
155*92dc5728SAndy Shevchenko /*
156*92dc5728SAndy Shevchenko * The Terra Pad 1061 has a micro-USB-B id-pin handler, which
157*92dc5728SAndy Shevchenko * instead of controlling the actual micro-USB-B turns the 5V
158*92dc5728SAndy Shevchenko * boost for its USB-A connector off. The actual micro-USB-B
159*92dc5728SAndy Shevchenko * connector is wired for charging only.
160*92dc5728SAndy Shevchenko */
161*92dc5728SAndy Shevchenko .matches = {
162*92dc5728SAndy Shevchenko DMI_MATCH(DMI_SYS_VENDOR, "Wortmann_AG"),
163*92dc5728SAndy Shevchenko DMI_MATCH(DMI_PRODUCT_NAME, "TERRA_PAD_1061"),
164*92dc5728SAndy Shevchenko },
165*92dc5728SAndy Shevchenko .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
166*92dc5728SAndy Shevchenko .no_edge_events_on_boot = true,
167*92dc5728SAndy Shevchenko },
168*92dc5728SAndy Shevchenko },
169*92dc5728SAndy Shevchenko {
170*92dc5728SAndy Shevchenko /*
171*92dc5728SAndy Shevchenko * The Dell Venue 10 Pro 5055, with Bay Trail SoC + TI PMIC uses an
172*92dc5728SAndy Shevchenko * external embedded-controller connected via I2C + an ACPI GPIO
173*92dc5728SAndy Shevchenko * event handler on INT33FFC:02 pin 12, causing spurious wakeups.
174*92dc5728SAndy Shevchenko */
175*92dc5728SAndy Shevchenko .matches = {
176*92dc5728SAndy Shevchenko DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
177*92dc5728SAndy Shevchenko DMI_MATCH(DMI_PRODUCT_NAME, "Venue 10 Pro 5055"),
178*92dc5728SAndy Shevchenko },
179*92dc5728SAndy Shevchenko .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
180*92dc5728SAndy Shevchenko .ignore_wake = "INT33FC:02@12",
181*92dc5728SAndy Shevchenko },
182*92dc5728SAndy Shevchenko },
183*92dc5728SAndy Shevchenko {
184*92dc5728SAndy Shevchenko /*
185*92dc5728SAndy Shevchenko * HP X2 10 models with Cherry Trail SoC + TI PMIC use an
186*92dc5728SAndy Shevchenko * external embedded-controller connected via I2C + an ACPI GPIO
187*92dc5728SAndy Shevchenko * event handler on INT33FF:01 pin 0, causing spurious wakeups.
188*92dc5728SAndy Shevchenko * When suspending by closing the LID, the power to the USB
189*92dc5728SAndy Shevchenko * keyboard is turned off, causing INT0002 ACPI events to
190*92dc5728SAndy Shevchenko * trigger once the XHCI controller notices the keyboard is
191*92dc5728SAndy Shevchenko * gone. So INT0002 events cause spurious wakeups too. Ignoring
192*92dc5728SAndy Shevchenko * EC wakes breaks wakeup when opening the lid, the user needs
193*92dc5728SAndy Shevchenko * to press the power-button to wakeup the system. The
194*92dc5728SAndy Shevchenko * alternative is suspend simply not working, which is worse.
195*92dc5728SAndy Shevchenko */
196*92dc5728SAndy Shevchenko .matches = {
197*92dc5728SAndy Shevchenko DMI_MATCH(DMI_SYS_VENDOR, "HP"),
198*92dc5728SAndy Shevchenko DMI_MATCH(DMI_PRODUCT_NAME, "HP x2 Detachable 10-p0XX"),
199*92dc5728SAndy Shevchenko },
200*92dc5728SAndy Shevchenko .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
201*92dc5728SAndy Shevchenko .ignore_wake = "INT33FF:01@0,INT0002:00@2",
202*92dc5728SAndy Shevchenko },
203*92dc5728SAndy Shevchenko },
204*92dc5728SAndy Shevchenko {
205*92dc5728SAndy Shevchenko /*
206*92dc5728SAndy Shevchenko * HP X2 10 models with Bay Trail SoC + AXP288 PMIC use an
207*92dc5728SAndy Shevchenko * external embedded-controller connected via I2C + an ACPI GPIO
208*92dc5728SAndy Shevchenko * event handler on INT33FC:02 pin 28, causing spurious wakeups.
209*92dc5728SAndy Shevchenko */
210*92dc5728SAndy Shevchenko .matches = {
211*92dc5728SAndy Shevchenko DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
212*92dc5728SAndy Shevchenko DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"),
213*92dc5728SAndy Shevchenko DMI_MATCH(DMI_BOARD_NAME, "815D"),
214*92dc5728SAndy Shevchenko },
215*92dc5728SAndy Shevchenko .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
216*92dc5728SAndy Shevchenko .ignore_wake = "INT33FC:02@28",
217*92dc5728SAndy Shevchenko },
218*92dc5728SAndy Shevchenko },
219*92dc5728SAndy Shevchenko {
220*92dc5728SAndy Shevchenko /*
221*92dc5728SAndy Shevchenko * HP X2 10 models with Cherry Trail SoC + AXP288 PMIC use an
222*92dc5728SAndy Shevchenko * external embedded-controller connected via I2C + an ACPI GPIO
223*92dc5728SAndy Shevchenko * event handler on INT33FF:01 pin 0, causing spurious wakeups.
224*92dc5728SAndy Shevchenko */
225*92dc5728SAndy Shevchenko .matches = {
226*92dc5728SAndy Shevchenko DMI_MATCH(DMI_SYS_VENDOR, "HP"),
227*92dc5728SAndy Shevchenko DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"),
228*92dc5728SAndy Shevchenko DMI_MATCH(DMI_BOARD_NAME, "813E"),
229*92dc5728SAndy Shevchenko },
230*92dc5728SAndy Shevchenko .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
231*92dc5728SAndy Shevchenko .ignore_wake = "INT33FF:01@0",
232*92dc5728SAndy Shevchenko },
233*92dc5728SAndy Shevchenko },
234*92dc5728SAndy Shevchenko {
235*92dc5728SAndy Shevchenko /*
236*92dc5728SAndy Shevchenko * Interrupt storm caused from edge triggered floating pin
237*92dc5728SAndy Shevchenko * Found in BIOS UX325UAZ.300
238*92dc5728SAndy Shevchenko * https://bugzilla.kernel.org/show_bug.cgi?id=216208
239*92dc5728SAndy Shevchenko */
240*92dc5728SAndy Shevchenko .matches = {
241*92dc5728SAndy Shevchenko DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
242*92dc5728SAndy Shevchenko DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UAZ_UM325UAZ"),
243*92dc5728SAndy Shevchenko },
244*92dc5728SAndy Shevchenko .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
245*92dc5728SAndy Shevchenko .ignore_interrupt = "AMDI0030:00@18",
246*92dc5728SAndy Shevchenko },
247*92dc5728SAndy Shevchenko },
248*92dc5728SAndy Shevchenko {
249*92dc5728SAndy Shevchenko /*
250*92dc5728SAndy Shevchenko * Spurious wakeups from TP_ATTN# pin
251*92dc5728SAndy Shevchenko * Found in BIOS 1.7.8
252*92dc5728SAndy Shevchenko * https://gitlab.freedesktop.org/drm/amd/-/issues/1722#note_1720627
253*92dc5728SAndy Shevchenko */
254*92dc5728SAndy Shevchenko .matches = {
255*92dc5728SAndy Shevchenko DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"),
256*92dc5728SAndy Shevchenko },
257*92dc5728SAndy Shevchenko .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
258*92dc5728SAndy Shevchenko .ignore_wake = "ELAN0415:00@9",
259*92dc5728SAndy Shevchenko },
260*92dc5728SAndy Shevchenko },
261*92dc5728SAndy Shevchenko {
262*92dc5728SAndy Shevchenko /*
263*92dc5728SAndy Shevchenko * Spurious wakeups from TP_ATTN# pin
264*92dc5728SAndy Shevchenko * Found in BIOS 1.7.8
265*92dc5728SAndy Shevchenko * https://gitlab.freedesktop.org/drm/amd/-/issues/1722#note_1720627
266*92dc5728SAndy Shevchenko */
267*92dc5728SAndy Shevchenko .matches = {
268*92dc5728SAndy Shevchenko DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"),
269*92dc5728SAndy Shevchenko },
270*92dc5728SAndy Shevchenko .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
271*92dc5728SAndy Shevchenko .ignore_wake = "ELAN0415:00@9",
272*92dc5728SAndy Shevchenko },
273*92dc5728SAndy Shevchenko },
274*92dc5728SAndy Shevchenko {
275*92dc5728SAndy Shevchenko /*
276*92dc5728SAndy Shevchenko * Spurious wakeups from TP_ATTN# pin
277*92dc5728SAndy Shevchenko * Found in BIOS 1.7.7
278*92dc5728SAndy Shevchenko */
279*92dc5728SAndy Shevchenko .matches = {
280*92dc5728SAndy Shevchenko DMI_MATCH(DMI_BOARD_NAME, "NH5xAx"),
281*92dc5728SAndy Shevchenko },
282*92dc5728SAndy Shevchenko .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
283*92dc5728SAndy Shevchenko .ignore_wake = "SYNA1202:00@16",
284*92dc5728SAndy Shevchenko },
285*92dc5728SAndy Shevchenko },
286*92dc5728SAndy Shevchenko {
287*92dc5728SAndy Shevchenko /*
288*92dc5728SAndy Shevchenko * On the Peaq C1010 2-in-1 INT33FC:00 pin 3 is connected to
289*92dc5728SAndy Shevchenko * a "dolby" button. At the ACPI level an _AEI event-handler
290*92dc5728SAndy Shevchenko * is connected which sets an ACPI variable to 1 on both
291*92dc5728SAndy Shevchenko * edges. This variable can be polled + cleared to 0 using
292*92dc5728SAndy Shevchenko * WMI. But since the variable is set on both edges the WMI
293*92dc5728SAndy Shevchenko * interface is pretty useless even when polling.
294*92dc5728SAndy Shevchenko * So instead the x86-android-tablets code instantiates
295*92dc5728SAndy Shevchenko * a gpio-keys platform device for it.
296*92dc5728SAndy Shevchenko * Ignore the _AEI handler for the pin, so that it is not busy.
297*92dc5728SAndy Shevchenko */
298*92dc5728SAndy Shevchenko .matches = {
299*92dc5728SAndy Shevchenko DMI_MATCH(DMI_SYS_VENDOR, "PEAQ"),
300*92dc5728SAndy Shevchenko DMI_MATCH(DMI_PRODUCT_NAME, "PEAQ PMM C1010 MD99187"),
301*92dc5728SAndy Shevchenko },
302*92dc5728SAndy Shevchenko .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
303*92dc5728SAndy Shevchenko .ignore_interrupt = "INT33FC:00@3",
304*92dc5728SAndy Shevchenko },
305*92dc5728SAndy Shevchenko },
306*92dc5728SAndy Shevchenko {
307*92dc5728SAndy Shevchenko /*
308*92dc5728SAndy Shevchenko * Spurious wakeups from TP_ATTN# pin
309*92dc5728SAndy Shevchenko * Found in BIOS 0.35
310*92dc5728SAndy Shevchenko * https://gitlab.freedesktop.org/drm/amd/-/issues/3073
311*92dc5728SAndy Shevchenko */
312*92dc5728SAndy Shevchenko .matches = {
313*92dc5728SAndy Shevchenko DMI_MATCH(DMI_SYS_VENDOR, "GPD"),
314*92dc5728SAndy Shevchenko DMI_MATCH(DMI_PRODUCT_NAME, "G1619-04"),
315*92dc5728SAndy Shevchenko },
316*92dc5728SAndy Shevchenko .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
317*92dc5728SAndy Shevchenko .ignore_wake = "PNP0C50:00@8",
318*92dc5728SAndy Shevchenko },
319*92dc5728SAndy Shevchenko },
320*92dc5728SAndy Shevchenko {
321*92dc5728SAndy Shevchenko /*
322*92dc5728SAndy Shevchenko * Spurious wakeups from GPIO 11
323*92dc5728SAndy Shevchenko * Found in BIOS 1.04
324*92dc5728SAndy Shevchenko * https://gitlab.freedesktop.org/drm/amd/-/issues/3954
325*92dc5728SAndy Shevchenko */
326*92dc5728SAndy Shevchenko .matches = {
327*92dc5728SAndy Shevchenko DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
328*92dc5728SAndy Shevchenko DMI_MATCH(DMI_PRODUCT_FAMILY, "Acer Nitro V 14"),
329*92dc5728SAndy Shevchenko },
330*92dc5728SAndy Shevchenko .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
331*92dc5728SAndy Shevchenko .ignore_interrupt = "AMDI0030:00@11",
332*92dc5728SAndy Shevchenko },
333*92dc5728SAndy Shevchenko },
334*92dc5728SAndy Shevchenko {} /* Terminating entry */
335*92dc5728SAndy Shevchenko };
336*92dc5728SAndy Shevchenko
acpi_gpio_setup_params(void)337*92dc5728SAndy Shevchenko static int __init acpi_gpio_setup_params(void)
338*92dc5728SAndy Shevchenko {
339*92dc5728SAndy Shevchenko const struct acpi_gpiolib_dmi_quirk *quirk = NULL;
340*92dc5728SAndy Shevchenko const struct dmi_system_id *id;
341*92dc5728SAndy Shevchenko
342*92dc5728SAndy Shevchenko id = dmi_first_match(gpiolib_acpi_quirks);
343*92dc5728SAndy Shevchenko if (id)
344*92dc5728SAndy Shevchenko quirk = id->driver_data;
345*92dc5728SAndy Shevchenko
346*92dc5728SAndy Shevchenko if (run_edge_events_on_boot < 0) {
347*92dc5728SAndy Shevchenko if (quirk && quirk->no_edge_events_on_boot)
348*92dc5728SAndy Shevchenko run_edge_events_on_boot = 0;
349*92dc5728SAndy Shevchenko else
350*92dc5728SAndy Shevchenko run_edge_events_on_boot = 1;
351*92dc5728SAndy Shevchenko }
352*92dc5728SAndy Shevchenko
353*92dc5728SAndy Shevchenko if (ignore_wake == NULL && quirk && quirk->ignore_wake)
354*92dc5728SAndy Shevchenko ignore_wake = quirk->ignore_wake;
355*92dc5728SAndy Shevchenko
356*92dc5728SAndy Shevchenko if (ignore_interrupt == NULL && quirk && quirk->ignore_interrupt)
357*92dc5728SAndy Shevchenko ignore_interrupt = quirk->ignore_interrupt;
358*92dc5728SAndy Shevchenko
359*92dc5728SAndy Shevchenko return 0;
360*92dc5728SAndy Shevchenko }
361*92dc5728SAndy Shevchenko
362*92dc5728SAndy Shevchenko /* Directly after dmi_setup() which runs as core_initcall() */
363*92dc5728SAndy Shevchenko postcore_initcall(acpi_gpio_setup_params);
364