2 * ChromeOS EC multi-function device
4 * Copyright (C) 2017 Google, Inc
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * The ChromeOS EC multi function device is used to mux all the requests
16 * to the EC device for its multiple features: keyboard controller,
17 * battery charging and regulator control, firmware update.
19 #include <linux/acpi.h>
21 #define ACPI_LID_DEVICE "LID0"
23 static int ec_wake_gpe
= -EINVAL
;
26 * This handler indicates to ACPI core that this GPE should stay enabled for
27 * lid to work in suspend to idle path.
29 static u32
cros_ec_gpe_handler(acpi_handle gpe_device
, u32 gpe_number
,
32 return ACPI_INTERRUPT_HANDLED
| ACPI_REENABLE_GPE
;
36 * Get ACPI GPE for LID0 device.
38 static int cros_ec_get_ec_wake_gpe(struct device
*dev
)
40 struct acpi_device
*cros_acpi_dev
;
41 struct acpi_device
*adev
;
46 cros_acpi_dev
= ACPI_COMPANION(dev
);
48 if (!cros_acpi_dev
|| !cros_acpi_dev
->parent
||
49 !cros_acpi_dev
->parent
->handle
)
52 status
= acpi_get_handle(cros_acpi_dev
->parent
->handle
, ACPI_LID_DEVICE
,
54 if (ACPI_FAILURE(status
))
57 ret
= acpi_bus_get_device(handle
, &adev
);
61 return adev
->wakeup
.gpe_number
;
64 int cros_ec_acpi_install_gpe_handler(struct device
*dev
)
68 ec_wake_gpe
= cros_ec_get_ec_wake_gpe(dev
);
73 status
= acpi_install_gpe_handler(NULL
, ec_wake_gpe
,
74 ACPI_GPE_EDGE_TRIGGERED
,
75 &cros_ec_gpe_handler
, NULL
);
76 if (ACPI_FAILURE(status
))
79 dev_info(dev
, "Initialized, GPE = 0x%x\n", ec_wake_gpe
);
84 void cros_ec_acpi_remove_gpe_handler(void)
91 status
= acpi_remove_gpe_handler(NULL
, ec_wake_gpe
,
92 &cros_ec_gpe_handler
);
93 if (ACPI_FAILURE(status
))
94 pr_err("failed to remove gpe handler\n");
97 void cros_ec_acpi_clear_gpe(void)
102 acpi_clear_gpe(NULL
, ec_wake_gpe
);