Skip to content

Commit 66c8401

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
1 parent 94e747e commit 66c8401

File tree

1 file changed

+26
-0
lines changed

1 file changed

+26
-0
lines changed

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];
@@ -326,6 +332,13 @@ static int surface3_spi_create_pen_input(struct surface3_ts_data *data)
326332
return 0;
327333
}
328334

335+
static bool surface3_spi_can_dma(struct spi_controller *ctlr,
336+
struct spi_device *spi,
337+
struct spi_transfer *tfr)
338+
{
339+
return use_dma;
340+
}
341+
329342
static int surface3_spi_probe(struct spi_device *spi)
330343
{
331344
struct surface3_ts_data *data;
@@ -368,6 +381,19 @@ static int surface3_spi_probe(struct spi_device *spi)
368381
if (error)
369382
return error;
370383

384+
/*
385+
* Set up DMA
386+
*
387+
* TODO: Currently, touch input with DMA seems to be broken.
388+
* On 4.19 LTS, touch input will crash after suspend.
389+
* On recent stable kernel (at least after 5.1), touch input will crash after
390+
* the first touch. No problem with PIO on those kernels.
391+
* Maybe we need to configure DMA here.
392+
*
393+
* Link to issue: https://github.com/jakeday/linux-surface/issues/596
394+
*/
395+
spi->controller->can_dma = surface3_spi_can_dma;
396+
371397
return 0;
372398
}
373399

0 commit comments

Comments
 (0)