Merge tag 'regmap-v4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 8 Sep 2015 23:48:55 +0000 (16:48 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 8 Sep 2015 23:48:55 +0000 (16:48 -0700)
Pull regmap updates from Mark Brown:
 "This has been a busy release for regmap.

  By far the biggest set of changes here are those from Markus Pargmann
  which implement support for block transfers in smbus devices.  This
  required quite a bit of refactoring but leaves us better able to
  handle odd restrictions that controllers may have and with better
  performance on smbus.

  Other new features include:

   - Fix interactions with lockdep for nested regmaps (eg, when a device
     using regmap is connected to a bus where the bus controller has a
     separate regmap).  Lockdep's default class identification is too
     crude to work without help.

   - Support for must write bitfield operations, useful for operations
     which require writing a bit to trigger them from Kuniori Morimoto.

   - Support for delaying during register patch application from Nariman
     Poushin.

   - Support for overriding cache state via the debugfs implementation
     from Richard Fitzgerald"

* tag 'regmap-v4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap: (25 commits)
  regmap: fix a NULL pointer dereference in __regmap_init
  regmap: Support bulk reads for devices without raw formatting
  regmap-i2c: Add smbus i2c block support
  regmap: Add raw_write/read checks for max_raw_write/read sizes
  regmap: regmap max_raw_read/write getter functions
  regmap: Introduce max_raw_read/write for regmap_bulk_read/write
  regmap: Add missing comments about struct regmap_bus
  regmap: No multi_write support if bus->write does not exist
  regmap: Split use_single_rw internally into use_single_read/write
  regmap: Fix regmap_bulk_write for bus writes
  regmap: regmap_raw_read return error on !bus->read
  regulator: core: Print at debug level on debugfs creation failure
  regmap: Fix regmap_can_raw_write check
  regmap: fix typos in regmap.c
  regmap: Fix integertypes for register address and value
  regmap: Move documentation to regmap.h
  regmap: Use different lockdep class for each regmap init call
  thermal: sti: Add parentheses around bridge->ops->regmap_init call
  mfd: vexpress: Add parentheses around bridge->ops->regmap_init call
  regmap: debugfs: Fix misuse of IS_ENABLED
  ...

1  2 
drivers/regulator/core.c

diff --combined drivers/regulator/core.c
@@@ -111,11 -111,6 +111,11 @@@ static struct regulator *create_regulat
                                          const char *supply_name);
  static void _regulator_put(struct regulator *regulator);
  
 +static struct regulator_dev *dev_to_rdev(struct device *dev)
 +{
 +      return container_of(dev, struct regulator_dev, dev);
 +}
 +
  static const char *rdev_get_name(struct regulator_dev *rdev)
  {
        if (rdev->constraints && rdev->constraints->name)
@@@ -301,7 -296,7 +301,7 @@@ static int regulator_check_drms(struct 
                return -ENODEV;
        }
        if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS)) {
 -              rdev_err(rdev, "operation not allowed\n");
 +              rdev_dbg(rdev, "operation not allowed\n");
                return -EPERM;
        }
        return 0;
