RE: [PATCH] HID: intel-thc-hid: intel-quickspi: reset touch IC on system resume
From: Xu, Even
Date: Sun May 31 2026 - 23:26:45 EST
Sorry, missed the doc link: https://docs.kernel.org/admin-guide/pm/sleep-states.html
> -----Original Message-----
> From: Xu, Even
> Sent: Monday, June 1, 2026 11:25 AM
> To: 'd3z-the-dev' <d3z.the.dev@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>
> Subject: RE: [PATCH] HID: intel-thc-hid: intel-quickspi: reset touch IC on system
> resume
>
> 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