2021-03-15 07:29:29

by AceLan Kao

[permalink] [raw]
Subject: [PATCH] Input: i8042 - add dmi quirk

From: "Chia-Lin Kao (AceLan)" <[email protected]>

On some platforms, the EC doesn't support the register reading sequence
for sentelic[1], and then make the EC can't respond commands for a while
when probing. It leads to the keyboard non-responsive for around 10
seconds while waking up from s2idle.

[ 44.304488] i8042: [9804] d4 -> i8042 (command)
[ 44.304634] i8042: [9804] f3 -> i8042 (parameter)
[ 44.304787] i8042: [9804] fa <- i8042 (interrupt, 1, 12)
[ 44.304855] i8042: [9804] d4 -> i8042 (command)
[ 44.304938] i8042: [9804] 66 -> i8042 (parameter)
[ 44.337698] i8042: [9813] d4 -> i8042 (command)
[ 44.905695] i8042: [9942] 88 -> i8042 (parameter)
[ 45.497478] i8042: [10102] d4 -> i8042 (command)
[ 46.098041] i8042: [10253] f3 -> i8042 (parameter)
[ 46.098070] i8042: [10253] fe <- i8042 (interrupt, 1, 12)
[ 46.718154] i8042: [10386] d4 -> i8042 (command)
[ 47.309915] i8042: [10386] f4 -> i8042 (parameter)
[ 47.918961] i8042: [10556] d4 -> i8042 (command)
[ 48.402624] i8042: [10556] f6 -> i8042 (parameter)

A DMI quirk to mark this platform doesn't have aux device could avoid those
commands to be sent. And the system could still using i2c interface to
communicate with the touchpad.

1. https://www.kernel.org/doc/html/v5.11/input/devices/sentelic.html#programming-sequence-for-register-reading-writing

Signed-off-by: Chia-Lin Kao (AceLan) <[email protected]>
---
drivers/input/serio/i8042.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)

diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index dbe1810e6242..3d778c9616dc 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -22,6 +22,7 @@
#include <linux/slab.h>
#include <linux/suspend.h>
#include <linux/property.h>
+#include <linux/dmi.h>

#include <asm/io.h>

@@ -174,6 +175,24 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id);
static bool (*i8042_platform_filter)(unsigned char data, unsigned char str,
struct serio *serio);

+static int __init i8042_set_noaux(const struct dmi_system_id *dmi)
+{
+ i8042_noaux = true;
+ return 1;
+}
+
+static const struct dmi_system_id i8042_quirks[] __initconst = {
+ {
+ .callback = i8042_set_noaux,
+ .ident = "Dell laptop",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Precision 5550"),
+ },
+ },
+ {},
+};
+
void i8042_lock_chip(void)
{
mutex_lock(&i8042_mutex);
@@ -1559,6 +1578,8 @@ static int __init i8042_probe(struct platform_device *dev)
i8042_dritek_enable();
#endif

+ dmi_check_system(i8042_quirks);
+
if (!i8042_noaux) {
error = i8042_setup_aux();
if (error && error != -ENODEV && error != -EBUSY)
--
2.25.1