struct i2chid_ops ops;
 
        struct regulator *vdd;
+       struct notifier_block nb;
+       struct mutex regulator_mutex;
        struct gpio_desc *reset_gpio;
        const struct goodix_i2c_hid_timing_data *timings;
 };
 
-static int goodix_i2c_hid_power_up(struct i2chid_ops *ops)
+static void goodix_i2c_hid_deassert_reset(struct i2c_hid_of_goodix *ihid_goodix,
+                                         bool regulator_just_turned_on)
 {
-       struct i2c_hid_of_goodix *ihid_goodix =
-               container_of(ops, struct i2c_hid_of_goodix, ops);
-       int ret;
-
-       ret = regulator_enable(ihid_goodix->vdd);
-       if (ret)
-               return ret;
-
-       if (ihid_goodix->timings->post_power_delay_ms)
+       if (regulator_just_turned_on && ihid_goodix->timings->post_power_delay_ms)
                msleep(ihid_goodix->timings->post_power_delay_ms);
 
        gpiod_set_value_cansleep(ihid_goodix->reset_gpio, 0);
        if (ihid_goodix->timings->post_gpio_reset_delay_ms)
                msleep(ihid_goodix->timings->post_gpio_reset_delay_ms);
+}
 
-       return 0;
+static int goodix_i2c_hid_power_up(struct i2chid_ops *ops)
+{
+       struct i2c_hid_of_goodix *ihid_goodix =
+               container_of(ops, struct i2c_hid_of_goodix, ops);
+
+       return regulator_enable(ihid_goodix->vdd);
 }
 
 static void goodix_i2c_hid_power_down(struct i2chid_ops *ops)
        struct i2c_hid_of_goodix *ihid_goodix =
                container_of(ops, struct i2c_hid_of_goodix, ops);
 
-       gpiod_set_value_cansleep(ihid_goodix->reset_gpio, 1);
        regulator_disable(ihid_goodix->vdd);
 }
 
+static int ihid_goodix_vdd_notify(struct notifier_block *nb,
+                                   unsigned long event,
+                                   void *ignored)
+{
+       struct i2c_hid_of_goodix *ihid_goodix =
+               container_of(nb, struct i2c_hid_of_goodix, nb);
+       int ret = NOTIFY_OK;
+
+       mutex_lock(&ihid_goodix->regulator_mutex);
+
+       switch (event) {
+       case REGULATOR_EVENT_PRE_DISABLE:
+               gpiod_set_value_cansleep(ihid_goodix->reset_gpio, 1);
+               break;
+
+       case REGULATOR_EVENT_ENABLE:
+               goodix_i2c_hid_deassert_reset(ihid_goodix, true);
+               break;
+
+       case REGULATOR_EVENT_ABORT_DISABLE:
+               goodix_i2c_hid_deassert_reset(ihid_goodix, false);
+               break;
+
+       default:
+               ret = NOTIFY_DONE;
+               break;
+       }
+
+       mutex_unlock(&ihid_goodix->regulator_mutex);
+
+       return ret;
+}
+
 static int i2c_hid_of_goodix_probe(struct i2c_client *client,
                                   const struct i2c_device_id *id)
 {
        struct i2c_hid_of_goodix *ihid_goodix;
-
+       int ret;
        ihid_goodix = devm_kzalloc(&client->dev, sizeof(*ihid_goodix),
                                   GFP_KERNEL);
        if (!ihid_goodix)
                return -ENOMEM;
 
+       mutex_init(&ihid_goodix->regulator_mutex);
+
        ihid_goodix->ops.power_up = goodix_i2c_hid_power_up;
        ihid_goodix->ops.power_down = goodix_i2c_hid_power_down;
 
 
        ihid_goodix->timings = device_get_match_data(&client->dev);
 
+       /*
+        * We need to control the "reset" line in lockstep with the regulator
+        * actually turning on an off instead of just when we make the request.
+        * This matters if the regulator is shared with another consumer.
+        * - If the regulator is off then we must assert reset. The reset
+        *   line is active low and on some boards it could cause a current
+        *   leak if left high.
+        * - If the regulator is on then we don't want reset asserted for very
+        *   long. Holding the controller in reset apparently draws extra
+        *   power.
+        */
+       mutex_lock(&ihid_goodix->regulator_mutex);
+       ihid_goodix->nb.notifier_call = ihid_goodix_vdd_notify;
+       ret = regulator_register_notifier(ihid_goodix->vdd, &ihid_goodix->nb);
+       if (ret) {
+               mutex_unlock(&ihid_goodix->regulator_mutex);
+               return dev_err_probe(&client->dev, ret,
+                       "regulator notifier request failed\n");
+       }
+
+       /*
+        * If someone else is holding the regulator on (or the regulator is
+        * an always-on one) we might never be told to deassert reset. Do it
+        * now. Here we'll assume that someone else might have _just
+        * barely_ turned the regulator on so we'll do the full
+        * "post_power_delay" just in case.
+        */
+       if (ihid_goodix->reset_gpio && regulator_is_enabled(ihid_goodix->vdd))
+               goodix_i2c_hid_deassert_reset(ihid_goodix, true);
+       mutex_unlock(&ihid_goodix->regulator_mutex);
+
        return i2c_hid_core_probe(client, &ihid_goodix->ops, 0x0001);
 }