RE: [PATCH] HID: intel-thc-hid: intel-quickspi: reset touch IC on system resume
From: Xu, Even
Date: Sun May 31 2026 - 23:25:58 EST
Hi,
Sorry, I cannot get your exact name from this patch email.
>From your issue description, I suppose Surface Pro 10 uses "Suspend-to-RAM" instead of "Standby" or "Suspend-to-Idle" for suspend/resume.
As this documents mentioned, driver needs to take care the suspend type then handle resume flow carefully.
Actually, I had a patch for this "Suspend-to-RAM" support several months ago, please find attached file for the patch. This patch is still under our internal final validation.
It will be very appreciated if you can help test attached patch on your Surface device.
If it works, then everything is fine, I will submit this patch with your name after our final validation.
If it doesn't work for your case, then we need to future debug on your surface device to refine your patch to let it more standard.
Thanks!
Best Regards,
Even Xu
> -----Original Message-----
> From: d3z-the-dev <d3z.the.dev@xxxxxxxxx>
> Sent: Saturday, May 30, 2026 6:22 AM
> To: Xu, Even <even.xu@xxxxxxxxx>; Sun, Xinpeng <xinpeng.sun@xxxxxxxxx>; Jiri
> Kosina <jikos@xxxxxxxxxx>; Benjamin Tissoires <bentiss@xxxxxxxxxx>
> Cc: linux-input@xxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx; Abhishek Tamboli
> <abhishektamboli9@xxxxxxxxx>; Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx>;
> d3z-the-dev <d3z.the.dev@xxxxxxxxx>
> Subject: [PATCH] HID: intel-thc-hid: intel-quickspi: reset touch IC on system
> resume
>
> On the Surface Pro 10 (Meteor Lake) the touchscreen stops working after a
> suspend/resume cycle and only recovers after a reboot. The driver logs
> "GET_DEVICE_INFO: recv failed: -11" on resume.
>
> The touch IC loses power during system suspend (s2idle) on this platform, the
> same way it does across hibernation. quickspi_resume() only restores the THC
> port, interrupts and DMA and sends a HIDSPI_ON command, assuming the touch
> IC kept its power and state. When it has actually lost power the HIDSPI_ON
> command is never acknowledged and the descriptor read fails, leaving the
> touchscreen dead until the module is reloaded.
>
> quickspi_restore() already handles this for hibernation by running
> reset_tic() and reconfiguring the THC SPI/LTR settings. Make
> quickspi_resume() do the same: quiesce interrupts, re-select the THC port,
> reconfigure the SPI input/output addresses and read/write parameters, run
> reset_tic() to re-enumerate the device and restore the LTR configuration.
>
> Tested on a Surface Pro 10 across multiple s2idle suspend/resume cycles.
>
> Link: https://github.com/linux-surface/linux-surface/issues/1799
>
> Signed-off-by: d3z-the-dev <d3z.the.dev@xxxxxxxxx>
> ---
> .../intel-quickspi/pci-quickspi.c | 38 +++++++++++++++++--
> 1 file changed, 34 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
> b/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
> index f669235f1883..d59278a3e5c1 100644
> --- a/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
> +++ b/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
> @@ -780,24 +780,54 @@ static int quickspi_resume(struct device *device)
> if (!qsdev)
> return -ENODEV;
>
> + ret = thc_interrupt_quiesce(qsdev->thc_hw, true);
> + if (ret)
> + return ret;
> +
> ret = thc_port_select(qsdev->thc_hw, THC_PORT_TYPE_SPI);
> if (ret)
> return ret;
>
> + thc_spi_input_output_address_config(qsdev->thc_hw,
> + qsdev->input_report_hdr_addr,
> + qsdev->input_report_bdy_addr,
> + qsdev->output_report_addr);
> +
> + ret = thc_spi_read_config(qsdev->thc_hw, qsdev->spi_freq_val,
> + qsdev->spi_read_io_mode,
> + qsdev->spi_read_opcode,
> + qsdev->spi_packet_size);
> + if (ret)
> + return ret;
> +
> + ret = thc_spi_write_config(qsdev->thc_hw, qsdev->spi_freq_val,
> + qsdev->spi_write_io_mode,
> + qsdev->spi_write_opcode,
> + qsdev->spi_packet_size,
> + qsdev->performance_limit);
> + if (ret)
> + return ret;
> +
> thc_interrupt_config(qsdev->thc_hw);
>
> thc_interrupt_enable(qsdev->thc_hw, true);
>
> - ret = thc_dma_configure(qsdev->thc_hw);
> + /* The TIC may lose power across system suspend, reset it to recover */
> + ret = reset_tic(qsdev);
> if (ret)
> return ret;
>
> - ret = thc_interrupt_quiesce(qsdev->thc_hw, false);
> + ret = thc_dma_configure(qsdev->thc_hw);
> if (ret)
> return ret;
>
> - if (!device_may_wakeup(qsdev->dev))
> - return quickspi_set_power(qsdev, HIDSPI_ON);
> + thc_ltr_config(qsdev->thc_hw,
> + qsdev->active_ltr_val,
> + qsdev->low_power_ltr_val);
> +
> + thc_change_ltr_mode(qsdev->thc_hw, THC_LTR_MODE_ACTIVE);
> +
> + qsdev->state = QUICKSPI_ENABLED;
>
> return 0;
> }
> --
> 2.54.0
Attachment:
0001-Hid-Intel-thc-hid-Intel-quickspi-Fix-non-functional-.patch
Description: 0001-Hid-Intel-thc-hid-Intel-quickspi-Fix-non-functional-.patch