Re: [PATCH] i2c: Prevent runtime suspend of adapter when Host Notify is required

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

 



On Tue, Apr 30, 2019 at 4:23 PM Jarkko Nikula
<jarkko.nikula@xxxxxxxxxxxxxxx> wrote:
>
> Multiple users have reported their Synaptics touchpad has stopped
> working between v4.20.1 and v4.20.2 when using SMBus interface.
>
> The culprit for this appeared to be commit c5eb1190074c ("PCI / PM: Allow
> runtime PM without callback functions") that fixed the runtime PM for
> i2c-i801 SMBus adapter. Those Synaptics touchpad are using i2c-i801
> for SMBus communication and testing showed they are able to get back
> working by preventing the runtime suspend of adapter.
>
> Normally when i2c-i801 SMBus adapter transmits with the client it resumes
> before operation and autosuspends after.
>
> However, if client requires SMBus Host Notify protocol, what those
> Synaptics touchpads do, then the host adapter must not go to runtime
> suspend since then it cannot process incoming SMBus Host Notify commands
> the client may send.
>
> Fix this by keeping I2C/SMBus adapter active in case client requires
> Host Notify.
>
> Reported-by: Keijo Vaara <ferdasyn@xxxxxxxxxxxxxx>
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=203297
> Fixes: c5eb1190074c ("PCI / PM: Allow runtime PM without callback functions")
> Cc: stable@xxxxxxxxxxxxxxx # v4.20+
> Signed-off-by: Jarkko Nikula <jarkko.nikula@xxxxxxxxxxxxxxx>

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx>

Or please let me know if you want me to take this.

> ---
> Keijo: could you test this does it fix the issue you reported? This is
> practically the same diff I sent earlier what you probably haven't tested yet.
> I wanted to send a commitable fix in case it works since I'll be out of
> office in a few coming days.
> ---
>  drivers/i2c/i2c-core-base.c | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
> index 38af18645133..8149c9e32b69 100644
> --- a/drivers/i2c/i2c-core-base.c
> +++ b/drivers/i2c/i2c-core-base.c
> @@ -327,6 +327,8 @@ static int i2c_device_probe(struct device *dev)
>
>                 if (client->flags & I2C_CLIENT_HOST_NOTIFY) {
>                         dev_dbg(dev, "Using Host Notify IRQ\n");
> +                       /* Keep adapter active when Host Notify is required */
> +                       pm_runtime_get_sync(&client->adapter->dev);
>                         irq = i2c_smbus_host_notify_to_irq(client);
>                 } else if (dev->of_node) {
>                         irq = of_irq_get_byname(dev->of_node, "irq");
> @@ -431,6 +433,8 @@ static int i2c_device_remove(struct device *dev)
>         device_init_wakeup(&client->dev, false);
>
>         client->irq = client->init_irq;
> +       if (client->flags & I2C_CLIENT_HOST_NOTIFY)
> +               pm_runtime_put(&client->adapter->dev);
>
>         return status;
>  }
> --
> 2.20.1
>



[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux