All of lore.kernel.org
 help / color / mirror / Atom feed
From: thatslyude@gmail.com
To: Dmitry Torokhov <dmitry.torokhov@gmail.com>,
	Benjamin Tissoires <benjamin.tissoires@redhat.com>,
	Damjan Georgievski <gdamjan@gmail.com>
Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org,
	Andrew Duggan <aduggan@synaptics.com>,
	stable@vger.kernel.org
Subject: Re: [PATCH 2/3] Input: synaptics_rmi4 - unmask F03 interrupts when port is opened
Date: Fri, 19 Jan 2018 13:08:47 -0500	[thread overview]
Message-ID: <1516385327.2814.4.camel@gmail.com> (raw)
In-Reply-To: <20180119004955.247190-3-dmitry.torokhov@gmail.com>

Looks good to me.

Reviewed-by: Lyude Paul <lyude@redhat.com>

On Thu, 2018-01-18 at 16:49 -0800, Dmitry Torokhov wrote:
> Currently we register the pass-through serio port when we probe the F03 RMI
> function, and then, in sensor configure phase, we unmask interrupts.
> Unfortunately this is too late, as other drivers are free probe devices
> attached to the serio port as soon as it is probed. Because interrupts are
> masked, the IO times out, which may result in not being able to detect
> trackpoints on the pass-through port.
> 
> To fix the issue we implement open() and close() methods for the
> pass-through serio port and unmask interrupts from there. We also move
> creation of the pass-through port form probe to configure stage, as RMI
> driver does not enable transport interrupt until all functions are probed
> (we should change this, but this is a separate topic).
> 
> We also try to clear the pending data before unmasking interrupts, because
> some devices like to spam the system with multiple 0xaa 0x00 announcements,
> which may interfere with us trying to query ID of the device.
> 
> Fixes: c5e8848fc98e ("Input: synaptics-rmi4 - add support for F03")
> Cc: stable@vger.kernel.org
> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> ---
>  drivers/input/rmi4/rmi_f03.c | 64 +++++++++++++++++++++++++++++++++++++--
> -----
>  1 file changed, 54 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/input/rmi4/rmi_f03.c b/drivers/input/rmi4/rmi_f03.c
> index ad71a5e768dc4..7ccbb370a9a81 100644
> --- a/drivers/input/rmi4/rmi_f03.c
> +++ b/drivers/input/rmi4/rmi_f03.c
> @@ -32,6 +32,7 @@ struct f03_data {
>  	struct rmi_function *fn;
>  
>  	struct serio *serio;
> +	bool serio_registered;
>  
>  	unsigned int overwrite_buttons;
>  
> @@ -138,6 +139,37 @@ static int rmi_f03_initialize(struct f03_data *f03)
>  	return 0;
>  }
>  
> +static int rmi_f03_pt_open(struct serio *serio)
> +{
> +	struct f03_data *f03 = serio->port_data;
> +	struct rmi_function *fn = f03->fn;
> +	const u8 ob_len = f03->rx_queue_length * RMI_F03_OB_SIZE;
> +	const u16 data_addr = fn->fd.data_base_addr + RMI_F03_OB_OFFSET;
> +	u8 obs[RMI_F03_QUEUE_LENGTH * RMI_F03_OB_SIZE];
> +	int error;
> +
> +	/*
> +	 * Consume any pending data. Some devices like to spam with
> +	 * 0xaa 0x00 announcements which may confuse us as we try to
> +	 * probe the device.
> +	 */
> +	error = rmi_read_block(fn->rmi_dev, data_addr, &obs, ob_len);
> +	if (!error)
> +		rmi_dbg(RMI_DEBUG_FN, &fn->dev,
> +			"%s: Consumed %*ph (%d) from PS2 guest\n",
> +			__func__, ob_len, obs, ob_len);
> +
> +	return fn->rmi_dev->driver->set_irq_bits(fn->rmi_dev, fn-
> >irq_mask);
> +}
> +
> +static void rmi_f03_pt_close(struct serio *serio)
> +{
> +	struct f03_data *f03 = serio->port_data;
> +	struct rmi_function *fn = f03->fn;
> +
> +	fn->rmi_dev->driver->clear_irq_bits(fn->rmi_dev, fn->irq_mask);
> +}
> +
>  static int rmi_f03_register_pt(struct f03_data *f03)
>  {
>  	struct serio *serio;
> @@ -148,6 +180,8 @@ static int rmi_f03_register_pt(struct f03_data *f03)
>  
>  	serio->id.type = SERIO_PS_PSTHRU;
>  	serio->write = rmi_f03_pt_write;
> +	serio->open = rmi_f03_pt_open;
> +	serio->close = rmi_f03_pt_close;
>  	serio->port_data = f03;
>  
>  	strlcpy(serio->name, "Synaptics RMI4 PS/2 pass-through",
> @@ -184,17 +218,27 @@ static int rmi_f03_probe(struct rmi_function *fn)
>  			 f03->device_count);
>  
>  	dev_set_drvdata(dev, f03);
> -
> -	error = rmi_f03_register_pt(f03);
> -	if (error)
> -		return error;
> -
>  	return 0;
>  }
>  
>  static int rmi_f03_config(struct rmi_function *fn)
>  {
> -	fn->rmi_dev->driver->set_irq_bits(fn->rmi_dev, fn->irq_mask);
> +	struct f03_data *f03 = dev_get_drvdata(&fn->dev);
> +	int error;
> +
> +	if (!f03->serio_registered) {
> +		error = rmi_f03_register_pt(f03);
> +		if (error)
> +			return error;
> +
> +		f03->serio_registered = true;
> +	} else {
> +		/*
> +		 * We must be re-configuring the sensor, just enable
> +		 * interrupts for this function.
> +		 */
> +		fn->rmi_dev->driver->set_irq_bits(fn->rmi_dev, fn-
> >irq_mask);
> +	}
>  
>  	return 0;
>  }
> @@ -204,7 +248,7 @@ static int rmi_f03_attention(struct rmi_function *fn,
> unsigned long *irq_bits)
>  	struct rmi_device *rmi_dev = fn->rmi_dev;
>  	struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
>  	struct f03_data *f03 = dev_get_drvdata(&fn->dev);
> -	u16 data_addr = fn->fd.data_base_addr;
> +	const u16 data_addr = fn->fd.data_base_addr + RMI_F03_OB_OFFSET;
>  	const u8 ob_len = f03->rx_queue_length * RMI_F03_OB_SIZE;
>  	u8 obs[RMI_F03_QUEUE_LENGTH * RMI_F03_OB_SIZE];
>  	u8 ob_status;
> @@ -226,8 +270,7 @@ static int rmi_f03_attention(struct rmi_function *fn,
> unsigned long *irq_bits)
>  		drvdata->attn_data.size -= ob_len;
>  	} else {
>  		/* Grab all of the data registers, and check them for data
> */
> -		error = rmi_read_block(fn->rmi_dev, data_addr +
> RMI_F03_OB_OFFSET,
> -				       &obs, ob_len);
> +		error = rmi_read_block(fn->rmi_dev, data_addr, &obs,
> ob_len);
>  		if (error) {
>  			dev_err(&fn->dev,
>  				"%s: Failed to read F03 output buffers:
> %d\n",
> @@ -266,7 +309,8 @@ static void rmi_f03_remove(struct rmi_function *fn)
>  {
>  	struct f03_data *f03 = dev_get_drvdata(&fn->dev);
>  
> -	serio_unregister_port(f03->serio);
> +	if (f03->serio_registered)
> +		serio_unregister_port(f03->serio);
>  }
>  
>  struct rmi_function_handler rmi_f03_handler = {

  reply	other threads:[~2018-01-19 18:08 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-19  0:49 [PATCH 0/3] RMI4: improve trackpoint detection Dmitry Torokhov
2018-01-19  0:49 ` [PATCH 1/3] Input: synaptics_rmi4 - do not delete interrupt memory too early Dmitry Torokhov
2018-01-19  1:05   ` thatslyude
2018-01-19  0:49 ` [PATCH 2/3] Input: synaptics_rmi4 - unmask F03 interrupts when port is opened Dmitry Torokhov
2018-01-19 18:08   ` thatslyude [this message]
2018-01-19  0:49 ` [PATCH 3/3] Input: synaptics-rmi4 - log when we create a guest serio port Dmitry Torokhov
2018-01-19 18:10   ` thatslyude

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=1516385327.2814.4.camel@gmail.com \
    --to=thatslyude@gmail.com \
    --cc=aduggan@synaptics.com \
    --cc=benjamin.tissoires@redhat.com \
    --cc=dmitry.torokhov@gmail.com \
    --cc=gdamjan@gmail.com \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@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.