Re: [PATCHv3 2/2] input/serio/i8042.c: Skipt selftest on ASUS laptops

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Ulrik,

On Tue, Aug 23, 2016 at 10:20:08PM +0200, ulrik.debie-os@xxxxxxxxx wrote:
> Hi Marcos,
> 
> Given the fact that there are already Asus laptops that do not have a problem
> with self test, is there no chance of regression on those that they would stop functioning with this patch ?

I really don't know. This just worked for me, and as it is a really
annoying bug (that can be seen be the large number of models affected),
I just wanted to check with more people about other models, if this
patch break anything.

> 
> Anyone with a Asus K53SV, G46VW, G750JX, TP500LN, X750JN, UX31 or UX32VD wants to give this patch a try ?

That would solve our doubts about fixing some models and breaking new
ones. I hope that someone could make a test on any of these devices.

Thanks,

> 
> Thanks,
> Kind regards
> 
> On Wed, Aug 10, 2016 at 12:25:45AM -0300, Marcos Paulo de Souza wrote:
> > Date:	Wed, 10 Aug 2016 00:25:45 -0300
> > From: Marcos Paulo de Souza <marcos.souza.org@xxxxxxxxx>
> > To: dmitry.torokhov@xxxxxxxxx, linux-input@xxxxxxxxxxxxxxx
> > Cc: Marcos Paulo de Souza <marcos.souza.org@xxxxxxxxx>
> > Subject: [PATCHv3 2/2] input/serio/i8042.c: Skipt selftest on ASUS laptops
> > X-Mailer: git-send-email 2.7.4
> > X-Mailing-List:	linux-input@xxxxxxxxxxxxxxx
> > 
> > On suspend/resume cycle, selftest is executed to reset i8042 controller. But
> > when this is done in Asus devices, posterior calls to detect/init functions
> > to elantech driver fails. Skipping selftest fixes this problem.
> > 
> > An easier step to reproduce this problem is adding i8042.reset=1 as a kernel
> > parameter. On Asus laptops, it'll make the system to start with the
> > touchpad already stuck, since psmouse_probe forcibly calls the
> > selftest function.
> > 
> > This patch was inspired by John Hiesey's change[1], but, since this problem
> > affects a lot of models of Asus (A455LD, K401LB, K501LX, V502LX, X302LA, X450LCP,
> > X455LAB, X455LDB, X455LF, V502LX), let's just disable self tests for any Asus laptop.
> > 
> > [1]: https://marc.info/?l=linux-input&m=144312209020616&w=2
> > 
> > Fixes: "ETPS/2 Elantech Touchpad dies after resume from suspend" (https://bugzilla.kernel.org/show_bug.cgi?id=107971)
> > 
> > Signed-off-by: Marcos Paulo de Souza <marcos.souza.org@xxxxxxxxx>
> > ---
> >  drivers/input/serio/i8042-x86ia64io.h | 21 +++++++++++++++++--
> >  drivers/input/serio/i8042.c           | 38 +++++++++++++++++++++++++++++------
> >  2 files changed, 51 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
> > index 68f5f4a..43008b6 100644
> > --- a/drivers/input/serio/i8042-x86ia64io.h
> > +++ b/drivers/input/serio/i8042-x86ia64io.h
> > @@ -510,6 +510,17 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
> >  	{ }
> >  };
> >  
> > +/*
> > + * On Asus laptops, just running self tests cause problems.
> > + */
> > +static const struct dmi_system_id __initconst i8042_dmi_noselftest_table[] = {
> > +	{
> > +		.matches = {
> > +			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
> > +		},
> > +	},
> > +	{ }
> > +};
> >  static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
> >  	{
> >  		/* MSI Wind U-100 */
> > @@ -1076,8 +1087,14 @@ static int __init i8042_platform_init(void)
> >  #endif
> >  
> >  #ifdef CONFIG_X86
> > -	if (dmi_check_system(i8042_dmi_reset_table))
> > -		i8042_reset = true;
> > +	/* Honor module parameter when value is not default */
> > +	if (i8042_reset == I8042_RESET_ON_RESUME) {
> > +		if (dmi_check_system(i8042_dmi_reset_table))
> > +			i8042_reset = I8042_RESET_ALWAYS;
> > +
> > +		if (dmi_check_system(i8042_dmi_noselftest_table))
> > +			i8042_reset = I8042_RESET_NEVER;
> > +	}
> >  
> >  	if (dmi_check_system(i8042_dmi_noloop_table))
> >  		i8042_noloop = true;
> > diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
> > index b4d3408..0dfe754 100644
> > --- a/drivers/input/serio/i8042.c
> > +++ b/drivers/input/serio/i8042.c
> > @@ -48,9 +48,32 @@ static bool i8042_unlock;
> >  module_param_named(unlock, i8042_unlock, bool, 0);
> >  MODULE_PARM_DESC(unlock, "Ignore keyboard lock.");
> >  
> > -static bool i8042_reset;
> > -module_param_named(reset, i8042_reset, bool, 0);
> > -MODULE_PARM_DESC(reset, "Reset controller during init and cleanup.");
> > +enum i8042_controller_reset_mode {
> > +	I8042_RESET_NEVER,
> > +	I8042_RESET_ALWAYS,
> > +	I8042_RESET_ON_RESUME
> > +};
> > +static unsigned int i8042_reset = I8042_RESET_ON_RESUME;
> > +static int i8042_set_reset(const char *val, const struct kernel_param *kp)
> > +{
> > +	unsigned int ret = I8042_RESET_ON_RESUME;
> > +        if (!val || !strncmp(val, "1", 1) || !strncasecmp(val, "y", 1))
> > +		ret = I8042_RESET_ALWAYS;
> > +	else if (!strncmp(val, "0", 1) || !strncasecmp(val, "n", 1))
> > +		ret = I8042_RESET_NEVER;
> > +
> > +        *((unsigned int *)kp->arg) = ret;
> > +
> > +        return 0;
> > +}
> > +
> > +static const struct kernel_param_ops param_ops_reset_param = {
> > +	.flags = KERNEL_PARAM_OPS_FL_NOARG,
> > +	.set = i8042_set_reset,
> > +};
> > +#define param_check_reset_param(name, p) __param_check(name, p, unsigned int)
> > +module_param_named(reset, i8042_reset, reset_param, 0);
> > +MODULE_PARM_DESC(reset, "Reset controller on resume, cleanup or both");
> >  
> >  static bool i8042_direct;
> >  module_param_named(direct, i8042_direct, bool, 0);
> > @@ -890,6 +913,9 @@ static int i8042_controller_selftest(void)
> >  	unsigned char param;
> >  	int i = 0;
> >  
> > +	if (i8042_reset == I8042_RESET_NEVER)
> > +		return 0;
> > +
> >  	/*
> >  	 * We try this 5 times; on some really fragile systems this does not
> >  	 * take the first time...
> > @@ -1044,7 +1070,7 @@ static void i8042_controller_reset(bool force_reset)
> >   * Reset the controller if requested.
> >   */
> >  
> > -	if (i8042_reset || force_reset)
> > +	if (i8042_reset != I8042_RESET_NEVER || force_reset)
> >  		i8042_controller_selftest();
> >  
> >  /*
> > @@ -1118,7 +1144,7 @@ static int i8042_controller_resume(bool force_reset)
> >  	if (error)
> >  		return error;
> >  
> > -	if (i8042_reset || force_reset) {
> > +	if (i8042_reset != I8042_RESET_NEVER || force_reset) {
> >  		error = i8042_controller_selftest();
> >  		if (error)
> >  			return error;
> > @@ -1481,7 +1507,7 @@ static int __init i8042_probe(struct platform_device *dev)
> >  
> >  	i8042_platform_device = dev;
> >  
> > -	if (i8042_reset) {
> > +	if (i8042_reset == I8042_RESET_ALWAYS) {
> >  		error = i8042_controller_selftest();
> >  		if (error)
> >  			return error;
> > -- 
> > 2.7.4
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-input" in
> > the body of a message to majordomo@xxxxxxxxxxxxxxx
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux