| From 04b7762e37c95d9b965d16bb0e18dbd1fa2e2861 Mon Sep 17 00:00:00 2001 |
| From: Hans de Goede <hdegoede@redhat.com> |
| Date: Mon, 28 Feb 2022 23:39:50 -0800 |
| Subject: Input: elan_i2c - fix regulator enable count imbalance after suspend/resume |
| |
| From: Hans de Goede <hdegoede@redhat.com> |
| |
| commit 04b7762e37c95d9b965d16bb0e18dbd1fa2e2861 upstream. |
| |
| Before these changes elan_suspend() would only disable the regulator |
| when device_may_wakeup() returns false; whereas elan_resume() would |
| unconditionally enable it, leading to an enable count imbalance when |
| device_may_wakeup() returns true. |
| |
| This triggers the "WARN_ON(regulator->enable_count)" in regulator_put() |
| when the elan_i2c driver gets unbound, this happens e.g. with the |
| hot-plugable dock with Elan I2C touchpad for the Asus TF103C 2-in-1. |
| |
| Fix this by making the regulator_enable() call also be conditional |
| on device_may_wakeup() returning false. |
| |
| Signed-off-by: Hans de Goede <hdegoede@redhat.com> |
| Link: https://lore.kernel.org/r/20220131135436.29638-2-hdegoede@redhat.com |
| Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/input/mouse/elan_i2c_core.c | 14 +++++++------- |
| 1 file changed, 7 insertions(+), 7 deletions(-) |
| |
| --- a/drivers/input/mouse/elan_i2c_core.c |
| +++ b/drivers/input/mouse/elan_i2c_core.c |
| @@ -1305,17 +1305,17 @@ static int __maybe_unused elan_resume(st |
| struct elan_tp_data *data = i2c_get_clientdata(client); |
| int error; |
| |
| - if (device_may_wakeup(dev) && data->irq_wake) { |
| + if (!device_may_wakeup(dev)) { |
| + error = regulator_enable(data->vcc); |
| + if (error) { |
| + dev_err(dev, "error %d enabling regulator\n", error); |
| + goto err; |
| + } |
| + } else if (data->irq_wake) { |
| disable_irq_wake(client->irq); |
| data->irq_wake = false; |
| } |
| |
| - error = regulator_enable(data->vcc); |
| - if (error) { |
| - dev_err(dev, "error %d enabling regulator\n", error); |
| - goto err; |
| - } |
| - |
| error = elan_set_power(data, true); |
| if (error) { |
| dev_err(dev, "power up when resuming failed: %d\n", error); |