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

HID: Intel-thc-hid: Intel-thc: Add Wake-on-Touch support

Wake-on-Touch (WoT) feature gives system the capability to wake from
sleep state by user touch event, it requires platform providing wake
GPIO through ACPI resource.

Intel UEFI provides a user setting to enable or disable THC device WoT
feature. If it's enabled, UEFI assigns an additional wake GPIO resource
to THC device ACPI configuration, facilitating system wakeup.

This patch provides helper APIs for THC device driver to query wake
GPIO resource, enable WoT feature and unconfigure WoT.

APIs added:
- thc_wot_config(): Query and configure wake-on-touch feature.
- thc_wot_unconfig(): Unconfig wake-on-touch feature.

Signed-off-by: Even Xu <even.xu@intel.com>
Tested-by: Chong Han <chong.han@intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>

authored by

Even Xu and committed by
Jiri Kosina
dcb2ccb9 2c7c9c5d

+125
+1
drivers/hid/intel-thc-hid/Makefile
··· 8 8 obj-$(CONFIG_INTEL_THC_HID) += intel-thc.o 9 9 intel-thc-objs += intel-thc/intel-thc-dev.o 10 10 intel-thc-objs += intel-thc/intel-thc-dma.o 11 + intel-thc-objs += intel-thc/intel-thc-wot.o 11 12 12 13 obj-$(CONFIG_INTEL_QUICKSPI) += intel-quickspi.o 13 14 intel-quickspi-objs += intel-quickspi/pci-quickspi.o
+4
drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.h
··· 9 9 #include <linux/workqueue.h> 10 10 11 11 #include "intel-thc-dma.h" 12 + #include "intel-thc-wot.h" 12 13 13 14 #define THC_REGMAP_COMMON_OFFSET 0x10 14 15 #define THC_REGMAP_MMIO_OFFSET 0x1000 ··· 57 56 * @port_type: Port type of THC port instance 58 57 * @pio_int_supported: PIO interrupt supported flag 59 58 * @dma_ctx: DMA specific data 59 + * @wot: THC Wake-on-Touch data 60 60 * @write_complete_wait: Signal event for DMA write complete 61 61 * @swdma_complete_wait: Signal event for SWDMA sequence complete 62 62 * @write_done: Bool value that indicates if DMA write is done ··· 78 76 bool pio_int_supported; 79 77 80 78 struct thc_dma_context *dma_ctx; 79 + 80 + struct thc_wot wot; 81 81 82 82 wait_queue_head_t write_complete_wait; 83 83 wait_queue_head_t swdma_complete_wait;
+94
drivers/hid/intel-thc-hid/intel-thc/intel-thc-wot.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2025 Intel Corporation */ 3 + 4 + #include <linux/acpi.h> 5 + #include <linux/pm_wakeirq.h> 6 + 7 + #include "intel-thc-dev.h" 8 + #include "intel-thc-wot.h" 9 + 10 + /** 11 + * thc_wot_config - Query and configure wake-on-touch feature 12 + * @thc_dev: Point to thc_device structure 13 + * @gpio_map: Point to ACPI GPIO resource mapping structure 14 + * 15 + * THC ACPI device only provides _CRS with GpioInt() resources, doesn't contain 16 + * _DSD to map this GPIO resource, so this function first registers wake GPIO 17 + * mapping manually, then queries wake-on-touch GPIO resource from ACPI, 18 + * if it exists and is wake-able, configure driver to enable it, otherwise, 19 + * return immediately. 20 + * This function will not return error as it doesn't impact major function. 21 + */ 22 + void thc_wot_config(struct thc_device *thc_dev, const struct acpi_gpio_mapping *gpio_map) 23 + { 24 + struct acpi_device *adev; 25 + struct thc_wot *wot; 26 + int ret; 27 + 28 + if (!thc_dev) 29 + return; 30 + 31 + adev = ACPI_COMPANION(thc_dev->dev); 32 + if (!adev) 33 + return; 34 + 35 + wot = &thc_dev->wot; 36 + 37 + ret = acpi_dev_add_driver_gpios(adev, gpio_map); 38 + if (ret) { 39 + dev_warn(thc_dev->dev, "Can't add wake GPIO resource, ret = %d\n", ret); 40 + return; 41 + } 42 + 43 + wot->gpio_irq = acpi_dev_gpio_irq_wake_get_by(adev, "wake-on-touch", 0, 44 + &wot->gpio_irq_wakeable); 45 + if (wot->gpio_irq <= 0) { 46 + dev_warn(thc_dev->dev, "Can't find wake GPIO resource\n"); 47 + return; 48 + } 49 + 50 + if (!wot->gpio_irq_wakeable) { 51 + dev_warn(thc_dev->dev, "GPIO resource isn't wakeable\n"); 52 + return; 53 + } 54 + 55 + ret = device_init_wakeup(thc_dev->dev, true); 56 + if (ret) { 57 + dev_warn(thc_dev->dev, "Failed to init wake up.\n"); 58 + return; 59 + } 60 + 61 + ret = dev_pm_set_dedicated_wake_irq(thc_dev->dev, wot->gpio_irq); 62 + if (ret) { 63 + dev_warn(thc_dev->dev, "Failed to set wake up IRQ.\n"); 64 + device_init_wakeup(thc_dev->dev, false); 65 + } 66 + } 67 + EXPORT_SYMBOL_NS_GPL(thc_wot_config, "INTEL_THC"); 68 + 69 + /** 70 + * thc_wot_unconfig - Unconfig wake-on-touch feature 71 + * @thc_dev: Point to thc_device structure 72 + * 73 + * Configure driver to disable wake-on-touch and release ACPI resource. 74 + */ 75 + void thc_wot_unconfig(struct thc_device *thc_dev) 76 + { 77 + struct acpi_device *adev; 78 + 79 + if (!thc_dev) 80 + return; 81 + 82 + adev = ACPI_COMPANION(thc_dev->dev); 83 + if (!adev) 84 + return; 85 + 86 + if (thc_dev->wot.gpio_irq_wakeable) 87 + device_init_wakeup(thc_dev->dev, false); 88 + 89 + if (thc_dev->wot.gpio_irq > 0) { 90 + dev_pm_clear_wake_irq(thc_dev->dev); 91 + acpi_dev_remove_driver_gpios(adev); 92 + } 93 + } 94 + EXPORT_SYMBOL_NS_GPL(thc_wot_unconfig, "INTEL_THC");
+26
drivers/hid/intel-thc-hid/intel-thc/intel-thc-wot.h
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2025 Intel Corporation */ 3 + 4 + #ifndef _INTEL_THC_WOT_H_ 5 + #define _INTEL_THC_WOT_H_ 6 + 7 + #include <linux/types.h> 8 + 9 + #include <linux/gpio/consumer.h> 10 + 11 + /** 12 + * struct thc_wot - THC Wake-on-Touch data structure 13 + * @gpio_irq : GPIO interrupt IRQ number for wake-on-touch 14 + * @gpio_irq_wakeable : Indicate GPIO IRQ workable or not 15 + */ 16 + struct thc_wot { 17 + int gpio_irq; 18 + bool gpio_irq_wakeable; 19 + }; 20 + 21 + struct thc_device; 22 + 23 + void thc_wot_config(struct thc_device *thc_dev, const struct acpi_gpio_mapping *gpio_map); 24 + void thc_wot_unconfig(struct thc_device *thc_dev); 25 + 26 + #endif /* _INTEL_THC_WOT_H_ */