Linux Input/HID development
 help / color / mirror / Atom feed
From: Friedrich Vock <friedrich.vock@gmx.de>
To: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: linux-input@vger.kernel.org,
	Mario Limonciello <mario.limonciello@amd.com>
Subject: Re: [PATCH] Input: i8042 - Add quirk for polling the KBD port
Date: Sat, 22 Jul 2023 17:35:43 +0200	[thread overview]
Message-ID: <a8e101fd-d221-7f56-77fd-d4656bc909f0@gmx.de> (raw)
In-Reply-To: <ZLsYUlSMIK0Gtr21@google.com>

Hi Dmitry,

On 22.07.23 01:44, Dmitry Torokhov wrote:
> Hi Friedrich,
>
> On Tue, May 30, 2023 at 05:36:44PM +0200, Friedrich Vock wrote:
>> It seems like there are some devices in the ASUS TUF A16 laptops that
>> just don't send any keyboard interrupts until you read from the KBD port.
> I am sorry, but continuously polling keyboard port will absolutely wreck
> battery life on these devices, so this can not be a real solution.
>
> I wonder if this is yet another example of incorrect IRQ 1 polarity
> override on devices with AMD chipsets (CC-ing Mario).
I'm pretty sure that's the case. I only found Mario's patch reverting
these overrides sometime after sending out this one, but that patch
indeed fixes this problem as well. It's contained in 6.5-rc2, so this
patch is not necessary anymore. Sorry for not sending a "please
disregard" earlier.

