| From 81a36d8ce554b82b0a08e2b95d0bd44fcbff339b Mon Sep 17 00:00:00 2001 |
| From: Hans de Goede <hdegoede@redhat.com> |
| Date: Mon, 28 Feb 2022 23:39:38 -0800 |
| Subject: Input: elan_i2c - move regulator_[en|dis]able() out of elan_[en|dis]able_power() |
| |
| From: Hans de Goede <hdegoede@redhat.com> |
| |
| commit 81a36d8ce554b82b0a08e2b95d0bd44fcbff339b upstream. |
| |
| elan_disable_power() is called conditionally on suspend, where as |
| elan_enable_power() is always called on resume. This leads to |
| an imbalance in the regulator's enable count. |
| |
| Move the regulator_[en|dis]able() calls out of elan_[en|dis]able_power() |
| in preparation of fixing this. |
| |
| No functional changes intended. |
| |
| Signed-off-by: Hans de Goede <hdegoede@redhat.com> |
| Link: https://lore.kernel.org/r/20220131135436.29638-1-hdegoede@redhat.com |
| [dtor: consolidate elan_[en|dis]able() into elan_set_power()] |
| 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 | 62 ++++++++++++------------------------ |
| 1 file changed, 22 insertions(+), 40 deletions(-) |
| |
| --- a/drivers/input/mouse/elan_i2c_core.c |
| +++ b/drivers/input/mouse/elan_i2c_core.c |
| @@ -139,55 +139,21 @@ static int elan_get_fwinfo(u16 ic_type, |
| return 0; |
| } |
| |
| -static int elan_enable_power(struct elan_tp_data *data) |
| +static int elan_set_power(struct elan_tp_data *data, bool on) |
| { |
| int repeat = ETP_RETRY_COUNT; |
| int error; |
| |
| - error = regulator_enable(data->vcc); |
| - if (error) { |
| - dev_err(&data->client->dev, |
| - "failed to enable regulator: %d\n", error); |
| - return error; |
| - } |
| - |
| do { |
| - error = data->ops->power_control(data->client, true); |
| + error = data->ops->power_control(data->client, on); |
| if (error >= 0) |
| return 0; |
| |
| msleep(30); |
| } while (--repeat > 0); |
| |
| - dev_err(&data->client->dev, "failed to enable power: %d\n", error); |
| - return error; |
| -} |
| - |
| -static int elan_disable_power(struct elan_tp_data *data) |
| -{ |
| - int repeat = ETP_RETRY_COUNT; |
| - int error; |
| - |
| - do { |
| - error = data->ops->power_control(data->client, false); |
| - if (!error) { |
| - error = regulator_disable(data->vcc); |
| - if (error) { |
| - dev_err(&data->client->dev, |
| - "failed to disable regulator: %d\n", |
| - error); |
| - /* Attempt to power the chip back up */ |
| - data->ops->power_control(data->client, true); |
| - break; |
| - } |
| - |
| - return 0; |
| - } |
| - |
| - msleep(30); |
| - } while (--repeat > 0); |
| - |
| - dev_err(&data->client->dev, "failed to disable power: %d\n", error); |
| + dev_err(&data->client->dev, "failed to set power %s: %d\n", |
| + on ? "on" : "off", error); |
| return error; |
| } |
| |
| @@ -1316,9 +1282,19 @@ static int __maybe_unused elan_suspend(s |
| /* Enable wake from IRQ */ |
| data->irq_wake = (enable_irq_wake(client->irq) == 0); |
| } else { |
| - ret = elan_disable_power(data); |
| + ret = elan_set_power(data, false); |
| + if (ret) |
| + goto err; |
| + |
| + ret = regulator_disable(data->vcc); |
| + if (ret) { |
| + dev_err(dev, "error %d disabling regulator\n", ret); |
| + /* Attempt to power the chip back up */ |
| + elan_set_power(data, true); |
| + } |
| } |
| |
| +err: |
| mutex_unlock(&data->sysfs_mutex); |
| return ret; |
| } |
| @@ -1334,7 +1310,13 @@ static int __maybe_unused elan_resume(st |
| data->irq_wake = false; |
| } |
| |
| - error = elan_enable_power(data); |
| + 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); |
| goto err; |