summaryrefslogtreecommitdiff
path: root/drivers/regulator
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/88pm800.c236
-rw-r--r--drivers/regulator/Kconfig6
-rw-r--r--drivers/regulator/ad5398.c1
-rw-r--r--drivers/regulator/axp20x-regulator.c1
-rw-r--r--drivers/regulator/core.c157
-rw-r--r--drivers/regulator/da9062-regulator.c1
-rw-r--r--drivers/regulator/da9210-regulator.c75
-rw-r--r--drivers/regulator/da9211-regulator.c40
-rw-r--r--drivers/regulator/da9211-regulator.h18
-rw-r--r--drivers/regulator/fan53555.c1
-rw-r--r--drivers/regulator/isl9305.c1
-rw-r--r--drivers/regulator/lp872x.c16
-rw-r--r--drivers/regulator/ltc3589.c3
-rw-r--r--drivers/regulator/max8973-regulator.c82
-rw-r--r--drivers/regulator/pbias-regulator.c5
-rw-r--r--drivers/regulator/s2mps11.c14
16 files changed, 404 insertions, 253 deletions
diff --git a/drivers/regulator/88pm800.c b/drivers/regulator/88pm800.c
index 832932bdc977..a62a89674fb5 100644
--- a/drivers/regulator/88pm800.c
+++ b/drivers/regulator/88pm800.c
@@ -78,7 +78,6 @@ struct pm800_regulator_info {
};
struct pm800_regulators {
- struct regulator_dev *regulators[PM800_ID_RG_MAX];
struct pm80x_chip *chip;
struct regmap *map;
};
@@ -92,14 +91,16 @@ struct pm800_regulators {
* not the constant voltage table.
* n_volt - Number of available selectors
*/
-#define PM800_BUCK(vreg, ereg, ebit, amax, volt_ranges, n_volt) \
+#define PM800_BUCK(match, vreg, ereg, ebit, amax, volt_ranges, n_volt) \
{ \
.desc = { \
- .name = #vreg, \
- .ops = &pm800_volt_range_ops, \
- .type = REGULATOR_VOLTAGE, \
- .id = PM800_ID_##vreg, \
- .owner = THIS_MODULE, \
+ .name = #vreg, \
+ .of_match = of_match_ptr(#match), \
+ .regulators_node = of_match_ptr("regulators"), \
+ .ops = &pm800_volt_range_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = PM800_ID_##vreg, \
+ .owner = THIS_MODULE, \
.n_voltages = n_volt, \
.linear_ranges = volt_ranges, \
.n_linear_ranges = ARRAY_SIZE(volt_ranges), \
@@ -108,7 +109,7 @@ struct pm800_regulators {
.enable_reg = PM800_##ereg, \
.enable_mask = 1 << (ebit), \
}, \
- .max_ua = (amax), \
+ .max_ua = (amax), \
}
/*
@@ -120,22 +121,24 @@ struct pm800_regulators {
* For all the LDOes, there are too many ranges. Using volt_table will be
* simpler and faster.
*/
-#define PM800_LDO(vreg, ereg, ebit, amax, ldo_volt_table) \
+#define PM800_LDO(match, vreg, ereg, ebit, amax, ldo_volt_table) \
{ \
.desc = { \
- .name = #vreg, \
- .ops = &pm800_volt_table_ops, \
- .type = REGULATOR_VOLTAGE, \
- .id = PM800_ID_##vreg, \
- .owner = THIS_MODULE, \
- .n_voltages = ARRAY_SIZE(ldo_volt_table), \
- .vsel_reg = PM800_##vreg##_VOUT, \
- .vsel_mask = 0x1f, \
- .enable_reg = PM800_##ereg, \
- .enable_mask = 1 << (ebit), \
- .volt_table = ldo_volt_table, \
+ .name = #vreg, \
+ .of_match = of_match_ptr(#match), \
+ .regulators_node = of_match_ptr("regulators"), \
+ .ops = &pm800_volt_table_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = PM800_ID_##vreg, \
+ .owner = THIS_MODULE, \
+ .n_voltages = ARRAY_SIZE(ldo_volt_table), \
+ .vsel_reg = PM800_##vreg##_VOUT, \
+ .vsel_mask = 0xf, \
+ .enable_reg = PM800_##ereg, \
+ .enable_mask = 1 << (ebit), \
+ .volt_table = ldo_volt_table, \
}, \
- .max_ua = (amax), \
+ .max_ua = (amax), \
}
/* Ranges are sorted in ascending order. */
@@ -178,122 +181,66 @@ static int pm800_get_current_limit(struct regulator_dev *rdev)
}
static struct regulator_ops pm800_volt_range_ops = {
- .list_voltage = regulator_list_voltage_linear_range,
- .map_voltage = regulator_map_voltage_linear_range,
- .set_voltage_sel = regulator_set_voltage_sel_regmap,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
- .get_current_limit = pm800_get_current_limit,
+ .list_voltage = regulator_list_voltage_linear_range,
+ .map_voltage = regulator_map_voltage_linear_range,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .get_current_limit = pm800_get_current_limit,
};
static struct regulator_ops pm800_volt_table_ops = {
- .list_voltage = regulator_list_voltage_table,
- .map_voltage = regulator_map_voltage_iterate,
- .set_voltage_sel = regulator_set_voltage_sel_regmap,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
- .get_current_limit = pm800_get_current_limit,
+ .list_voltage = regulator_list_voltage_table,
+ .map_voltage = regulator_map_voltage_iterate,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .get_current_limit = pm800_get_current_limit,
};
/* The array is indexed by id(PM800_ID_XXX) */
static struct pm800_regulator_info pm800_regulator_info[] = {
- PM800_BUCK(BUCK1, BUCK_ENA, 0, 3000000, buck1_volt_range, 0x55),
- PM800_BUCK(BUCK2, BUCK_ENA, 1, 1200000, buck2_5_volt_range, 0x73),
- PM800_BUCK(BUCK3, BUCK_ENA, 2, 1200000, buck2_5_volt_range, 0x73),
- PM800_BUCK(BUCK4, BUCK_ENA, 3, 1200000, buck2_5_volt_range, 0x73),
- PM800_BUCK(BUCK5, BUCK_ENA, 4, 1200000, buck2_5_volt_range, 0x73),
-
- PM800_LDO(LDO1, LDO_ENA1_1, 0, 200000, ldo1_volt_table),
- PM800_LDO(LDO2, LDO_ENA1_1, 1, 10000, ldo2_volt_table),
- PM800_LDO(LDO3, LDO_ENA1_1, 2, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO4, LDO_ENA1_1, 3, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO5, LDO_ENA1_1, 4, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO6, LDO_ENA1_1, 5, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO7, LDO_ENA1_1, 6, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO8, LDO_ENA1_1, 7, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO9, LDO_ENA1_2, 0, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO10, LDO_ENA1_2, 1, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO11, LDO_ENA1_2, 2, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO12, LDO_ENA1_2, 3, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO13, LDO_ENA1_2, 4, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO14, LDO_ENA1_2, 5, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO15, LDO_ENA1_2, 6, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO16, LDO_ENA1_2, 7, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO17, LDO_ENA1_3, 0, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO18, LDO_ENA1_3, 1, 200000, ldo18_19_volt_table),
- PM800_LDO(LDO19, LDO_ENA1_3, 2, 200000, ldo18_19_volt_table),
-};
-
-#define PM800_REGULATOR_OF_MATCH(_name, _id) \
- [PM800_ID_##_id] = { \
- .name = #_name, \
- .driver_data = &pm800_regulator_info[PM800_ID_##_id], \
- }
-
-static struct of_regulator_match pm800_regulator_matches[] = {
- PM800_REGULATOR_OF_MATCH(buck1, BUCK1),
- PM800_REGULATOR_OF_MATCH(buck2, BUCK2),
- PM800_REGULATOR_OF_MATCH(buck3, BUCK3),
- PM800_REGULATOR_OF_MATCH(buck4, BUCK4),
- PM800_REGULATOR_OF_MATCH(buck5, BUCK5),
- PM800_REGULATOR_OF_MATCH(ldo1, LDO1),
- PM800_REGULATOR_OF_MATCH(ldo2, LDO2),
- PM800_REGULATOR_OF_MATCH(ldo3, LDO3),
- PM800_REGULATOR_OF_MATCH(ldo4, LDO4),
- PM800_REGULATOR_OF_MATCH(ldo5, LDO5),
- PM800_REGULATOR_OF_MATCH(ldo6, LDO6),
- PM800_REGULATOR_OF_MATCH(ldo7, LDO7),
- PM800_REGULATOR_OF_MATCH(ldo8, LDO8),
- PM800_REGULATOR_OF_MATCH(ldo9, LDO9),
- PM800_REGULATOR_OF_MATCH(ldo10, LDO10),
- PM800_REGULATOR_OF_MATCH(ldo11, LDO11),
- PM800_REGULATOR_OF_MATCH(ldo12, LDO12),
- PM800_REGULATOR_OF_MATCH(ldo13, LDO13),
- PM800_REGULATOR_OF_MATCH(ldo14, LDO14),
- PM800_REGULATOR_OF_MATCH(ldo15, LDO15),
- PM800_REGULATOR_OF_MATCH(ldo16, LDO16),
- PM800_REGULATOR_OF_MATCH(ldo17, LDO17),
- PM800_REGULATOR_OF_MATCH(ldo18, LDO18),
- PM800_REGULATOR_OF_MATCH(ldo19, LDO19),
+ PM800_BUCK(buck1, BUCK1, BUCK_ENA, 0, 3000000, buck1_volt_range, 0x55),
+ PM800_BUCK(buck2, BUCK2, BUCK_ENA, 1, 1200000, buck2_5_volt_range, 0x73),
+ PM800_BUCK(buck3, BUCK3, BUCK_ENA, 2, 1200000, buck2_5_volt_range, 0x73),
+ PM800_BUCK(buck4, BUCK4, BUCK_ENA, 3, 1200000, buck2_5_volt_range, 0x73),
+ PM800_BUCK(buck5, BUCK5, BUCK_ENA, 4, 1200000, buck2_5_volt_range, 0x73),
+
+ PM800_LDO(ldo1, LDO1, LDO_ENA1_1, 0, 200000, ldo1_volt_table),
+ PM800_LDO(ldo2, LDO2, LDO_ENA1_1, 1, 10000, ldo2_volt_table),
+ PM800_LDO(ldo3, LDO3, LDO_ENA1_1, 2, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo4, LDO4, LDO_ENA1_1, 3, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo5, LDO5, LDO_ENA1_1, 4, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo6, LDO6, LDO_ENA1_1, 5, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo7, LDO7, LDO_ENA1_1, 6, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo8, LDO8, LDO_ENA1_1, 7, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo9, LDO9, LDO_ENA1_2, 0, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo10, LDO10, LDO_ENA1_2, 1, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo11, LDO11, LDO_ENA1_2, 2, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo12, LDO12, LDO_ENA1_2, 3, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo13, LDO13, LDO_ENA1_2, 4, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo14, LDO14, LDO_ENA1_2, 5, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo15, LDO15, LDO_ENA1_2, 6, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo16, LDO16, LDO_ENA1_2, 7, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo17, LDO17, LDO_ENA1_3, 0, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo18, LDO18, LDO_ENA1_3, 1, 200000, ldo18_19_volt_table),
+ PM800_LDO(ldo19, LDO19, LDO_ENA1_3, 2, 200000, ldo18_19_volt_table),
};
-static int pm800_regulator_dt_init(struct platform_device *pdev)
-{
- struct device_node *np = pdev->dev.of_node;
- int ret;
-
- ret = of_regulator_match(&pdev->dev, np,
- pm800_regulator_matches,
- ARRAY_SIZE(pm800_regulator_matches));
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
static int pm800_regulator_probe(struct platform_device *pdev)
{
struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent);
struct pm80x_platform_data *pdata = dev_get_platdata(pdev->dev.parent);
struct pm800_regulators *pm800_data;
- struct pm800_regulator_info *info;
struct regulator_config config = { };
struct regulator_init_data *init_data;
int i, ret;
- if (!pdata || pdata->num_regulators == 0) {
- if (IS_ENABLED(CONFIG_OF)) {
- ret = pm800_regulator_dt_init(pdev);
- if (ret)
- return ret;
- } else {
- return -ENODEV;
- }
- } else if (pdata->num_regulators) {
+ if (pdata && pdata->num_regulators) {
unsigned int count = 0;
/* Check whether num_regulator is valid. */
@@ -303,8 +250,6 @@ static int pm800_regulator_probe(struct platform_device *pdev)
}
if (count != pdata->num_regulators)
return -EINVAL;
- } else {
- return -EINVAL;
}
pm800_data = devm_kzalloc(&pdev->dev, sizeof(*pm800_data),
@@ -317,30 +262,27 @@ static int pm800_regulator_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, pm800_data);
+ config.dev = chip->dev;
+ config.regmap = pm800_data->map;
for (i = 0; i < PM800_ID_RG_MAX; i++) {
- if (!pdata || pdata->num_regulators == 0)
- init_data = pm800_regulator_matches[i].init_data;
- else
+ struct regulator_dev *regulator;
+
+ if (pdata && pdata->num_regulators) {
init_data = pdata->regulators[i];
- if (!init_data)
- continue;
- info = pm800_regulator_matches[i].driver_data;
- config.dev = &pdev->dev;
- config.init_data = init_data;
- config.driver_data = info;
- config.regmap = pm800_data->map;
- config.of_node = pm800_regulator_matches[i].of_node;
-
- pm800_data->regulators[i] =
- regulator_register(&info->desc, &config);
- if (IS_ERR(pm800_data->regulators[i])) {
- ret = PTR_ERR(pm800_data->regulators[i]);
- dev_err(&pdev->dev, "Failed to register %s\n",
- info->desc.name);
+ if (!init_data)
+ continue;
- while (--i >= 0)
- regulator_unregister(pm800_data->regulators[i]);
+ config.init_data = init_data;
+ }
+
+ config.driver_data = &pm800_regulator_info[i];
+ regulator = devm_regulator_register(&pdev->dev,
+ &pm800_regulator_info[i].desc, &config);
+ if (IS_ERR(regulator)) {
+ ret = PTR_ERR(regulator);
+ dev_err(&pdev->dev, "Failed to register %s\n",
+ pm800_regulator_info[i].desc.name);
return ret;
}
}
@@ -348,23 +290,11 @@ static int pm800_regulator_probe(struct platform_device *pdev)
return 0;
}
-static int pm800_regulator_remove(struct platform_device *pdev)
-{
- struct pm800_regulators *pm800_data = platform_get_drvdata(pdev);
- int i;
-
- for (i = 0; i < PM800_ID_RG_MAX; i++)
- regulator_unregister(pm800_data->regulators[i]);
-
- return 0;
-}
-
static struct platform_driver pm800_regulator_driver = {
.driver = {
.name = "88pm80x-regulator",
},
.probe = pm800_regulator_probe,
- .remove = pm800_regulator_remove,
};
module_platform_driver(pm800_regulator_driver);
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index ed5ac9eb5063..a7b81f0185b5 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -209,13 +209,13 @@ config REGULATOR_DA9210
interface.
config REGULATOR_DA9211
- tristate "Dialog Semiconductor DA9211/DA9212/DA9213/DA9214 regulator"
+ tristate "Dialog Semiconductor DA9211/DA9212/DA9213/DA9214/DA9215 regulator"
depends on I2C
select REGMAP_I2C
help
Say y here to support for the Dialog Semiconductor DA9211/DA9212
- /DA9213/DA9214.
- The DA9211/DA9212/DA9213/DA9214 is a multi-phase synchronous
+ /DA9213/DA9214/DA9215.
+ The DA9211/DA9212/DA9213/DA9214/DA9215 is a multi-phase synchronous
step down converter 12A or 16A DC-DC Buck controlled through an I2C
interface.
diff --git a/drivers/regulator/ad5398.c b/drivers/regulator/ad5398.c
index 48016a050d5f..ea50a886ba63 100644
--- a/drivers/regulator/ad5398.c
+++ b/drivers/regulator/ad5398.c
@@ -275,4 +275,3 @@ module_exit(ad5398_exit);
MODULE_DESCRIPTION("AD5398 and AD5821 current regulator driver");
MODULE_AUTHOR("Sonic Zhang");
MODULE_LICENSE("GPL");
-MODULE_ALIAS("i2c:ad5398-regulator");
diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c
index 646829132b59..01bf3476a791 100644
--- a/drivers/regulator/axp20x-regulator.c
+++ b/drivers/regulator/axp20x-regulator.c
@@ -405,3 +405,4 @@ module_platform_driver(axp20x_regulator_driver);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
MODULE_DESCRIPTION("Regulator Driver for AXP20X PMIC");
+MODULE_ALIAS("platform:axp20x-regulator");
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index c9f72019bd68..4315476540c4 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -109,6 +109,12 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
static struct regulator *create_regulator(struct regulator_dev *rdev,
struct device *dev,
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)
{
@@ -295,7 +301,7 @@ static int regulator_check_drms(struct regulator_dev *rdev)
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;
@@ -640,6 +646,8 @@ static int drms_uA_update(struct regulator_dev *rdev)
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.
@@ -760,6 +768,8 @@ static int suspend_set_state(struct regulator_dev *rdev,
/* 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;
@@ -1105,6 +1115,9 @@ static int set_supply(struct regulator_dev *rdev,
rdev_info(rdev, "supplied by %s\n", rdev_get_name(supply_rdev));
+ if (!try_module_get(supply_rdev->owner))
+ return -ENODEV;
+
rdev->supply = create_regulator(supply_rdev, &rdev->dev, "SUPPLY");
if (rdev->supply == NULL) {
err = -ENOMEM;
@@ -1381,9 +1394,13 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
}
if (!r) {
- dev_err(dev, "Failed to resolve %s-supply for %s\n",
- rdev->supply_name, rdev->desc->name);
- return -EPROBE_DEFER;
+ if (have_full_constraints()) {
+ r = dummy_regulator_rdev;
+ } else {
+ dev_err(dev, "Failed to resolve %s-supply for %s\n",
+ rdev->supply_name, rdev->desc->name);
+ return -EPROBE_DEFER;
+ }
}
/* Recursively resolve the supply of the supply */
@@ -1398,8 +1415,11 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
/* Cascade always-on state to supply */
if (_regulator_is_enabled(rdev)) {
ret = regulator_enable(rdev->supply);
- if (ret < 0)
+ if (ret < 0) {
+ if (rdev->supply)
+ _regulator_put(rdev->supply);
return ret;
+ }
}
return 0;
@@ -1584,9 +1604,11 @@ static void _regulator_put(struct regulator *regulator)
{
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);
@@ -1595,14 +1617,15 @@ static void _regulator_put(struct regulator *regulator)
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);
}
@@ -1965,6 +1988,8 @@ static int _regulator_enable(struct regulator_dev *rdev)
{
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))
@@ -2065,6 +2090,8 @@ static int _regulator_disable(struct regulator_dev *rdev)
{
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;
@@ -2143,6 +2170,8 @@ static int _regulator_force_disable(struct regulator_dev *rdev)
{
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)
@@ -2711,7 +2740,7 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
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)) {
@@ -3439,6 +3468,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;
@@ -3583,6 +3614,9 @@ static const struct attribute_group *regulator_dev_groups[] = {
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);
}
@@ -3813,11 +3847,9 @@ void regulator_unregister(struct regulator_dev *rdev)
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);
@@ -4136,13 +4168,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
@@ -4152,58 +4228,13 @@ static int __init regulator_init_complete(void)
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;
}
diff --git a/drivers/regulator/da9062-regulator.c b/drivers/regulator/da9062-regulator.c
index dd76da09b3c7..5638fe8d759d 100644
--- a/drivers/regulator/da9062-regulator.c
+++ b/drivers/regulator/da9062-regulator.c
@@ -818,7 +818,6 @@ static int da9062_regulator_probe(struct platform_device *pdev)
static struct platform_driver da9062_regulator_driver = {
.driver = {
.name = "da9062-regulators",
- .owner = THIS_MODULE,
},
.probe = da9062_regulator_probe,
};
diff --git a/drivers/regulator/da9210-regulator.c b/drivers/regulator/da9210-regulator.c
index f0489cb9018b..8e39f7457bc3 100644
--- a/drivers/regulator/da9210-regulator.c
+++ b/drivers/regulator/da9210-regulator.c
@@ -22,6 +22,8 @@
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/slab.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
@@ -120,6 +122,55 @@ static int da9210_get_current_limit(struct regulator_dev *rdev)
return da9210_buck_limits[sel];
}
+static irqreturn_t da9210_irq_handler(int irq, void *data)
+{
+ struct da9210 *chip = data;
+ unsigned int val, handled = 0;
+ int error, ret = IRQ_NONE;
+
+ error = regmap_read(chip->regmap, DA9210_REG_EVENT_B, &val);
+ if (error < 0)
+ goto error_i2c;
+
+ if (val & DA9210_E_OVCURR) {
+ regulator_notifier_call_chain(chip->rdev,
+ REGULATOR_EVENT_OVER_CURRENT,
+ NULL);
+ handled |= DA9210_E_OVCURR;
+ }
+ if (val & DA9210_E_NPWRGOOD) {
+ regulator_notifier_call_chain(chip->rdev,
+ REGULATOR_EVENT_UNDER_VOLTAGE,
+ NULL);
+ handled |= DA9210_E_NPWRGOOD;
+ }
+ if (val & (DA9210_E_TEMP_WARN | DA9210_E_TEMP_CRIT)) {
+ regulator_notifier_call_chain(chip->rdev,
+ REGULATOR_EVENT_OVER_TEMP, NULL);
+ handled |= val & (DA9210_E_TEMP_WARN | DA9210_E_TEMP_CRIT);
+ }
+ if (val & DA9210_E_VMAX) {
+ regulator_notifier_call_chain(chip->rdev,
+ REGULATOR_EVENT_REGULATION_OUT,
+ NULL);
+ handled |= DA9210_E_VMAX;
+ }
+ if (handled) {
+ /* Clear handled events */
+ error = regmap_write(chip->regmap, DA9210_REG_EVENT_B, handled);
+ if (error < 0)
+ goto error_i2c;
+
+ ret = IRQ_HANDLED;
+ }
+
+ return ret;
+
+error_i2c:
+ dev_err(regmap_get_device(chip->regmap), "I2C error : %d\n", error);
+ return ret;
+}
+
/*
* I2C driver interface functions
*/
@@ -168,6 +219,30 @@ static int da9210_i2c_probe(struct i2c_client *i2c,
}
chip->rdev = rdev;
+ if (i2c->irq) {
+ error = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL,
+ da9210_irq_handler,
+ IRQF_TRIGGER_LOW |
+ IRQF_ONESHOT | IRQF_SHARED,
+ "da9210", chip);
+ if (error) {
+ dev_err(&i2c->dev, "Failed to request IRQ%u: %d\n",
+ i2c->irq, error);
+ return error;
+ }
+
+ error = regmap_update_bits(chip->regmap, DA9210_REG_MASK_B,
+ DA9210_M_OVCURR | DA9210_M_NPWRGOOD |
+ DA9210_M_TEMP_WARN |
+ DA9210_M_TEMP_CRIT | DA9210_M_VMAX, 0);
+ if (error < 0) {
+ dev_err(&i2c->dev, "Failed to update mask reg: %d\n",
+ error);
+ return error;
+ }
+ } else {
+ dev_warn(&i2c->dev, "No IRQ configured\n");
+ }
i2c_set_clientdata(i2c, chip);
diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c
index df79e4b1946e..0858100d2d03 100644
--- a/drivers/regulator/da9211-regulator.c
+++ b/drivers/regulator/da9211-regulator.c
@@ -1,6 +1,6 @@
/*
- * da9211-regulator.c - Regulator device driver for DA9211/DA9213
- * Copyright (C) 2014 Dialog Semiconductor Ltd.
+ * da9211-regulator.c - Regulator device driver for DA9211/DA9213/DA9215
+ * Copyright (C) 2015 Dialog Semiconductor Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -32,6 +32,7 @@
/* DEVICE IDs */
#define DA9211_DEVICE_ID 0x22
#define DA9213_DEVICE_ID 0x23
+#define DA9215_DEVICE_ID 0x24
#define DA9211_BUCK_MODE_SLEEP 1
#define DA9211_BUCK_MODE_SYNC 2
@@ -90,6 +91,13 @@ static const int da9213_current_limits[] = {
3000000, 3200000, 3400000, 3600000, 3800000, 4000000, 4200000, 4400000,
4600000, 4800000, 5000000, 5200000, 5400000, 5600000, 5800000, 6000000
};
+/* Current limits for DA9215 buck (uA) indices
+ * corresponds with register values
+ */
+static const int da9215_current_limits[] = {
+ 4000000, 4200000, 4400000, 4600000, 4800000, 5000000, 5200000, 5400000,
+ 5600000, 5800000, 6000000, 6200000, 6400000, 6600000, 6800000, 7000000
+};
static unsigned int da9211_buck_get_mode(struct regulator_dev *rdev)
{
@@ -157,6 +165,10 @@ static int da9211_set_current_limit(struct regulator_dev *rdev, int min,
current_limits = da9213_current_limits;
max_size = ARRAY_SIZE(da9213_current_limits)-1;
break;
+ case DA9215:
+ current_limits = da9215_current_limits;
+ max_size = ARRAY_SIZE(da9215_current_limits)-1;
+ break;
default:
return -EINVAL;
}
@@ -189,6 +201,9 @@ static int da9211_get_current_limit(struct regulator_dev *rdev)
case DA9213:
current_limits = da9213_current_limits;
break;
+ case DA9215:
+ current_limits = da9215_current_limits;
+ break;
default:
return -EINVAL;
}
@@ -350,13 +365,11 @@ static int da9211_regulator_init(struct da9211 *chip)
/* If configuration for 1/2 bucks is different between platform data
* and the register, driver should exit.
*/
- if ((chip->pdata->num_buck == 2 && data == 0x40)
- || (chip->pdata->num_buck == 1 && data == 0x00)) {
- if (data == 0)
- chip->num_regulator = 1;
- else
- chip->num_regulator = 2;
- } else {
+ if (chip->pdata->num_buck == 1 && data == 0x00)
+ chip->num_regulator = 1;
+ else if (chip->pdata->num_buck == 2 && data != 0x00)
+ chip->num_regulator = 2;
+ else {
dev_err(chip->dev, "Configuration is mismatched\n");
return -EINVAL;
}
@@ -438,6 +451,9 @@ static int da9211_i2c_probe(struct i2c_client *i2c,
case DA9213_DEVICE_ID:
chip->chip_id = DA9213;
break;
+ case DA9215_DEVICE_ID:
+ chip->chip_id = DA9215;
+ break;
default:
dev_err(chip->dev, "Unsupported device id = 0x%x.\n", data);
return -ENODEV;
@@ -478,6 +494,7 @@ static int da9211_i2c_probe(struct i2c_client *i2c,
static const struct i2c_device_id da9211_i2c_id[] = {
{"da9211", DA9211},
{"da9213", DA9213},
+ {"da9215", DA9215},
{},
};
MODULE_DEVICE_TABLE(i2c, da9211_i2c_id);
@@ -486,6 +503,7 @@ MODULE_DEVICE_TABLE(i2c, da9211_i2c_id);
static const struct of_device_id da9211_dt_ids[] = {
{ .compatible = "dlg,da9211", .data = &da9211_i2c_id[0] },
{ .compatible = "dlg,da9213", .data = &da9211_i2c_id[1] },
+ { .compatible = "dlg,da9215", .data = &da9211_i2c_id[2] },
{},
};
MODULE_DEVICE_TABLE(of, da9211_dt_ids);
@@ -504,5 +522,5 @@ static struct i2c_driver da9211_regulator_driver = {
module_i2c_driver(da9211_regulator_driver);
MODULE_AUTHOR("James Ban <James.Ban.opensource@diasemi.com>");
-MODULE_DESCRIPTION("Regulator device driver for Dialog DA9211/DA9213");
-MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Regulator device driver for Dialog DA9211/DA9213/DA9215");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/da9211-regulator.h b/drivers/regulator/da9211-regulator.h
index 93fa9df2721c..d6ad96fc64d3 100644
--- a/drivers/regulator/da9211-regulator.h
+++ b/drivers/regulator/da9211-regulator.h
@@ -1,16 +1,16 @@
/*
- * da9211-regulator.h - Regulator definitions for DA9211/DA9213
- * Copyright (C) 2014 Dialog Semiconductor Ltd.
+ * da9211-regulator.h - Regulator definitions for DA9211/DA9213/DA9215
+ * Copyright (C) 2015 Dialog Semiconductor Ltd.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
*
- * This library is distributed in the hope that it will be useful,
+ * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*/
#ifndef __DA9211_REGISTERS_H__
diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c
index 42865681c00b..4940e8287df6 100644
--- a/drivers/regulator/fan53555.c
+++ b/drivers/regulator/fan53555.c
@@ -439,6 +439,7 @@ static const struct i2c_device_id fan53555_id[] = {
},
{ },
};
+MODULE_DEVICE_TABLE(i2c, fan53555_id);
static struct i2c_driver fan53555_regulator_driver = {
.driver = {
diff --git a/drivers/regulator/isl9305.c b/drivers/regulator/isl9305.c
index 6e3a15fe00f1..e02e9a9dddbd 100644
--- a/drivers/regulator/isl9305.c
+++ b/drivers/regulator/isl9305.c
@@ -183,6 +183,7 @@ static const struct of_device_id isl9305_dt_ids[] = {
{ .compatible = "isil,isl9305h" },
{},
};
+MODULE_DEVICE_TABLE(of, isl9305_dt_ids);
#endif
static const struct i2c_device_id isl9305_i2c_id[] = {
diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c
index 3de328ab41f3..8702e7384af7 100644
--- a/drivers/regulator/lp872x.c
+++ b/drivers/regulator/lp872x.c
@@ -849,7 +849,7 @@ static struct lp872x_platform_data
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
- goto out;
+ return ERR_PTR(-ENOMEM);
of_property_read_u8(np, "ti,general-config", &pdata->general_config);
if (of_find_property(np, "ti,update-config", NULL))
@@ -857,7 +857,7 @@ static struct lp872x_platform_data
pdata->dvs = devm_kzalloc(dev, sizeof(struct lp872x_dvs), GFP_KERNEL);
if (!pdata->dvs)
- goto out;
+ return ERR_PTR(-ENOMEM);
pdata->dvs->gpio = of_get_named_gpio(np, "ti,dvs-gpio", 0);
of_property_read_u8(np, "ti,dvs-vsel", (u8 *)&pdata->dvs->vsel);
@@ -903,15 +903,21 @@ static struct lp872x_platform_data
static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
{
struct lp872x *lp;
+ struct lp872x_platform_data *pdata;
int ret;
const int lp872x_num_regulators[] = {
[LP8720] = LP8720_NUM_REGULATORS,
[LP8725] = LP8725_NUM_REGULATORS,
};
- if (cl->dev.of_node)
- cl->dev.platform_data = lp872x_populate_pdata_from_dt(&cl->dev,
+ if (cl->dev.of_node) {
+ pdata = lp872x_populate_pdata_from_dt(&cl->dev,
(enum lp872x_id)id->driver_data);
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
+ } else {
+ pdata = dev_get_platdata(&cl->dev);
+ }
lp = devm_kzalloc(&cl->dev, sizeof(struct lp872x), GFP_KERNEL);
if (!lp)
@@ -927,7 +933,7 @@ static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
}
lp->dev = &cl->dev;
- lp->pdata = dev_get_platdata(&cl->dev);
+ lp->pdata = pdata;
lp->chipid = id->driver_data;
i2c_set_clientdata(cl, lp);
diff --git a/drivers/regulator/ltc3589.c b/drivers/regulator/ltc3589.c
index 0ce8e4e0fa73..cc22ac66c8fd 100644
--- a/drivers/regulator/ltc3589.c
+++ b/drivers/regulator/ltc3589.c
@@ -378,7 +378,7 @@ static bool ltc3589_volatile_reg(struct device *dev, unsigned int reg)
return false;
}
-static struct reg_default ltc3589_reg_defaults[] = {
+static const struct reg_default ltc3589_reg_defaults[] = {
{ LTC3589_SCR1, 0x00 },
{ LTC3589_OVEN, 0x00 },
{ LTC3589_SCR2, 0x00 },
@@ -552,4 +552,3 @@ module_i2c_driver(ltc3589_driver);
MODULE_AUTHOR("Philipp Zabel <p.zabel@pengutronix.de>");
MODULE_DESCRIPTION("Regulator driver for Linear Technology LTC3589(-1,2)");
MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("i2c:ltc3589");
diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c
index 6f2bdad8b4d8..8857cc02d9a8 100644
--- a/drivers/regulator/max8973-regulator.c
+++ b/drivers/regulator/max8973-regulator.c
@@ -75,6 +75,7 @@
#define MAX8973_DISCH_ENBABLE BIT(5)
#define MAX8973_FT_ENABLE BIT(4)
+#define MAX8973_CKKADV_TRIP_MASK 0xC
#define MAX8973_CKKADV_TRIP_DISABLE 0xC
#define MAX8973_CKKADV_TRIP_75mV_PER_US 0x0
#define MAX8973_CKKADV_TRIP_150mV_PER_US 0x4
@@ -282,6 +283,55 @@ static int max8973_set_ramp_delay(struct regulator_dev *rdev,
return ret;
}
+static int max8973_set_current_limit(struct regulator_dev *rdev,
+ int min_ua, int max_ua)
+{
+ struct max8973_chip *max = rdev_get_drvdata(rdev);
+ unsigned int val;
+ int ret;
+
+ if (max_ua <= 9000000)
+ val = MAX8973_CKKADV_TRIP_75mV_PER_US;
+ else if (max_ua <= 12000000)
+ val = MAX8973_CKKADV_TRIP_150mV_PER_US;
+ else
+ val = MAX8973_CKKADV_TRIP_DISABLE;
+
+ ret = regmap_update_bits(max->regmap, MAX8973_CONTROL2,
+ MAX8973_CKKADV_TRIP_MASK, val);
+ if (ret < 0) {
+ dev_err(max->dev, "register %d update failed: %d\n",
+ MAX8973_CONTROL2, ret);
+ return ret;
+ }
+ return 0;
+}
+
+static int max8973_get_current_limit(struct regulator_dev *rdev)
+{
+ struct max8973_chip *max = rdev_get_drvdata(rdev);
+ unsigned int control2;
+ int ret;
+
+ ret = regmap_read(max->regmap, MAX8973_CONTROL2, &control2);
+ if (ret < 0) {
+ dev_err(max->dev, "register %d read failed: %d\n",
+ MAX8973_CONTROL2, ret);
+ return ret;
+ }
+ switch (control2 & MAX8973_CKKADV_TRIP_MASK) {
+ case MAX8973_CKKADV_TRIP_DISABLE:
+ return 15000000;
+ case MAX8973_CKKADV_TRIP_150mV_PER_US:
+ return 12000000;
+ case MAX8973_CKKADV_TRIP_75mV_PER_US:
+ return 9000000;
+ default:
+ break;
+ }
+ return 9000000;
+}
+
static const struct regulator_ops max8973_dcdc_ops = {
.get_voltage_sel = max8973_dcdc_get_voltage_sel,
.set_voltage_sel = max8973_dcdc_set_voltage_sel,
@@ -421,6 +471,8 @@ static struct max8973_regulator_platform_data *max8973_parse_dt(
struct device_node *np = dev->of_node;
int ret;
u32 pval;
+ bool etr_enable;
+ bool etr_sensitivity_high;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
@@ -450,7 +502,24 @@ static struct max8973_regulator_platform_data *max8973_parse_dt(
pdata->control_flags |= MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE;
if (of_property_read_bool(np, "maxim,enable-bias-control"))
- pdata->control_flags |= MAX8973_BIAS_ENABLE;
+ pdata->control_flags |= MAX8973_CONTROL_BIAS_ENABLE;
+
+ etr_enable = of_property_read_bool(np, "maxim,enable-etr");
+ etr_sensitivity_high = of_property_read_bool(np,
+ "maxim,enable-high-etr-sensitivity");
+ if (etr_sensitivity_high)
+ etr_enable = true;
+
+ if (etr_enable) {
+ if (etr_sensitivity_high)
+ pdata->control_flags |=
+ MAX8973_CONTROL_CLKADV_TRIP_75mV_PER_US;
+ else
+ pdata->control_flags |=
+ MAX8973_CONTROL_CLKADV_TRIP_150mV_PER_US;
+ } else {
+ pdata->control_flags |= MAX8973_CONTROL_CLKADV_TRIP_DISABLED;
+ }
return pdata;
}
@@ -568,6 +637,15 @@ static int max8973_probe(struct i2c_client *client,
max->lru_index[i] = i;
max->lru_index[0] = max->curr_vout_reg;
max->lru_index[max->curr_vout_reg] = 0;
+ } else {
+ /*
+ * If there is no DVS GPIO, the VOUT register
+ * address is fixed.
+ */
+ max->ops.set_voltage_sel = regulator_set_voltage_sel_regmap;
+ max->ops.get_voltage_sel = regulator_get_voltage_sel_regmap;
+ max->desc.vsel_reg = max->curr_vout_reg;
+ max->desc.vsel_mask = MAX8973_VOUT_MASK;
}
if (pdata_from_dt)
@@ -613,6 +691,8 @@ static int max8973_probe(struct i2c_client *client,
max->ops.enable = regulator_enable_regmap;
max->ops.disable = regulator_disable_regmap;
max->ops.is_enabled = regulator_is_enabled_regmap;
+ max->ops.set_current_limit = max8973_set_current_limit;
+ max->ops.get_current_limit = max8973_get_current_limit;
break;
default:
break;
diff --git a/drivers/regulator/pbias-regulator.c b/drivers/regulator/pbias-regulator.c
index bd2b75c0d1d1..4fa7bcaf454e 100644
--- a/drivers/regulator/pbias-regulator.c
+++ b/drivers/regulator/pbias-regulator.c
@@ -30,6 +30,7 @@
struct pbias_reg_info {
u32 enable;
u32 enable_mask;
+ u32 disable_val;
u32 vmode;
unsigned int enable_time;
char *name;
@@ -62,6 +63,7 @@ static const struct pbias_reg_info pbias_mmc_omap2430 = {
.enable = BIT(1),
.enable_mask = BIT(1),
.vmode = BIT(0),
+ .disable_val = 0,
.enable_time = 100,
.name = "pbias_mmc_omap2430"
};
@@ -77,6 +79,7 @@ static const struct pbias_reg_info pbias_sim_omap3 = {
static const struct pbias_reg_info pbias_mmc_omap4 = {
.enable = BIT(26) | BIT(22),
.enable_mask = BIT(26) | BIT(25) | BIT(22),
+ .disable_val = BIT(25),
.vmode = BIT(21),
.enable_time = 100,
.name = "pbias_mmc_omap4"
@@ -85,6 +88,7 @@ static const struct pbias_reg_info pbias_mmc_omap4 = {
static const struct pbias_reg_info pbias_mmc_omap5 = {
.enable = BIT(27) | BIT(26),
.enable_mask = BIT(27) | BIT(25) | BIT(26),
+ .disable_val = BIT(25),
.vmode = BIT(21),
.enable_time = 100,
.name = "pbias_mmc_omap5"
@@ -159,6 +163,7 @@ static int pbias_regulator_probe(struct platform_device *pdev)
drvdata[data_idx].desc.enable_reg = res->start;
drvdata[data_idx].desc.enable_mask = info->enable_mask;
drvdata[data_idx].desc.enable_val = info->enable;
+ drvdata[data_idx].desc.disable_val = info->disable_val;
cfg.init_data = pbias_matches[idx].init_data;
cfg.driver_data = &drvdata[data_idx];
diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c
index 326ffb553371..72fc3c32db49 100644
--- a/drivers/regulator/s2mps11.c
+++ b/drivers/regulator/s2mps11.c
@@ -34,6 +34,8 @@
#include <linux/mfd/samsung/s2mps14.h>
#include <linux/mfd/samsung/s2mpu02.h>
+/* The highest number of possible regulators for supported devices. */
+#define S2MPS_REGULATOR_MAX S2MPS13_REGULATOR_MAX
struct s2mps11_info {
unsigned int rdev_num;
int ramp_delay2;
@@ -49,7 +51,7 @@ struct s2mps11_info {
* One bit for each S2MPS13/S2MPS14/S2MPU02 regulator whether
* the suspend mode was enabled.
*/
- unsigned long long s2mps14_suspend_state:50;
+ DECLARE_BITMAP(suspend_state, S2MPS_REGULATOR_MAX);
/* Array of size rdev_num with GPIO-s for external sleep control */
int *ext_control_gpio;
@@ -500,7 +502,7 @@ static int s2mps14_regulator_enable(struct regulator_dev *rdev)
switch (s2mps11->dev_type) {
case S2MPS13X:
case S2MPS14X:
- if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev)))
+ if (test_bit(rdev_get_id(rdev), s2mps11->suspend_state))
val = S2MPS14_ENABLE_SUSPEND;
else if (gpio_is_valid(s2mps11->ext_control_gpio[rdev_get_id(rdev)]))
val = S2MPS14_ENABLE_EXT_CONTROL;
@@ -508,7 +510,7 @@ static int s2mps14_regulator_enable(struct regulator_dev *rdev)
val = rdev->desc->enable_mask;
break;
case S2MPU02:
- if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev)))
+ if (test_bit(rdev_get_id(rdev), s2mps11->suspend_state))
val = S2MPU02_ENABLE_SUSPEND;
else
val = rdev->desc->enable_mask;
@@ -562,7 +564,7 @@ static int s2mps14_regulator_set_suspend_disable(struct regulator_dev *rdev)
if (ret < 0)
return ret;
- s2mps11->s2mps14_suspend_state |= (1 << rdev_get_id(rdev));
+ set_bit(rdev_get_id(rdev), s2mps11->suspend_state);
/*
* Don't enable suspend mode if regulator is already disabled because
* this would effectively for a short time turn on the regulator after
@@ -960,18 +962,22 @@ static int s2mps11_pmic_probe(struct platform_device *pdev)
case S2MPS11X:
s2mps11->rdev_num = ARRAY_SIZE(s2mps11_regulators);
regulators = s2mps11_regulators;
+ BUILD_BUG_ON(S2MPS_REGULATOR_MAX < s2mps11->rdev_num);
break;
case S2MPS13X:
s2mps11->rdev_num = ARRAY_SIZE(s2mps13_regulators);
regulators = s2mps13_regulators;
+ BUILD_BUG_ON(S2MPS_REGULATOR_MAX < s2mps11->rdev_num);
break;
case S2MPS14X:
s2mps11->rdev_num = ARRAY_SIZE(s2mps14_regulators);
regulators = s2mps14_regulators;
+ BUILD_BUG_ON(S2MPS_REGULATOR_MAX < s2mps11->rdev_num);
break;
case S2MPU02:
s2mps11->rdev_num = ARRAY_SIZE(s2mpu02_regulators);
regulators = s2mpu02_regulators;
+ BUILD_BUG_ON(S2MPS_REGULATOR_MAX < s2mps11->rdev_num);
break;
default:
dev_err(&pdev->dev, "Invalid device type: %u\n",