Thanks,
Friedrich
>
>> Signed-off-by: Friedrich Vock <friedrich.vock@gmx.de>
>> ---
>>   drivers/input/serio/i8042-acpipnpio.h | 30 +++++++++++++++--
>>   drivers/input/serio/i8042.c           | 47 ++++++++++++++++++++++-----
>>   drivers/input/serio/i8042.h           |  2 +-
>>   3 files changed, 67 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/input/serio/i8042-acpipnpio.h b/drivers/input/serio/i8042-acpipnpio.h
>> index 028e45bd050b..be2e72aaa658 100644
>> --- a/drivers/input/serio/i8042-acpipnpio.h
>> +++ b/drivers/input/serio/i8042-acpipnpio.h
>> @@ -83,6 +83,7 @@ static inline void i8042_write_command(int val)
>>   #define SERIO_QUIRK_KBDRESET		BIT(12)
>>   #define SERIO_QUIRK_DRITEK		BIT(13)
>>   #define SERIO_QUIRK_NOPNP		BIT(14)
>> +#define SERIO_QUIRK_POLL_KBD            BIT(15)
>>
>>   /* Quirk table for different mainboards. Options similar or identical to i8042
>>    * module parameters.
>> @@ -99,6 +100,26 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
>>   		},
>>   		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
>>   	},
>> +	/* Some laptops seem to not trigger any keyboard interrupts at all,
>> +	 * even when there is data available. On these devices, manually
>> +	 * polling the keyboard port is required.
>> +	 */
>> +	{
>> +		/* ASUS TUF Gaming A16 with Ryzen 7 7735HS */
>> +		.matches = {
>> +			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
>> +			DMI_MATCH(DMI_PRODUCT_NAME, "FA617NS"),
>> +		},
>> +		.driver_data = (void *)(SERIO_QUIRK_POLL_KBD)
>> +	},
>> +	{
>> +		/* ASUS TUF Gaming A16 with Ryzen 9 7940HS */
>> +		.matches = {
>> +			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
>> +			DMI_MATCH(DMI_PRODUCT_NAME, "FA617XS"),
>> +		},
>> +		.driver_data = (void *)(SERIO_QUIRK_POLL_KBD)
>> +	},
>>   	{
>>   		.matches = {
>>   			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
>> @@ -1634,6 +1655,8 @@ static void __init i8042_check_quirks(void)
>>   	if (quirks & SERIO_QUIRK_NOPNP)
>>   		i8042_nopnp = true;
>>   #endif
>> +	if (quirks & SERIO_QUIRK_POLL_KBD)
>> +		i8042_poll_kbd = true;
>>   }
>>   #else
>>   static inline void i8042_check_quirks(void) {}
>> @@ -1667,7 +1690,7 @@ static int __init i8042_platform_init(void)
>>
>>   	i8042_check_quirks();
>>
>> -	pr_debug("Active quirks (empty means none):%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
>> +	pr_debug("Active quirks (empty means none):%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
>>   		i8042_nokbd ? " nokbd" : "",
>>   		i8042_noaux ? " noaux" : "",
>>   		i8042_nomux ? " nomux" : "",
>> @@ -1687,10 +1710,11 @@ static int __init i8042_platform_init(void)
>>   		"",
>>   #endif
>>   #ifdef CONFIG_PNP
>> -		i8042_nopnp ? " nopnp" : "");
>> +		i8042_nopnp ? " nopnp" : "",
>>   #else
>> -		"");
>> +		"",
>>   #endif
>> +		i8042_poll_kbd ? "poll_kbd" : "");
>>
>>   	retval = i8042_pnp_init();
>>   	if (retval)
>> diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
>> index 6dac7c1853a5..7212263d3a41 100644
>> --- a/drivers/input/serio/i8042.c
>> +++ b/drivers/input/serio/i8042.c
>> @@ -115,6 +115,10 @@ module_param_named(nopnp, i8042_nopnp, bool, 0);
>>   MODULE_PARM_DESC(nopnp, "Do not use PNP to detect controller settings");
>>   #endif
>>
>> +static bool i8042_poll_kbd;
>> +module_param_named(poll_kbd, i8042_poll_kbd, bool, 0);
>> +MODULE_PARM_DESC(poll_kbd, "Continuously poll the KBD port instead of relying on interrupts");
>> +
>>   #define DEBUG
>>   #ifdef DEBUG
>>   static bool i8042_debug;
>> @@ -178,6 +182,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);
>>
>> +#define POLL_TIME 1
>> +static void i8042_poll_func(struct timer_list *timer)
>> +{
>> +	unsigned char status;
>> +	unsigned long flags;
>> +
>> +	do {
>> +		spin_lock_irqsave(&i8042_lock, flags);
>> +		status = i8042_read_status();
>> +		spin_unlock_irqrestore(&i8042_lock, flags);
>> +		if (status & I8042_STR_OBF)
>> +			i8042_interrupt(0, NULL);
>> +	} while (status & I8042_STR_OBF);
>> +	mod_timer(timer, jiffies + msecs_to_jiffies(POLL_TIME));
>> +}
>> +
>> +DEFINE_TIMER(poll_timer, i8042_poll_func);
>> +
>>   void i8042_lock_chip(void)
>>   {
>>   	mutex_lock(&i8042_mutex);
>> @@ -1437,13 +1459,15 @@ static void i8042_unregister_ports(void)
>>   	}
>>   }
>>
>> +
>>   static void i8042_free_irqs(void)
>>   {
>>   	if (i8042_aux_irq_registered)
>>   		free_irq(I8042_AUX_IRQ, i8042_platform_device);
>> -	if (i8042_kbd_irq_registered)
>> +	if (i8042_poll_kbd)
>> +		del_timer(&poll_timer);
>> +	else if (i8042_kbd_irq_registered)
>>   		free_irq(I8042_KBD_IRQ, i8042_platform_device);
>> -
>>   	i8042_aux_irq_registered = i8042_kbd_irq_registered = false;
>>   }
>>
>> @@ -1497,10 +1521,14 @@ static int i8042_setup_kbd(void)
>>   	if (error)
>>   		return error;
>>
>> -	error = request_irq(I8042_KBD_IRQ, i8042_interrupt, IRQF_SHARED,
>> -			    "i8042", i8042_platform_device);
>> -	if (error)
>> -		goto err_free_port;
>> +	if (i8042_poll_kbd)
>> +		mod_timer(&poll_timer, msecs_to_jiffies(POLL_TIME));
>> +	else {
>> +		error = request_irq(I8042_KBD_IRQ, i8042_interrupt, IRQF_SHARED,
>> +				    "i8042", i8042_platform_device);
>> +		if (error)
>> +			goto err_free_port;
>> +	}
>>
>>   	error = i8042_enable_kbd_port();
>>   	if (error)
>> @@ -1510,8 +1538,11 @@ static int i8042_setup_kbd(void)
>>   	return 0;
>>
>>    err_free_irq:
>> -	free_irq(I8042_KBD_IRQ, i8042_platform_device);
>> - err_free_port:
>> +	if (i8042_poll_kbd)
>> +		del_timer(&poll_timer);
>> +	else
>> +		free_irq(I8042_KBD_IRQ, i8042_platform_device);
>> +err_free_port:
>>   	i8042_free_kbd_port();
>>   	return error;
>>   }
>> --
>> 2.40.1
>>
> Thanks.
>

  reply	other threads:[~2023-07-22 15:35 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-30 15:36 [PATCH] Input: i8042 - Add quirk for polling the KBD port Friedrich Vock
2023-07-21 23:44 ` Dmitry Torokhov
2023-07-22 15:35   ` Friedrich Vock [this message]
2023-07-23 15:45     ` Mario Limonciello

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=a8e101fd-d221-7f56-77fd-d4656bc909f0@gmx.de \
    --to=friedrich.vock@gmx.de \
    --cc=dmitry.torokhov@gmail.com \
    --cc=linux-input@vger.kernel.org \
    --cc=mario.limonciello@amd.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox