Merge tag 'regulator-fix-v5.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 8 Jun 2021 16:41:16 +0000 (09:41 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 8 Jun 2021 16:41:16 +0000 (09:41 -0700)
Pull regulator fixes from Mark Brown:
 "A collection of fixes for the regulator API that have come up since
  the merge window, including a big batch of fixes from Axel Lin's usual
  careful and detailed review.

  The one stand out fix here is Dmitry Baryshkov's fix for an issue
  where we fail to power on the parents of always on regulators during
  system startup if they weren't already powered on"

* tag 'regulator-fix-v5.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (21 commits)
  regulator: rt4801: Fix NULL pointer dereference if priv->enable_gpios is NULL
  regulator: hi6421v600: Fix .vsel_mask setting
  regulator: bd718x7: Fix the BUCK7 voltage setting on BD71837
  regulator: atc260x: Fix n_voltages and min_sel for pickable linear ranges
  regulator: rtmv20: Fix to make regcache value first reading back from HW
  regulator: mt6315: Fix function prototype for mt6315_map_mode
  regulator: rtmv20: Add Richtek to Kconfig text
  regulator: rtmv20: Fix .set_current_limit/.get_current_limit callbacks
  regulator: hisilicon: use the correct HiSilicon copyright
  regulator: bd71828: Fix .n_voltages settings
  regulator: bd70528: Fix off-by-one for buck123 .n_voltages setting
  regulator: max77620: Silence deferred probe error
  regulator: max77620: Use device_set_of_node_from_dev()
  regulator: scmi: Fix off-by-one for linear regulators .n_voltages setting
  regulator: core: resolve supply for boot-on/always-on regulators
  regulator: fixed: Ensure enable_counter is correct if reg_domain_disable fails
  regulator: Check ramp_delay_table for regulator_set_ramp_delay_regmap
  regulator: fan53880: Fix missing n_voltages setting
  regulator: da9121: Return REGULATOR_MODE_INVALID for invalid mode
  regulator: fan53555: fix TCS4525 voltage calulation
  ...

1  2 
drivers/regulator/Kconfig
drivers/regulator/bd718x7-regulator.c
drivers/regulator/hi6421v600-regulator.c
drivers/regulator/scmi-regulator.c
include/linux/mfd/rohm-bd71828.h

Simple merge
Simple merge
index f6a14e9,0000000..d6340bb
mode 100644,000000..100644
--- /dev/null
@@@ -1,299 -1,0 +1,299 @@@
- // Copyright (c) 2011 Hisilicon.
 +// SPDX-License-Identifier: GPL-2.0
 +//
 +// Device driver for regulators in Hisi IC
 +//
 +// Copyright (c) 2013 Linaro Ltd.
