• Doug Anderson's avatar
    regulator: core: Fix enable GPIO reference counting · 29d62ec5
    Doug Anderson authored
    Normally _regulator_do_enable() isn't called on an already-enabled
    rdev.  That's because the main caller, _regulator_enable() always
    calls _regulator_is_enabled() and only calls _regulator_do_enable() if
    the rdev was not already enabled.
    
    However, there is one caller of _regulator_do_enable() that doesn't
    check: regulator_suspend_finish().  While we might want to make
    regulator_suspend_finish() behave more like _regulator_enable(), it's
    probably also a good idea to make _regulator_do_enable() robust if it
    is called on an already enabled rdev.
    
    At the moment, _regulator_do_enable() is _not_ robust for already
    enabled rdevs if we're using an ena_pin.  Each time
    _regulator_do_enable() is called for an rdev using an ena_pin the
    reference count of the ena_pin is incremented even if the rdev was
    already enabled.  This is not as intended because the ena_pin is for
    something else: for keeping track of how many active rdevs there are
    sharing the same ena_pin.
    
    Here's how the reference counting works here:
    
    * Each time _regulator_enable() is called we increment
      rdev->use_count, so _regulator_enable() calls need to be balanced
      with _regulator_disable() calls.
    
    * There is no explicit reference counting in _regulator_do_enable()
      which is normally just a warapper around rdev->desc->ops->enable()
      with code for supporting delays.  It's not expected that the
      "ops->enable()" call do reference counting.
    
    * Since regulator_ena_gpio_ctrl() does have reference counting
      (handling the sharing of the pin amongst multiple rdevs), we
      shouldn't call it if the current rdev is already enabled.
    
    Note that as part of this we cleanup (remove) the initting of
    ena_gpio_state in regulator_register().  In _regulator_do_enable(),
    _regulator_do_disable() and _regulator_is_enabled() is is clear that
    ena_gpio_state should be the state of whether this particular rdev has
    requested the GPIO be enabled.  regulator_register() was initting it
    as the actual state of the pin.
    
    Fixes: 967cfb18 ("regulator: core: manage enable GPIO list")
    Signed-off-by: default avatarDoug Anderson <dianders@chromium.org>
    Signed-off-by: default avatarMark Brown <broonie@kernel.org>
    Cc: stable@vger.kernel.org
    29d62ec5
core.c 104 KB