[PATCH v2 4/5] input: drv260x: Fix unbalanced regulator_disable() call

Yauhen Kharuzhy posted 5 patches 1 month, 2 weeks ago
[PATCH v2 4/5] input: drv260x: Fix unbalanced regulator_disable() call
Posted by Yauhen Kharuzhy 1 month, 2 weeks ago
The driver acquires the 'vbat' regulator during probing but never enables
it. Consequently, in the suspend method, the driver disables the regulator
without enabling it first, causing an 'Unbalanced regulator_disable()'
error.

Enable the regulator in the probe() method and add the remove() method with
regulator disabling to fix this.

Signed-off-by: Yauhen Kharuzhy <jekhor@gmail.com>
---
 drivers/input/misc/drv260x.c | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c
index c4dd410c303e..71fbdabc6589 100644
--- a/drivers/input/misc/drv260x.c
+++ b/drivers/input/misc/drv260x.c
@@ -520,19 +520,37 @@ static int drv260x_probe(struct i2c_client *client)
 		return error;
 	}
 
+	error = regulator_enable(haptics->regulator);
+	if (error) {
+		dev_err(dev, "Failed to enable regulator\n");
+		return error;
+	}
+
 	error = drv260x_init(haptics);
 	if (error) {
 		dev_err(dev, "Device init failed: %d\n", error);
-		return error;
+		goto err_regulator_disable;
 	}
 
 	error = input_register_device(haptics->input_dev);
 	if (error) {
 		dev_err(dev, "couldn't register input device: %d\n", error);
-		return error;
+		goto err_regulator_disable;
 	}
 
 	return 0;
+
+err_regulator_disable:
+	regulator_disable(haptics->regulator);
+
+	return error;
+}
+
+static void drv260x_remove(struct i2c_client *client)
+{
+	struct drv260x_data *haptics = i2c_get_clientdata(client);
+
+	regulator_disable(haptics->regulator);
 }
 
 static int drv260x_suspend(struct device *dev)
@@ -626,6 +644,7 @@ MODULE_DEVICE_TABLE(of, drv260x_of_match);
 
 static struct i2c_driver drv260x_driver = {
 	.probe		= drv260x_probe,
+	.remove		= drv260x_remove,
 	.driver		= {
 		.name	= "drv260x-haptics",
 		.of_match_table = drv260x_of_match,
-- 
2.51.0
Re: [PATCH v2 4/5] input: drv260x: Fix unbalanced regulator_disable() call
Posted by Dmitry Torokhov 1 month, 1 week ago
Hi Yauhen,

On Sun, Feb 15, 2026 at 04:14:34PM +0200, Yauhen Kharuzhy wrote:
> +static void drv260x_remove(struct i2c_client *client)
> +{
> +	struct drv260x_data *haptics = i2c_get_clientdata(client);
> +
> +	regulator_disable(haptics->regulator);
>  }

This will result in power being shut off the first thing during
unbinding, which is too early.

I switched this to devm_add_action_or_reset() and applied.

Thanks.

-- 
Dmitry
Re: [PATCH v2 4/5] input: drv260x: Fix unbalanced regulator_disable() call
Posted by Yauhen Kharuzhy 1 month, 1 week ago
On Wed, Feb 18, 2026 at 06:43:30PM -0800, Dmitry Torokhov wrote:
> Hi Yauhen,
> 
> On Sun, Feb 15, 2026 at 04:14:34PM +0200, Yauhen Kharuzhy wrote:
> > +static void drv260x_remove(struct i2c_client *client)
> > +{
> > +	struct drv260x_data *haptics = i2c_get_clientdata(client);
> > +
> > +	regulator_disable(haptics->regulator);
> >  }
> 
> This will result in power being shut off the first thing during
> unbinding, which is too early.
> 
> I switched this to devm_add_action_or_reset() and applied.

Do you mean that, in this case, regulator_disable() may be called before any
devm_* registered actions? Good point, thanks.

-- 
Yauhen Kharuzhy
Re: [PATCH v2 4/5] input: drv260x: Fix unbalanced regulator_disable() call
Posted by Dmitry Torokhov 1 month, 1 week ago
On Thu, Feb 19, 2026 at 12:11:47PM +0200, Yauhen Kharuzhy wrote:
> On Wed, Feb 18, 2026 at 06:43:30PM -0800, Dmitry Torokhov wrote:
> > Hi Yauhen,
> > 
> > On Sun, Feb 15, 2026 at 04:14:34PM +0200, Yauhen Kharuzhy wrote:
> > > +static void drv260x_remove(struct i2c_client *client)
> > > +{
> > > +	struct drv260x_data *haptics = i2c_get_clientdata(client);
> > > +
> > > +	regulator_disable(haptics->regulator);
> > >  }
> > 
> > This will result in power being shut off the first thing during
> > unbinding, which is too early.
> > 
> > I switched this to devm_add_action_or_reset() and applied.
> 
> Do you mean that, in this case, regulator_disable() may be called before any
> devm_* registered actions? Good point, thanks.
> 

Yes, all devm* actions are run after remove() completes.

Thanks.

-- 
Dmitry