From: Greg Kroah-Hartman Date: Sun, 6 Mar 2022 09:44:19 +0000 (+0100) Subject: 4.19-stable patches X-Git-Tag: v4.9.305~36 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=bf55f3b1946c518e836446505f27d315a19b4730;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: input-elan_i2c-fix-regulator-enable-count-imbalance-after-suspend-resume.patch input-elan_i2c-move-regulator_able-out-of-elan_able_power.patch --- diff --git a/queue-4.19/input-elan_i2c-fix-regulator-enable-count-imbalance-after-suspend-resume.patch b/queue-4.19/input-elan_i2c-fix-regulator-enable-count-imbalance-after-suspend-resume.patch new file mode 100644 index 00000000000..f7b424eaaf1 --- /dev/null +++ b/queue-4.19/input-elan_i2c-fix-regulator-enable-count-imbalance-after-suspend-resume.patch @@ -0,0 +1,56 @@ +From 04b7762e37c95d9b965d16bb0e18dbd1fa2e2861 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +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 + +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 +Link: https://lore.kernel.org/r/20220131135436.29638-2-hdegoede@redhat.com +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -1280,17 +1280,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); diff --git a/queue-4.19/input-elan_i2c-move-regulator_able-out-of-elan_able_power.patch b/queue-4.19/input-elan_i2c-move-regulator_able-out-of-elan_able_power.patch new file mode 100644 index 00000000000..1dba1ed68a2 --- /dev/null +++ b/queue-4.19/input-elan_i2c-move-regulator_able-out-of-elan_able_power.patch @@ -0,0 +1,125 @@ +From 81a36d8ce554b82b0a08e2b95d0bd44fcbff339b Mon Sep 17 00:00:00 2001 +From: Hans de Goede +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 + +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 +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -140,55 +140,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; + } + +@@ -1291,9 +1257,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; + } +@@ -1309,7 +1285,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; diff --git a/queue-4.19/series b/queue-4.19/series index 872ed13deaa..c7d57559978 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -42,3 +42,5 @@ ibmvnic-free-reset-work-item-when-flushing.patch soc-fsl-qe-check-of-ioremap-return-value.patch net-chelsio-cxgb3-check-the-return-value-of-pci_find.patch nl80211-handle-nla_memdup-failures-in-handle_nan_fil.patch +input-elan_i2c-move-regulator_able-out-of-elan_able_power.patch +input-elan_i2c-fix-regulator-enable-count-imbalance-after-suspend-resume.patch