Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.14 103 lines 2.5 kB view raw
1/* 2 * ChromeOS EC multi-function device 3 * 4 * Copyright (C) 2017 Google, Inc 5 * 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. 9 * 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. 14 * 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. 18 */ 19#include <linux/acpi.h> 20 21#define ACPI_LID_DEVICE "LID0" 22 23static int ec_wake_gpe = -EINVAL; 24 25/* 26 * This handler indicates to ACPI core that this GPE should stay enabled for 27 * lid to work in suspend to idle path. 28 */ 29static u32 cros_ec_gpe_handler(acpi_handle gpe_device, u32 gpe_number, 30 void *data) 31{ 32 return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE; 33} 34 35/* 36 * Get ACPI GPE for LID0 device. 37 */ 38static int cros_ec_get_ec_wake_gpe(struct device *dev) 39{ 40 struct acpi_device *cros_acpi_dev; 41 struct acpi_device *adev; 42 acpi_handle handle; 43 acpi_status status; 44 int ret; 45 46 cros_acpi_dev = ACPI_COMPANION(dev); 47 48 if (!cros_acpi_dev || !cros_acpi_dev->parent || 49 !cros_acpi_dev->parent->handle) 50 return -EINVAL; 51 52 status = acpi_get_handle(cros_acpi_dev->parent->handle, ACPI_LID_DEVICE, 53 &handle); 54 if (ACPI_FAILURE(status)) 55 return -EINVAL; 56 57 ret = acpi_bus_get_device(handle, &adev); 58 if (ret) 59 return ret; 60 61 return adev->wakeup.gpe_number; 62} 63 64int cros_ec_acpi_install_gpe_handler(struct device *dev) 65{ 66 acpi_status status; 67 68 ec_wake_gpe = cros_ec_get_ec_wake_gpe(dev); 69 70 if (ec_wake_gpe < 0) 71 return ec_wake_gpe; 72 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)) 77 return -ENODEV; 78 79 dev_info(dev, "Initialized, GPE = 0x%x\n", ec_wake_gpe); 80 81 return 0; 82} 83 84void cros_ec_acpi_remove_gpe_handler(void) 85{ 86 acpi_status status; 87 88 if (ec_wake_gpe < 0) 89 return; 90 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"); 95} 96 97void cros_ec_acpi_clear_gpe(void) 98{ 99 if (ec_wake_gpe < 0) 100 return; 101 102 acpi_clear_gpe(NULL, ec_wake_gpe); 103}