-                       .vsel_mask      = (1 << (ARRAY_SIZE(vtable) - 1)) - 1, \
++// Copyright (c) 2011 HiSilicon Ltd.
 +// Copyright (c) 2020-2021 Huawei Technologies Co., Ltd
 +//
 +// Guodong Xu <guodong.xu@linaro.org>
 +
 +#include <linux/delay.h>
 +#include <linux/mfd/hi6421-spmi-pmic.h>
 +#include <linux/module.h>
 +#include <linux/platform_device.h>
 +#include <linux/regmap.h>
 +#include <linux/regulator/driver.h>
 +#include <linux/spmi.h>
 +
 +struct hi6421_spmi_reg_info {
 +      struct regulator_desc   desc;
 +      struct hi6421_spmi_pmic *pmic;
 +      u8                      eco_mode_mask;
 +      u32                     eco_uA;
 +
 +      /* Serialize regulator enable logic */
 +      struct mutex enable_mutex;
 +};
 +
 +static const unsigned int ldo3_voltages[] = {
 +      1500000, 1550000, 1600000, 1650000,
 +      1700000, 1725000, 1750000, 1775000,
 +      1800000, 1825000, 1850000, 1875000,
 +      1900000, 1925000, 1950000, 2000000
 +};
 +
 +static const unsigned int ldo4_voltages[] = {
 +      1725000, 1750000, 1775000, 1800000,
 +      1825000, 1850000, 1875000, 1900000
 +};
 +
 +static const unsigned int ldo9_voltages[] = {
 +      1750000, 1800000, 1825000, 2800000,
 +      2850000, 2950000, 3000000, 3300000
 +};
 +
 +static const unsigned int ldo15_voltages[] = {
 +      1800000, 1850000, 2400000, 2600000,
 +      2700000, 2850000, 2950000, 3000000
 +};
 +
 +static const unsigned int ldo17_voltages[] = {
 +      2500000, 2600000, 2700000, 2800000,
 +      3000000, 3100000, 3200000, 3300000
 +};
 +
 +static const unsigned int ldo34_voltages[] = {
 +      2600000, 2700000, 2800000, 2900000,
 +      3000000, 3100000, 3200000, 3300000
 +};
 +
 +/**
 + * HI6421V600_LDO() - specify a LDO power line
 + * @_id: LDO id name string
 + * @vtable: voltage table
 + * @ereg: enable register
 + * @emask: enable mask
 + * @vreg: voltage select register
 + * @odelay: off/on delay time in uS
 + * @etime: enable time in uS
 + * @ecomask: eco mode mask
 + * @ecoamp: eco mode load uppler limit in uA
 + */
 +#define HI6421V600_LDO(_id, vtable, ereg, emask, vreg,                               \
 +                     odelay, etime, ecomask, ecoamp)                         \
 +      [HI6421V600_##_id] = {                                                 \
 +              .desc = {                                                      \
 +                      .name           = #_id,                                \
 +                      .of_match        = of_match_ptr(#_id),                 \
 +                      .regulators_node = of_match_ptr("regulators"),         \
 +                      .ops            = &hi6421_spmi_ldo_rops,               \
 +                      .type           = REGULATOR_VOLTAGE,                   \
 +                      .id             = HI6421V600_##_id,                    \
 +                      .owner          = THIS_MODULE,                         \
 +                      .volt_table     = vtable,                              \
 +                      .n_voltages     = ARRAY_SIZE(vtable),                  \
++                      .vsel_mask      = ARRAY_SIZE(vtable) - 1,              \
 +                      .vsel_reg       = vreg,                                \
 +                      .enable_reg     = ereg,                                \
 +                      .enable_mask    = emask,                               \
 +                      .enable_time    = etime,                               \
 +                      .ramp_delay     = etime,                               \
 +                      .off_on_delay   = odelay,                              \
 +              },                                                             \
 +              .eco_mode_mask          = ecomask,                             \
 +              .eco_uA                 = ecoamp,                              \
 +      }
 +
 +static int hi6421_spmi_regulator_enable(struct regulator_dev *rdev)
 +{
 +      struct hi6421_spmi_reg_info *sreg = rdev_get_drvdata(rdev);
 +      struct hi6421_spmi_pmic *pmic = sreg->pmic;
 +      int ret;
 +
 +      /* cannot enable more than one regulator at one time */
 +      mutex_lock(&sreg->enable_mutex);
 +
 +      ret = regmap_update_bits(pmic->regmap, rdev->desc->enable_reg,
 +                               rdev->desc->enable_mask,
 +                               rdev->desc->enable_mask);
 +
 +      /* Avoid powering up multiple devices at the same time */
 +      usleep_range(rdev->desc->off_on_delay, rdev->desc->off_on_delay + 60);
 +
 +      mutex_unlock(&sreg->enable_mutex);
 +
 +      return ret;
 +}
 +
 +static int hi6421_spmi_regulator_disable(struct regulator_dev *rdev)
 +{
 +      struct hi6421_spmi_reg_info *sreg = rdev_get_drvdata(rdev);
 +      struct hi6421_spmi_pmic *pmic = sreg->pmic;
 +
 +      return regmap_update_bits(pmic->regmap, rdev->desc->enable_reg,
 +                                rdev->desc->enable_mask, 0);
 +}
 +
 +static unsigned int hi6421_spmi_regulator_get_mode(struct regulator_dev *rdev)
 +{
 +      struct hi6421_spmi_reg_info *sreg = rdev_get_drvdata(rdev);
 +      struct hi6421_spmi_pmic *pmic = sreg->pmic;
 +      u32 reg_val;
 +
 +      regmap_read(pmic->regmap, rdev->desc->enable_reg, &reg_val);
 +
 +      if (reg_val & sreg->eco_mode_mask)
 +              return REGULATOR_MODE_IDLE;
 +
 +      return REGULATOR_MODE_NORMAL;
 +}
 +
 +static int hi6421_spmi_regulator_set_mode(struct regulator_dev *rdev,
 +                                        unsigned int mode)
 +{
 +      struct hi6421_spmi_reg_info *sreg = rdev_get_drvdata(rdev);
 +      struct hi6421_spmi_pmic *pmic = sreg->pmic;
 +      u32 val;
 +
 +      switch (mode) {
 +      case REGULATOR_MODE_NORMAL:
 +              val = 0;
 +              break;
 +      case REGULATOR_MODE_IDLE:
 +              val = sreg->eco_mode_mask << (ffs(sreg->eco_mode_mask) - 1);
 +              break;
 +      default:
 +              return -EINVAL;
 +      }
 +
 +      return regmap_update_bits(pmic->regmap, rdev->desc->enable_reg,
 +                                sreg->eco_mode_mask, val);
 +}
 +
 +static unsigned int
 +hi6421_spmi_regulator_get_optimum_mode(struct regulator_dev *rdev,
 +                                     int input_uV, int output_uV,
 +                                     int load_uA)
 +{
 +      struct hi6421_spmi_reg_info *sreg = rdev_get_drvdata(rdev);
 +
 +      if (!sreg->eco_uA || ((unsigned int)load_uA > sreg->eco_uA))
 +              return REGULATOR_MODE_NORMAL;
 +
 +      return REGULATOR_MODE_IDLE;
 +}
 +
 +static const struct regulator_ops hi6421_spmi_ldo_rops = {
 +      .is_enabled = regulator_is_enabled_regmap,
 +      .enable = hi6421_spmi_regulator_enable,
 +      .disable = hi6421_spmi_regulator_disable,
 +      .list_voltage = regulator_list_voltage_table,
 +      .map_voltage = regulator_map_voltage_iterate,
 +      .get_voltage_sel = regulator_get_voltage_sel_regmap,
 +      .set_voltage_sel = regulator_set_voltage_sel_regmap,
 +      .get_mode = hi6421_spmi_regulator_get_mode,
 +      .set_mode = hi6421_spmi_regulator_set_mode,
 +      .get_optimum_mode = hi6421_spmi_regulator_get_optimum_mode,
 +};
 +
 +/* HI6421v600 regulators with known registers */
 +enum hi6421_spmi_regulator_id {
 +      HI6421V600_LDO3,
 +      HI6421V600_LDO4,
 +      HI6421V600_LDO9,
 +      HI6421V600_LDO15,
 +      HI6421V600_LDO16,
 +      HI6421V600_LDO17,
 +      HI6421V600_LDO33,
 +      HI6421V600_LDO34,
 +};
 +
 +static struct hi6421_spmi_reg_info regulator_info[] = {
 +      HI6421V600_LDO(LDO3, ldo3_voltages,
 +                     0x16, 0x01, 0x51,
 +                     20000, 120,
 +                     0, 0),
 +      HI6421V600_LDO(LDO4, ldo4_voltages,
 +                     0x17, 0x01, 0x52,
 +                     20000, 120,
 +                     0x10, 10000),
 +      HI6421V600_LDO(LDO9, ldo9_voltages,
 +                     0x1c, 0x01, 0x57,
 +                     20000, 360,
 +                     0x10, 10000),
 +      HI6421V600_LDO(LDO15, ldo15_voltages,
 +                     0x21, 0x01, 0x5c,
 +                     20000, 360,
 +                     0x10, 10000),
 +      HI6421V600_LDO(LDO16, ldo15_voltages,
 +                     0x22, 0x01, 0x5d,
 +                     20000, 360,
 +                     0x10, 10000),
 +      HI6421V600_LDO(LDO17, ldo17_voltages,
 +                     0x23, 0x01, 0x5e,
 +                     20000, 120,
 +                     0x10, 10000),
 +      HI6421V600_LDO(LDO33, ldo17_voltages,
 +                     0x32, 0x01, 0x6d,
 +                     20000, 120,
 +                     0, 0),
 +      HI6421V600_LDO(LDO34, ldo34_voltages,
 +                     0x33, 0x01, 0x6e,
 +                     20000, 120,
 +                     0, 0),
 +};
 +
 +static int hi6421_spmi_regulator_probe(struct platform_device *pdev)
 +{
 +      struct device *pmic_dev = pdev->dev.parent;
 +      struct regulator_config config = { };
 +      struct hi6421_spmi_reg_info *sreg;
 +      struct hi6421_spmi_reg_info *info;
 +      struct device *dev = &pdev->dev;
 +      struct hi6421_spmi_pmic *pmic;
 +      struct regulator_dev *rdev;
 +      int i;
 +
 +      /*
 +       * This driver is meant to be called by hi6421-spmi-core,
 +       * which should first set drvdata. If this doesn't happen, hit
 +       * a warn on and return.
 +       */
 +      pmic = dev_get_drvdata(pmic_dev);
 +      if (WARN_ON(!pmic))
 +              return -ENODEV;
 +
 +      sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL);
 +      if (!sreg)
 +              return -ENOMEM;
 +
 +      sreg->pmic = pmic;
 +      mutex_init(&sreg->enable_mutex);
 +
 +      for (i = 0; i < ARRAY_SIZE(regulator_info); i++) {
 +              info = &regulator_info[i];
 +
 +              config.dev = pdev->dev.parent;
 +              config.driver_data = sreg;
 +              config.regmap = pmic->regmap;
 +
 +              rdev = devm_regulator_register(dev, &info->desc, &config);
 +              if (IS_ERR(rdev)) {
 +                      dev_err(dev, "failed to register %s\n",
 +                              info->desc.name);
 +                      return PTR_ERR(rdev);
 +              }
 +      }
 +
 +      return 0;
 +}
 +
 +static const struct platform_device_id hi6421_spmi_regulator_table[] = {
 +      { .name = "hi6421v600-regulator" },
 +      {},
 +};
 +MODULE_DEVICE_TABLE(platform, hi6421_spmi_regulator_table);
 +
 +static struct platform_driver hi6421_spmi_regulator_driver = {
 +      .id_table = hi6421_spmi_regulator_table,
 +      .driver = {
 +              .name = "hi6421v600-regulator",
 +      },
 +      .probe  = hi6421_spmi_regulator_probe,
 +};
 +module_platform_driver(hi6421_spmi_regulator_driver);
 +
 +MODULE_DESCRIPTION("Hi6421v600 SPMI regulator driver");
 +MODULE_LICENSE("GPL v2");
 +
Simple merge
Simple merge