All of lore.kernel.org
 help / color / mirror / Atom feed
From: Maxim Mikityanskiy <maxtram95@gmail.com>
To: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: "Hans de Goede" <hdegoede@redhat.com>,
	"Ike Panhc" <ike.pan@canonical.com>,
	"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
	"Andy Shevchenko" <andy@kernel.org>,
	platform-driver-x86@vger.kernel.org, linux-input@vger.kernel.org,
	"Jonathan Denose" <jdenose@chromium.org>,
	stable@vger.kernel.org
Subject: Re: [PATCH] platform/x86: ideapad-laptop: Stop calling i8042_command()
Date: Sun, 22 Sep 2024 11:35:14 +0300	[thread overview]
Message-ID: <Zu_WwjD15VgiR2j9@mail.gmail.com> (raw)
In-Reply-To: <ZteiClP9jabjHFkG@google.com>

On Tue, 03 Sep 2024 at 16:55:54 -0700, Dmitry Torokhov wrote:
> On Tue, Aug 20, 2024 at 10:28:24PM -0700, Dmitry Torokhov wrote:
> > On Wed, Aug 21, 2024 at 12:40:34AM +0300, Maxim Mikityanskiy wrote:
> > > On Tue, 20 Aug 2024 at 13:46:53 +0300, Maxim Mikityanskiy wrote:
> > > > On Sun, 18 Aug 2024 at 13:30:37 -0700, Dmitry Torokhov wrote:
> > > > > 
> > > > > Maybe something like below can work?
> > > > 
> > > > Great patch, thank you, I'll test it and report the results. See some
> > > > minor comments below.
> > > > 
> > > > > 
> > > > > 
> > > > > platform/x86: ideapad-laptop: do not poke keyboard controller
> > > > > 
> > > > > From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> > > > > 
> > > > > On Ideapad Z570 the driver tries to disable and reenable data coming
> > > > > from the touchpad by poking directly into 8042 keyboard controller.
> > > > > This may coincide with the controller resuming and leads to spews in
> > > > > dmesg and potentially other instabilities.
> > > > > 
> > > > > Instead of using i8042_command() to control the touchpad state create a
> > > > > input handler that serves as a filter and drop events coming from the
> > > > > touchpad when it is supposed to be off.
> > > > > 
> > > > > Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> > > > > ---
> > > > >  drivers/platform/x86/ideapad-laptop.c |  171 ++++++++++++++++++++++++++++++++-
> > > > >  1 file changed, 168 insertions(+), 3 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
> > > > > index fcf13d88fd6e..2f40feefd5e3 100644
> > > > > --- a/drivers/platform/x86/ideapad-laptop.c
> > > > > +++ b/drivers/platform/x86/ideapad-laptop.c
> > > > > @@ -17,7 +17,6 @@
> > > > >  #include <linux/device.h>
> > > > >  #include <linux/dmi.h>
> > > > >  #include <linux/fb.h>
> > > > > -#include <linux/i8042.h>
> > > > >  #include <linux/init.h>
> > > > >  #include <linux/input.h>
> > > > >  #include <linux/input/sparse-keymap.h>
> > > > > @@ -157,6 +156,13 @@ struct ideapad_private {
> > > > >  		struct led_classdev led;
> > > > >  		unsigned int last_brightness;
> > > > >  	} fn_lock;
> > > > > +	struct {
> > > > > +		bool initialized;
> > > > > +		bool active;
> > > > > +		struct input_handler handler;
> > > > > +		struct input_dev *tp_dev;
> > > > > +		spinlock_t lock;
> > > > > +	} tp_switch;
> > > > >  };
> > > > >  
> > > > >  static bool no_bt_rfkill;
> > > > > @@ -1236,6 +1242,158 @@ static void ideapad_check_special_buttons(struct ideapad_private *priv)
> > > > >  	}
> > > > >  }
> > > > >  
> > > > > +struct ideapad_tpswitch_handle {
> > > > > +	struct input_handle handle;
> > > > > +	struct ideapad_private *priv;
> > > > > +};
> > > > > +
> > > > > +#define to_tpswitch_handle(h) \
> > > > > +	container_of(h, struct ideapad_tpswitch_handle, handle);
> > > > > +
> > > > > +static int ideapad_tpswitch_connect(struct input_handler *handler,
> > > > > +				    struct input_dev *dev,
> > > > > +				    const struct input_device_id *id)
> > > > > +{
> > > > > +	struct ideapad_private *priv =
> > > > > +		container_of(handler, struct ideapad_private, tp_switch.handler);
> > > > > +	struct ideapad_tpswitch_handle *h;
> > > > > +	int error;
> > > > > +
> > > > > +	h = kzalloc(sizeof(*h), GFP_KERNEL);
> > > > > +	if (!h)
> > > > > +		return -ENOMEM;
> > > > > +
> > > > > +	h->priv = priv;
> > > > > +	h->handle.dev = dev;
> > > > > +	h->handle.handler = handler;
> > > > > +	h->handle.name = "ideapad-tpswitch";
> > > > > +
> > > > > +	error = input_register_handle(&h->handle);
> > > > > +	if (error)
> > > > > +		goto err_free_handle;
> > > > > +
> > > > > +	/*
> > > > > +	 * FIXME: ideally we do not want to open the input device here
> > > > > +	 * if there are no other users. We need a notion of "observer"
> > > > > +	 * handlers in the input core.
> > > > > +	 */
> > > > > +	error = input_open_device(&h->handle);
> > > > > +	if (error)
> > > > > +		goto err_unregister_handle;
> > > > > +
> > > > > +	scoped_guard(spinlock_irq, &priv->tp_switch.lock)
> > > > > +		priv->tp_switch.tp_dev = dev;
> > > > > +
> > > > > +	return 0;
> > > > > +
> > > > > + err_unregister_handle:
> > > > > +	input_unregister_handle(&h->handle);
> > > > > +err_free_handle:
> > > > > +	kfree(h);
> > > > > +	return error;
> > > > > +}
> > > > > +
> > > > > +static void ideapad_tpswitch_disconnect(struct input_handle *handle)
> > > > > +{
> > > > > +	struct ideapad_tpswitch_handle *h = to_tpswitch_handle(handle);
> > > > > +	struct ideapad_private *priv = h->priv;
> > > > > +
> > > > > +	scoped_guard(spinlock_irq, &priv->tp_switch.lock)
> > > > 
> > > > Nice syntax, I didn't know about it before.
> > > > 
> > > > > +		priv->tp_switch.tp_dev = NULL;
> > > > > +
> > > > > +	input_close_device(handle);
> > > > > +	input_unregister_handle(handle);
> > > > > +	kfree(h);
> > > > > +}
> > > > > +
> > > > > +static bool ideapad_tpswitch_filter(struct input_handle *handle,
> > > > > +				    unsigned int type, unsigned int code,
> > > > > +				    int value)
> > > > > +{
> > > > > +	struct ideapad_tpswitch_handle *h = to_tpswitch_handle(handle);
> > > > > +	struct ideapad_private *priv = h->priv;
> > > > > +
> > > > > +	if (!priv->tp_switch.active)
> > > > 
> > > > This check seems inverted. ideapad_tpswitch_toggle assigns true when the
> > > > touchpad is enabled.
> > > 
> > > I tested the patch on Z570 (with this check inverted), and it seems to
> > > work great.
> > > 
> > > Also tested what happens on resume from suspend: the laptop reenables
> > > the touchpad (the LED turns off on suspend and blinks briefly on
> > > resume), and the driver handles it properly.
> > 
> > Great, thank you! Give me a couple of days and I think I will implement
> > observer/passive handler support and we can figure out how to merge
> > this...
> 
> OK, so if you could try the patch below that would be great.
> Don't forget to set ".passive_observer = 1" in the ideapad handler.

Sorry for the slow response. I tested the patches, setting
passive_observer in ideapad_tpswitch_init and inverting the check in
ideapad_tpswitch_filter - all seems to work perfectly!

> Thanks!
> 
> -- 
> Dmitry
> 
> 
> Input: introduce notion of passive observers for input handlers
> 
> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> ---
>  drivers/input/input.c |    7 +++++++
>  include/linux/input.h |    5 +++++
>  2 files changed, 12 insertions(+)
> 
> diff --git a/drivers/input/input.c b/drivers/input/input.c
> index 54c57b267b25..60a9445d78d5 100644
> --- a/drivers/input/input.c
> +++ b/drivers/input/input.c
> @@ -605,6 +605,9 @@ int input_open_device(struct input_handle *handle)
>  
>  	handle->open++;
>  
> +	if (handle->handler->passive_observer)
> +		goto out;
> +
>  	if (dev->users++ || dev->inhibited) {
>  		/*
>  		 * Device is already opened and/or inhibited,
> @@ -668,6 +671,9 @@ void input_close_device(struct input_handle *handle)
>  
>  	__input_release_device(handle);
>  
> +	if (handle->handler->passive_observer)
> +		goto out;
> +
>  	if (!--dev->users && !dev->inhibited) {
>  		if (dev->poller)
>  			input_dev_poller_stop(dev->poller);
> @@ -684,6 +690,7 @@ void input_close_device(struct input_handle *handle)
>  		synchronize_rcu();
>  	}
>  
> +out:
>  	mutex_unlock(&dev->mutex);
>  }
>  EXPORT_SYMBOL(input_close_device);
> diff --git a/include/linux/input.h b/include/linux/input.h
> index 89a0be6ee0e2..6437c35f0796 100644
> --- a/include/linux/input.h
> +++ b/include/linux/input.h
> @@ -286,6 +286,10 @@ struct input_handle;
>   * @start: starts handler for given handle. This function is called by
>   *	input core right after connect() method and also when a process
>   *	that "grabbed" a device releases it
> + * @passive_observer: set to %true by drivers only interested in observing
> + *	data stream from devices if there are other users present. Such
> + *	drivers will not result in starting underlying hardware device
> + *	when input_open_device() is called for their handles
>   * @legacy_minors: set to %true by drivers using legacy minor ranges
>   * @minor: beginning of range of 32 legacy minors for devices this driver
>   *	can provide
> @@ -321,6 +325,7 @@ struct input_handler {
>  	void (*disconnect)(struct input_handle *handle);
>  	void (*start)(struct input_handle *handle);
>  
> +	bool passive_observer;
>  	bool legacy_minors;
>  	int minor;
>  	const char *name;

      reply	other threads:[~2024-09-22  8:35 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-08-05 14:16 [PATCH] platform/x86: ideapad-laptop: Stop calling i8042_command() Hans de Goede
2024-08-05 14:30 ` Dmitry Torokhov
2024-08-05 15:30 ` Maxim Mikityanskiy
2024-08-05 15:45   ` Hans de Goede
2024-08-05 17:00     ` Dmitry Torokhov
2024-08-05 18:40       ` Hans de Goede
2024-08-12 14:37     ` Maxim Mikityanskiy
2024-08-12 14:41       ` Hans de Goede
2024-08-12 17:24         ` Dmitry Torokhov
2024-08-12 18:18           ` Hans de Goede
2024-08-12 19:26             ` Dmitry Torokhov
2024-08-18 20:30               ` Dmitry Torokhov
2024-08-20 10:46                 ` Maxim Mikityanskiy
2024-08-20 21:40                   ` Maxim Mikityanskiy
2024-08-21  5:28                     ` Dmitry Torokhov
2024-09-03 23:55                       ` Dmitry Torokhov
2024-09-22  8:35                         ` Maxim Mikityanskiy [this message]

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=Zu_WwjD15VgiR2j9@mail.gmail.com \
    --to=maxtram95@gmail.com \
    --cc=andy@kernel.org \
    --cc=dmitry.torokhov@gmail.com \
    --cc=hdegoede@redhat.com \
    --cc=ike.pan@canonical.com \
    --cc=ilpo.jarvinen@linux.intel.com \
    --cc=jdenose@chromium.org \
    --cc=linux-input@vger.kernel.org \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.