@@@ -646,8 -641,6 +646,8 @@@ static int drms_uA_update(struct regula
        int current_uA = 0, output_uV, input_uV, err;
        unsigned int mode;
  
 +      lockdep_assert_held_once(&rdev->mutex);
 +
        /*
         * first check to see if we can set modes at all, otherwise just
         * tell the consumer everything is OK.
@@@ -768,8 -761,6 +768,8 @@@ static int suspend_set_state(struct reg
  /* locks held by caller */
  static int suspend_prepare(struct regulator_dev *rdev, suspend_state_t state)
  {
 +      lockdep_assert_held_once(&rdev->mutex);
 +
        if (!rdev->constraints)
                return -EINVAL;
  
@@@ -1091,15 -1082,6 +1091,15 @@@ static int set_machine_constraints(stru
                }
        }
  
 +      if (rdev->constraints->over_current_protection
 +              && ops->set_over_current_protection) {
 +              ret = ops->set_over_current_protection(rdev);
 +              if (ret < 0) {
 +                      rdev_err(rdev, "failed to set over current protection\n");
 +                      goto out;
 +              }
 +      }
 +
        print_constraints(rdev);
        return 0;
  out:
@@@ -1262,7 -1244,7 +1262,7 @@@ static struct regulator *create_regulat
        regulator->debugfs = debugfs_create_dir(regulator->supply_name,
                                                rdev->debugfs);
        if (!regulator->debugfs) {
-               rdev_warn(rdev, "Failed to create debugfs directory\n");
+               rdev_dbg(rdev, "Failed to create debugfs directory\n");
        } else {
                debugfs_create_u32("uA_load", 0444, regulator->debugfs,
                                   &regulator->uA_load);
@@@ -1613,11 -1595,9 +1613,11 @@@ static void _regulator_put(struct regul
  {
        struct regulator_dev *rdev;
  
 -      if (regulator == NULL || IS_ERR(regulator))
 +      if (IS_ERR_OR_NULL(regulator))
                return;
  
 +      lockdep_assert_held_once(&regulator_list_mutex);
 +
        rdev = regulator->rdev;
  
        debugfs_remove_recursive(regulator->debugfs);
        if (regulator->dev)
                sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
        mutex_lock(&rdev->mutex);
 -      kfree(regulator->supply_name);
        list_del(&regulator->list);
 -      kfree(regulator);
  
        rdev->open_count--;
        rdev->exclusive = 0;
        mutex_unlock(&rdev->mutex);
  
 +      kfree(regulator->supply_name);
 +      kfree(regulator);
 +
        module_put(rdev->owner);
  }
  
@@@ -1997,8 -1976,6 +1997,8 @@@ static int _regulator_enable(struct reg
  {
        int ret;
  
 +      lockdep_assert_held_once(&rdev->mutex);
 +
        /* check voltage and requested load before enabling */
        if (rdev->constraints &&
            (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS))
@@@ -2099,8 -2076,6 +2099,8 @@@ static int _regulator_disable(struct re
  {
        int ret = 0;
  
 +      lockdep_assert_held_once(&rdev->mutex);
 +
        if (WARN(rdev->use_count <= 0,
                 "unbalanced disables for %s\n", rdev_get_name(rdev)))
                return -EIO;
@@@ -2179,8 -2154,6 +2179,8 @@@ static int _regulator_force_disable(str
  {
        int ret = 0;
  
 +      lockdep_assert_held_once(&rdev->mutex);
 +
        ret = _notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE |
                        REGULATOR_EVENT_PRE_DISABLE, NULL);
        if (ret & NOTIFY_STOP_MASK)
@@@ -2749,7 -2722,7 +2749,7 @@@ int regulator_set_voltage(struct regula
                goto out;
  
        /* If we're trying to set a range that overlaps the current voltage,
 -       * return succesfully even though the regulator does not support
 +       * return successfully even though the regulator does not support
         * changing the voltage.
         */
        if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
@@@ -3477,8 -3450,6 +3477,8 @@@ EXPORT_SYMBOL_GPL(regulator_bulk_free)
  int regulator_notifier_call_chain(struct regulator_dev *rdev,
                                  unsigned long event, void *data)
  {
 +      lockdep_assert_held_once(&rdev->mutex);
 +
        _notifier_call_chain(rdev, event, data);
        return NOTIFY_DONE;
  
@@@ -3623,9 -3594,6 +3623,9 @@@ static const struct attribute_group *re
  static void regulator_dev_release(struct device *dev)
  {
        struct regulator_dev *rdev = dev_get_drvdata(dev);
 +
 +      kfree(rdev->constraints);
 +      of_node_put(rdev->dev.of_node);
        kfree(rdev);
  }
  
@@@ -3856,9 -3824,11 +3856,9 @@@ void regulator_unregister(struct regula
        WARN_ON(rdev->open_count);
        unset_regulator_supplies(rdev);
        list_del(&rdev->list);
 -      kfree(rdev->constraints);
 +      mutex_unlock(&regulator_list_mutex);
        regulator_ena_gpio_free(rdev);
 -      of_node_put(rdev->dev.of_node);
        device_unregister(&rdev->dev);
 -      mutex_unlock(&regulator_list_mutex);
  }
  EXPORT_SYMBOL_GPL(regulator_unregister);
  
@@@ -4177,57 -4147,13 +4177,57 @@@ static int __init regulator_init(void
  /* init early to allow our consumers to complete system booting */
  core_initcall(regulator_init);
  
 -static int __init regulator_init_complete(void)
 +static int __init regulator_late_cleanup(struct device *dev, void *data)
  {
 -      struct regulator_dev *rdev;
 -      const struct regulator_ops *ops;
 -      struct regulation_constraints *c;
 +      struct regulator_dev *rdev = dev_to_rdev(dev);
 +      const struct regulator_ops *ops = rdev->desc->ops;
 +      struct regulation_constraints *c = rdev->constraints;
        int enabled, ret;
  
 +      if (c && c->always_on)
 +              return 0;
 +
 +      if (c && !(c->valid_ops_mask & REGULATOR_CHANGE_STATUS))
 +              return 0;
 +
 +      mutex_lock(&rdev->mutex);
 +
 +      if (rdev->use_count)
 +              goto unlock;
 +
 +      /* If we can't read the status assume it's on. */
 +      if (ops->is_enabled)
 +              enabled = ops->is_enabled(rdev);
 +      else
 +              enabled = 1;
 +
 +      if (!enabled)
 +              goto unlock;
 +
 +      if (have_full_constraints()) {
 +              /* We log since this may kill the system if it goes
 +               * wrong. */
 +              rdev_info(rdev, "disabling\n");
 +              ret = _regulator_do_disable(rdev);
 +              if (ret != 0)
 +                      rdev_err(rdev, "couldn't disable: %d\n", ret);
 +      } else {
 +              /* The intention is that in future we will
 +               * assume that full constraints are provided
 +               * so warn even if we aren't going to do
 +               * anything here.
 +               */
 +              rdev_warn(rdev, "incomplete constraints, leaving on\n");
 +      }
 +
 +unlock:
 +      mutex_unlock(&rdev->mutex);
 +
 +      return 0;
 +}
 +
 +static int __init regulator_init_complete(void)
 +{
        /*
         * Since DT doesn't provide an idiomatic mechanism for
         * enabling full constraints and since it's much more natural
        if (of_have_populated_dt())
                has_full_constraints = true;
  
 -      mutex_lock(&regulator_list_mutex);
 -
        /* If we have a full configuration then disable any regulators
         * we have permission to change the status for and which are
         * not in use or always_on.  This is effectively the default
         * for DT and ACPI as they have full constraints.
         */
 -      list_for_each_entry(rdev, &regulator_list, list) {
 -              ops = rdev->desc->ops;
 -              c = rdev->constraints;
 -
 -              if (c && c->always_on)
 -                      continue;
 -
 -              if (c && !(c->valid_ops_mask & REGULATOR_CHANGE_STATUS))
 -                      continue;
 -
 -              mutex_lock(&rdev->mutex);
 -
 -              if (rdev->use_count)
 -                      goto unlock;
 -
 -              /* If we can't read the status assume it's on. */
 -              if (ops->is_enabled)
 -                      enabled = ops->is_enabled(rdev);
 -              else
 -                      enabled = 1;
 -
 -              if (!enabled)
 -                      goto unlock;
 -
 -              if (have_full_constraints()) {
 -                      /* We log since this may kill the system if it
 -                       * goes wrong. */
 -                      rdev_info(rdev, "disabling\n");
 -                      ret = _regulator_do_disable(rdev);
 -                      if (ret != 0)
 -                              rdev_err(rdev, "couldn't disable: %d\n", ret);
 -              } else {
 -                      /* The intention is that in future we will
 -                       * assume that full constraints are provided
 -                       * so warn even if we aren't going to do
 -                       * anything here.
 -                       */
 -                      rdev_warn(rdev, "incomplete constraints, leaving on\n");
 -              }
 -
 -unlock:
 -              mutex_unlock(&rdev->mutex);
 -      }
 -
 -      mutex_unlock(&regulator_list_mutex);
 +      class_for_each_device(&regulator_class, NULL, NULL,
 +                            regulator_late_cleanup);
  
        return 0;
  }