Skip to content

Commit ebacd5e

Browse files
kitakar5525qzed
authored andcommitted
surface3-spi: workaround: disable DMA mode to avoid crash by default
On Arch Linux kernel at least after 4.19, touch input is broken after suspend (s2idle). kern :err : [ +0.203408] Surface3-spi spi-MSHW0037:00: SPI transfer timed out On recent stable Arch Linux kernel (at least after 5.1), touch input will crash after the first touch. kern :err : [ +0.203592] Surface3-spi spi-MSHW0037:00: SPI transfer timed out kern :err : [ +0.000173] spi_master spi1: failed to transfer one message from queue I found on an affected system (Arch Linux kernel, etc.), the touchscreen driver uses DMA mode by default. Then, we found some kernels with different kernel config (5.1 kernel config from Jakeday [1] or Chromium OS kernel chromeos-4.19 [2]) will use PIO mode by default and no such issues there. So, this commit disables DMA mode on the touchscreen driver side as a quick workaround to avoid touch input crash. We may need to properly set up DMA mode to use the touchscreen driver with DMA mode. You can still switch DMA/PIO mode if you want: switch to DMA mode (maybe broken) echo 1 | sudo tee /sys/module/surface3_spi/parameters/use_dma back to PIO mode echo 0 | sudo tee /sys/module/surface3_spi/parameters/use_dma Link to issue: jakeday/linux-surface#596 References: [1] https://github.com/jakeday/linux-surface/blob/master/configs/5.1/config [2] https://chromium.googlesource.com/chromiumos/third_party/kernel/+/refs/heads/chromeos-4.19 Tested on Arch Linux 5.4.1 with Surface 3, which will use DMA by default. This commit made the driver use PIO by default and no touch input crash. Also tested on chromeos-4.19 4.19.90 with Surface 3, which will use PIO by default even without this commit. After this commit, it still uses PIO and confirmed no functional changes regarding touch input. More details: We can confirm which mode the touchscreen driver uses; first, enable debug output: echo "file drivers/spi/spi-pxa2xx.c +p" | sudo tee /sys/kernel/debug/dynamic_debug/control echo "file drivers/input/touchscreen/surface3_spi.c +p" | sudo tee /sys/kernel/debug/dynamic_debug/control Then, try to make a touch input and see dmesg log (On Arch Linux kernel, uses DMA) kern :debug : [ +0.006383] Surface3-spi spi-MSHW0037:00: 7692307 Hz actual, DMA kern :debug : [ +0.000495] Surface3-spi spi-MSHW0037:00: surface3_spi_irq_handler received -> ff ff ff ff a5 5a e7 7e 01 d2 00 80 01 03 03 18 00 e4 01 00 04 1a 04 1a e3 0c e3 0c b0 00 c5 00 00 00 00 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff (On the kernels I referenced above, uses PIO) kern :debug : [ +0.009260] Surface3-spi spi-MSHW0037:00: 7692307 Hz actual, PIO kern :debug : [ +0.001105] Surface3-spi spi-MSHW0037:00: surface3_spi_irq_handler received -> ff ff ff ff a5 5a e7 7e 01 d2 00 80 01 03 03 24 00 e4 01 00 58 0b 58 0b 83 12 83 12 26 01 95 01 00 00 00 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff Note (2025-03-08): This patch was originally dropped due to the comments in [3]. However, according to the commments in [4] it is still required. [3]: a3421c1 [4]: linux-surface/linux-surface#1184 Patchset: surface3
1 parent 97e443f commit ebacd5e

1 file changed

Lines changed: 26 additions & 0 deletions

File tree

‎drivers/input/touchscreen/surface3_spi.c‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@
2525
#define SURFACE3_REPORT_TOUCH 0xd2
2626
#define SURFACE3_REPORT_PEN 0x16
2727

28+
bool use_dma = false;
29+
module_param(use_dma, bool, 0644);
30+
MODULE_PARM_DESC(use_dma,
31+
"Disable DMA mode if you encounter touch input crash. "
32+
"(default: false, disabled to avoid crash)");
33+
2834
struct surface3_ts_data {
2935
struct spi_device *spi;
3036
struct gpio_desc *gpiod_rst[2];
@@ -317,6 +323,13 @@ static int surface3_spi_create_pen_input(struct surface3_ts_data *data)
317323
return 0;
318324
}
319325

326+
static bool surface3_spi_can_dma(struct spi_controller *ctlr,
327+
struct spi_device *spi,
328+
struct spi_transfer *tfr)
329+
{
330+
return use_dma;
331+
}
332+
320333
static int surface3_spi_probe(struct spi_device *spi)
321334
{
322335
struct surface3_ts_data *data;
@@ -359,6 +372,19 @@ static int surface3_spi_probe(struct spi_device *spi)
359372
if (error)
360373
return error;
361374

375+
/*
376+
* Set up DMA
377+
*
378+
* TODO: Currently, touch input with DMA seems to be broken.
379+
* On 4.19 LTS, touch input will crash after suspend.
380+
* On recent stable kernel (at least after 5.1), touch input will crash after
381+
* the first touch. No problem with PIO on those kernels.
382+
* Maybe we need to configure DMA here.
383+
*
384+
* Link to issue: https://github.com/jakeday/linux-surface/issues/596
385+
*/
386+
spi->controller->can_dma = surface3_spi_can_dma;
387+
362388
return 0;
363389
}
364390

0 commit comments

Comments
 (0)