diff options
Diffstat (limited to 'drivers')
33 files changed, 451 insertions, 215 deletions
diff --git a/drivers/gpio/gpiolib-devres.c b/drivers/gpio/gpiolib-devres.c index 98e3c20d9730..4421be09b960 100644 --- a/drivers/gpio/gpiolib-devres.c +++ b/drivers/gpio/gpiolib-devres.c @@ -185,12 +185,11 @@ struct gpio_desc *devm_gpiod_get_from_of_node(struct device *dev, EXPORT_SYMBOL_GPL(devm_gpiod_get_from_of_node); /** - * devm_fwnode_get_index_gpiod_from_child - get a GPIO descriptor from a - * device's child node + * devm_fwnode_gpiod_get_index - get a GPIO descriptor from a given node * @dev: GPIO consumer + * @fwnode: firmware node containing GPIO reference * @con_id: function within the GPIO consumer * @index: index of the GPIO to obtain in the consumer - * @child: firmware node (child of @dev) * @flags: GPIO initialization flags * @label: label to attach to the requested GPIO * @@ -200,35 +199,21 @@ EXPORT_SYMBOL_GPL(devm_gpiod_get_from_of_node); * On successful request the GPIO pin is configured in accordance with * provided @flags. */ -struct gpio_desc *devm_fwnode_get_index_gpiod_from_child(struct device *dev, - const char *con_id, int index, - struct fwnode_handle *child, - enum gpiod_flags flags, - const char *label) +struct gpio_desc *devm_fwnode_gpiod_get_index(struct device *dev, + struct fwnode_handle *fwnode, + const char *con_id, int index, + enum gpiod_flags flags, + const char *label) { - char prop_name[32]; /* 32 is max size of property name */ struct gpio_desc **dr; struct gpio_desc *desc; - unsigned int i; dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *), GFP_KERNEL); if (!dr) return ERR_PTR(-ENOMEM); - for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) { - if (con_id) - snprintf(prop_name, sizeof(prop_name), "%s-%s", - con_id, gpio_suffixes[i]); - else - snprintf(prop_name, sizeof(prop_name), "%s", - gpio_suffixes[i]); - - desc = fwnode_get_named_gpiod(child, prop_name, index, flags, - label); - if (!IS_ERR(desc) || (PTR_ERR(desc) != -ENOENT)) - break; - } + desc = fwnode_gpiod_get_index(fwnode, con_id, index, flags, label); if (IS_ERR(desc)) { devres_free(dr); return desc; @@ -239,7 +224,7 @@ struct gpio_desc *devm_fwnode_get_index_gpiod_from_child(struct device *dev, return desc; } -EXPORT_SYMBOL_GPL(devm_fwnode_get_index_gpiod_from_child); +EXPORT_SYMBOL_GPL(devm_fwnode_gpiod_get_index); /** * devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional() diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 104ed299d5ea..fb33ff6fc1a9 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -4356,6 +4356,54 @@ static int platform_gpio_count(struct device *dev, const char *con_id) } /** + * fwnode_gpiod_get_index - obtain a GPIO from firmware node + * @fwnode: handle of the firmware node + * @con_id: function within the GPIO consumer + * @index: index of the GPIO to obtain for the consumer + * @flags: GPIO initialization flags + * @label: label to attach to the requested GPIO + * + * This function can be used for drivers that get their configuration + * from opaque firmware. + * + * The function properly finds the corresponding GPIO using whatever is the + * underlying firmware interface and then makes sure that the GPIO + * descriptor is requested before it is returned to the caller. + * + * Returns: + * On successful request the GPIO pin is configured in accordance with + * provided @flags. + * + * In case of error an ERR_PTR() is returned. + */ +struct gpio_desc *fwnode_gpiod_get_index(struct fwnode_handle *fwnode, + const char *con_id, int index, + enum gpiod_flags flags, + const char *label) +{ + struct gpio_desc *desc; + char prop_name[32]; /* 32 is max size of property name */ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) { + if (con_id) + snprintf(prop_name, sizeof(prop_name), "%s-%s", + con_id, gpio_suffixes[i]); + else + snprintf(prop_name, sizeof(prop_name), "%s", + gpio_suffixes[i]); + + desc = fwnode_get_named_gpiod(fwnode, prop_name, index, flags, + label); + if (!IS_ERR(desc) || (PTR_ERR(desc) != -ENOENT)) + break; + } + + return desc; +} +EXPORT_SYMBOL_GPL(fwnode_gpiod_get_index); + +/** * gpiod_count - return the number of GPIOs associated with a device / function * or -ENOENT if no GPIO has been assigned to the requested function * @dev: GPIO consumer, can be NULL for system-global GPIOs diff --git a/drivers/mfd/tps6105x.c b/drivers/mfd/tps6105x.c index 6ac3607a79c2..c906324d293e 100644 --- a/drivers/mfd/tps6105x.c +++ b/drivers/mfd/tps6105x.c @@ -91,6 +91,32 @@ static int tps6105x_add_device(struct tps6105x *tps6105x, PLATFORM_DEVID_AUTO, cell, 1, NULL, 0, NULL); } +static struct tps6105x_platform_data *tps6105x_parse_dt(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct tps6105x_platform_data *pdata; + struct device_node *child; + + if (!np) + return ERR_PTR(-EINVAL); + if (of_get_available_child_count(np) > 1) { + dev_err(dev, "cannot support multiple operational modes"); + return ERR_PTR(-EINVAL); + } + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); + pdata->mode = TPS6105X_MODE_SHUTDOWN; + for_each_available_child_of_node(np, child) { + if (child->name && !of_node_cmp(child->name, "regulator")) + pdata->mode = TPS6105X_MODE_VOLTAGE; + else if (child->name && !of_node_cmp(child->name, "led")) + pdata->mode = TPS6105X_MODE_TORCH; + } + + return pdata; +} + static int tps6105x_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -99,9 +125,11 @@ static int tps6105x_probe(struct i2c_client *client, int ret; pdata = dev_get_platdata(&client->dev); - if (!pdata) { - dev_err(&client->dev, "missing platform data\n"); - return -ENODEV; + if (!pdata) + pdata = tps6105x_parse_dt(&client->dev); + if (IS_ERR(pdata)) { + dev_err(&client->dev, "No platform data or DT found"); + return PTR_ERR(pdata); } tps6105x = devm_kmalloc(&client->dev, sizeof(*tps6105x), GFP_KERNEL); diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 3ee63531f6d5..74eb5af7295f 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -841,10 +841,10 @@ config REGULATOR_SKY81452 will be called sky81452-regulator. config REGULATOR_SLG51000 - tristate "Dialog Semiconductor SLG51000 regulators" - depends on I2C - select REGMAP_I2C - help + tristate "Dialog Semiconductor SLG51000 regulators" + depends on I2C + select REGMAP_I2C + help Say y here to support for the Dialog Semiconductor SLG51000. The SLG51000 is seven compact and customizable low dropout regulators. diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index efb2f01a9101..f60e1b26c2d2 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -953,23 +953,6 @@ static struct ab8500_regulator_info .update_val_idle = 0x82, .update_val_normal = 0x02, }, - [AB8505_LDO_USB] = { - .desc = { - .name = "LDO-USB", - .ops = &ab8500_regulator_mode_ops, - .type = REGULATOR_VOLTAGE, - .id = AB8505_LDO_USB, - .owner = THIS_MODULE, - .n_voltages = 1, - .volt_table = fixed_3300000_voltage, - }, - .update_bank = 0x03, - .update_reg = 0x82, - .update_mask = 0x03, - .update_val = 0x01, - .update_val_idle = 0x03, - .update_val_normal = 0x01, - }, [AB8505_LDO_AUDIO] = { .desc = { .name = "LDO-AUDIO", diff --git a/drivers/regulator/bd70528-regulator.c b/drivers/regulator/bd70528-regulator.c index 0248a61f1006..ec764022621f 100644 --- a/drivers/regulator/bd70528-regulator.c +++ b/drivers/regulator/bd70528-regulator.c @@ -286,3 +286,4 @@ module_platform_driver(bd70528_regulator); MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); MODULE_DESCRIPTION("BD70528 voltage regulator driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:bd70528-pmic"); diff --git a/drivers/regulator/bd718x7-regulator.c b/drivers/regulator/bd718x7-regulator.c index bdab46a5c461..13a43eee2e46 100644 --- a/drivers/regulator/bd718x7-regulator.c +++ b/drivers/regulator/bd718x7-regulator.c @@ -1293,3 +1293,4 @@ module_platform_driver(bd718xx_regulator); MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); MODULE_DESCRIPTION("BD71837/BD71847 voltage regulator driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:bd718xx-pmic"); diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index a46be221dbdc..679ad3d2ed23 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1403,7 +1403,9 @@ static int set_machine_constraints(struct regulator_dev *rdev, rdev_err(rdev, "failed to enable\n"); return ret; } - rdev->use_count++; + + if (rdev->constraints->always_on) + rdev->use_count++; } print_constraints(rdev); @@ -1844,6 +1846,7 @@ struct regulator *_regulator_get(struct device *dev, const char *id, struct regulator_dev *rdev; struct regulator *regulator; const char *devname = dev ? dev_name(dev) : "deviceless"; + struct device_link *link; int ret; if (get_type >= MAX_GET_TYPE) { @@ -1951,7 +1954,9 @@ struct regulator *_regulator_get(struct device *dev, const char *id, rdev->use_count = 0; } - device_link_add(dev, &rdev->dev, DL_FLAG_STATELESS); + link = device_link_add(dev, &rdev->dev, DL_FLAG_STATELESS); + if (!IS_ERR_OR_NULL(link)) + regulator->device_link = true; return regulator; } @@ -2046,7 +2051,8 @@ static void _regulator_put(struct regulator *regulator) debugfs_remove_recursive(regulator->debugfs); if (regulator->dev) { - device_link_remove(regulator->dev, &rdev->dev); + if (regulator->device_link) + device_link_remove(regulator->dev, &rdev->dev); /* remove any sysfs entries */ sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name); @@ -4963,6 +4969,12 @@ static int generic_coupler_attach(struct regulator_coupler *coupler, return -EPERM; } + if (!rdev->constraints->always_on) { + rdev_err(rdev, + "Coupling of a non always-on regulator is unimplemented\n"); + return -ENOTSUPP; + } + return 0; } @@ -5198,6 +5210,7 @@ unset_supplies: regulator_remove_coupling(rdev); mutex_unlock(®ulator_list_mutex); wash: + kfree(rdev->coupling_desc.coupled_rdevs); kfree(rdev->constraints); mutex_lock(®ulator_list_mutex); regulator_ena_gpio_free(rdev); diff --git a/drivers/regulator/da9062-regulator.c b/drivers/regulator/da9062-regulator.c index 710e67081d53..d3ce0278bfbe 100644 --- a/drivers/regulator/da9062-regulator.c +++ b/drivers/regulator/da9062-regulator.c @@ -16,6 +16,7 @@ #include <linux/regulator/of_regulator.h> #include <linux/mfd/da9062/core.h> #include <linux/mfd/da9062/registers.h> +#include <dt-bindings/regulator/dlg,da9063-regulator.h> /* Regulator IDs */ enum { @@ -75,14 +76,6 @@ struct da9062_regulators { struct da9062_regulator regulator[0]; }; -/* BUCK modes */ -enum { - BUCK_MODE_MANUAL, /* 0 */ - BUCK_MODE_SLEEP, /* 1 */ - BUCK_MODE_SYNC, /* 2 */ - BUCK_MODE_AUTO /* 3 */ -}; - /* Regulator operations */ /* Current limits array (in uA) @@ -105,6 +98,20 @@ static const unsigned int da9062_buck_b_limits[] = { 2300000, 2400000, 2500000, 2600000, 2700000, 2800000, 2900000, 3000000 }; +static unsigned int da9062_map_buck_mode(unsigned int mode) +{ + switch (mode) { + case DA9063_BUCK_MODE_SLEEP: + return REGULATOR_MODE_STANDBY; + case DA9063_BUCK_MODE_SYNC: + return REGULATOR_MODE_FAST; + case DA9063_BUCK_MODE_AUTO: + return REGULATOR_MODE_NORMAL; + default: + return REGULATOR_MODE_INVALID; + } +} + static int da9062_buck_set_mode(struct regulator_dev *rdev, unsigned mode) { struct da9062_regulator *regl = rdev_get_drvdata(rdev); @@ -112,13 +119,13 @@ static int da9062_buck_set_mode(struct regulator_dev *rdev, unsigned mode) switch (mode) { case REGULATOR_MODE_FAST: - val = BUCK_MODE_SYNC; + val = DA9063_BUCK_MODE_SYNC; break; case REGULATOR_MODE_NORMAL: - val = BUCK_MODE_AUTO; + val = DA9063_BUCK_MODE_AUTO; break; case REGULATOR_MODE_STANDBY: - val = BUCK_MODE_SLEEP; + val = DA9063_BUCK_MODE_SLEEP; break; default: return -EINVAL; @@ -136,7 +143,7 @@ static int da9062_buck_set_mode(struct regulator_dev *rdev, unsigned mode) static unsigned da9062_buck_get_mode(struct regulator_dev *rdev) { struct da9062_regulator *regl = rdev_get_drvdata(rdev); - unsigned int val, mode = 0; + unsigned int val; int ret; ret = regmap_field_read(regl->mode, &val); @@ -145,15 +152,13 @@ static unsigned da9062_buck_get_mode(struct regulator_dev *rdev) switch (val) { default: - case BUCK_MODE_MANUAL: - mode = REGULATOR_MODE_FAST | REGULATOR_MODE_STANDBY; /* Sleep flag bit decides the mode */ break; - case BUCK_MODE_SLEEP: + case DA9063_BUCK_MODE_SLEEP: return REGULATOR_MODE_STANDBY; - case BUCK_MODE_SYNC: + case DA9063_BUCK_MODE_SYNC: return REGULATOR_MODE_FAST; - case BUCK_MODE_AUTO: + case DA9063_BUCK_MODE_AUTO: return REGULATOR_MODE_NORMAL; } @@ -162,11 +167,9 @@ static unsigned da9062_buck_get_mode(struct regulator_dev *rdev) return 0; if (val) - mode &= REGULATOR_MODE_STANDBY; + return REGULATOR_MODE_STANDBY; else - mode &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_FAST; - - return mode; + return REGULATOR_MODE_FAST; } /* @@ -282,13 +285,13 @@ static int da9062_buck_set_suspend_mode(struct regulator_dev *rdev, switch (mode) { case REGULATOR_MODE_FAST: - val = BUCK_MODE_SYNC; + val = DA9063_BUCK_MODE_SYNC; break; case REGULATOR_MODE_NORMAL: - val = BUCK_MODE_AUTO; + val = DA9063_BUCK_MODE_AUTO; break; case REGULATOR_MODE_STANDBY: - val = BUCK_MODE_SLEEP; + val = DA9063_BUCK_MODE_SLEEP; break; default: return -EINVAL; @@ -371,6 +374,7 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = { .desc.vsel_reg = DA9062AA_VBUCK1_A, .desc.vsel_mask = DA9062AA_VBUCK1_A_MASK, .desc.linear_min_sel = 0, + .desc.of_map_mode = da9062_map_buck_mode, .sleep = REG_FIELD(DA9062AA_VBUCK1_A, __builtin_ffs((int)DA9062AA_BUCK1_SL_A_MASK) - 1, sizeof(unsigned int) * 8 - @@ -407,6 +411,7 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = { .desc.vsel_reg = DA9062AA_VBUCK3_A, .desc.vsel_mask = DA9062AA_VBUCK3_A_MASK, .desc.linear_min_sel = 0, + .desc.of_map_mode = da9062_map_buck_mode, .sleep = REG_FIELD(DA9062AA_VBUCK3_A, __builtin_ffs((int)DA9062AA_BUCK3_SL_A_MASK) - 1, sizeof(unsigned int) * 8 - @@ -443,6 +448,7 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = { .desc.vsel_reg = DA9062AA_VBUCK4_A, .desc.vsel_mask = DA9062AA_VBUCK4_A_MASK, .desc.linear_min_sel = 0, + .desc.of_map_mode = da9062_map_buck_mode, .sleep = REG_FIELD(DA9062AA_VBUCK4_A, __builtin_ffs((int)DA9062AA_BUCK4_SL_A_MASK) - 1, sizeof(unsigned int) * 8 - @@ -615,6 +621,7 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { .desc.vsel_reg = DA9062AA_VBUCK1_A, .desc.vsel_mask = DA9062AA_VBUCK1_A_MASK, .desc.linear_min_sel = 0, + .desc.of_map_mode = da9062_map_buck_mode, .sleep = REG_FIELD(DA9062AA_VBUCK1_A, __builtin_ffs((int)DA9062AA_BUCK1_SL_A_MASK) - 1, sizeof(unsigned int) * 8 - @@ -651,6 +658,7 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { .desc.vsel_reg = DA9062AA_VBUCK2_A, .desc.vsel_mask = DA9062AA_VBUCK2_A_MASK, .desc.linear_min_sel = 0, + .desc.of_map_mode = da9062_map_buck_mode, .sleep = REG_FIELD(DA9062AA_VBUCK2_A, __builtin_ffs((int)DA9062AA_BUCK2_SL_A_MASK) - 1, sizeof(unsigned int) * 8 - @@ -687,6 +695,7 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { .desc.vsel_reg = DA9062AA_VBUCK3_A, .desc.vsel_mask = DA9062AA_VBUCK3_A_MASK, .desc.linear_min_sel = 0, + .desc.of_map_mode = da9062_map_buck_mode, .sleep = REG_FIELD(DA9062AA_VBUCK3_A, __builtin_ffs((int)DA9062AA_BUCK3_SL_A_MASK) - 1, sizeof(unsigned int) * 8 - @@ -723,6 +732,7 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { .desc.vsel_reg = DA9062AA_VBUCK4_A, .desc.vsel_mask = DA9062AA_VBUCK4_A_MASK, .desc.linear_min_sel = 0, + .desc.of_map_mode = da9062_map_buck_mode, .sleep = REG_FIELD(DA9062AA_VBUCK4_A, __builtin_ffs((int)DA9062AA_BUCK4_SL_A_MASK) - 1, sizeof(unsigned int) * 8 - @@ -942,8 +952,7 @@ static int da9062_regulator_probe(struct platform_device *pdev) regulators->n_regulators = max_regulators; platform_set_drvdata(pdev, regulators); - n = 0; - while (n < regulators->n_regulators) { + for (n = 0; n < regulators->n_regulators; n++) { /* Initialise regulator structure */ regl = ®ulators->regulator[n]; regl->hw = chip; @@ -1002,8 +1011,6 @@ static int da9062_regulator_probe(struct platform_device *pdev) regl->desc.name); return PTR_ERR(regl->rdev); } - - n++; } /* LDOs overcurrent event support */ diff --git a/drivers/regulator/da9063-regulator.c b/drivers/regulator/da9063-regulator.c index 28b1b20f45bd..2aceb3b7afc2 100644 --- a/drivers/regulator/da9063-regulator.c +++ b/drivers/regulator/da9063-regulator.c @@ -225,7 +225,7 @@ static unsigned da9063_buck_get_mode(struct regulator_dev *rdev) { struct da9063_regulator *regl = rdev_get_drvdata(rdev); struct regmap_field *field; - unsigned int val, mode = 0; + unsigned int val; int ret; ret = regmap_field_read(regl->mode, &val); @@ -235,7 +235,6 @@ static unsigned da9063_buck_get_mode(struct regulator_dev *rdev) switch (val) { default: case BUCK_MODE_MANUAL: - mode = REGULATOR_MODE_FAST | REGULATOR_MODE_STANDBY; /* Sleep flag bit decides the mode */ break; case BUCK_MODE_SLEEP: @@ -262,11 +261,9 @@ static unsigned da9063_buck_get_mode(struct regulator_dev *rdev) return 0; if (val) - mode &= REGULATOR_MODE_STANDBY; + return REGULATOR_MODE_STANDBY; else - mode &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_FAST; - - return mode; + return REGULATOR_MODE_FAST; } /* diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c index bf80748f1ccc..523dc1b95826 100644 --- a/drivers/regulator/da9211-regulator.c +++ b/drivers/regulator/da9211-regulator.c @@ -283,12 +283,12 @@ static struct da9211_pdata *da9211_parse_regulators_dt( pdata->init_data[n] = da9211_matches[i].init_data; pdata->reg_node[n] = da9211_matches[i].of_node; - pdata->gpiod_ren[n] = devm_gpiod_get_from_of_node(dev, - da9211_matches[i].of_node, - "enable-gpios", - 0, - GPIOD_OUT_HIGH | GPIOD_FLAGS_BIT_NONEXCLUSIVE, - "da9211-enable"); + pdata->gpiod_ren[n] = devm_fwnode_gpiod_get(dev, + of_fwnode_handle(pdata->reg_node[n]), + "enable", + GPIOD_OUT_HIGH | + GPIOD_FLAGS_BIT_NONEXCLUSIVE, + "da9211-enable"); if (IS_ERR(pdata->gpiod_ren[n])) pdata->gpiod_ren[n] = NULL; n++; diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c index dbe477da4e55..00c83492f774 100644 --- a/drivers/regulator/fan53555.c +++ b/drivers/regulator/fan53555.c @@ -83,6 +83,7 @@ enum { enum { SILERGY_SYR82X = 8, + SILERGY_SYR83X = 9, }; struct fan53555_device_info { @@ -302,6 +303,7 @@ static int fan53555_voltages_setup_silergy(struct fan53555_device_info *di) /* Init voltage range and step */ switch (di->chip_id) { case SILERGY_SYR82X: + case SILERGY_SYR83X: di->vsel_min = 712500; di->vsel_step = 12500; break; diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index f81533070058..bc0bbd99e98d 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -123,6 +123,7 @@ of_get_fixed_voltage_config(struct device *dev, config->enabled_at_boot = true; of_property_read_u32(np, "startup-delay-us", &config->startup_delay); + of_property_read_u32(np, "off-on-delay-us", &config->off_on_delay); if (of_find_property(np, "vin-supply", NULL)) config->input_supply = "vin"; @@ -189,6 +190,7 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) } drvdata->desc.enable_time = config->startup_delay; + drvdata->desc.off_on_delay = config->off_on_delay; if (config->input_supply) { drvdata->desc.supply_name = devm_kstrdup(&pdev->dev, diff --git a/drivers/regulator/internal.h b/drivers/regulator/internal.h index 83ae442f515b..2391b565ef11 100644 --- a/drivers/regulator/internal.h +++ b/drivers/regulator/internal.h @@ -36,6 +36,7 @@ struct regulator { struct list_head list; unsigned int always_on:1; unsigned int bypass:1; + unsigned int device_link:1; int uA_load; unsigned int enable_count; unsigned int deferred_disables; diff --git a/drivers/regulator/max77686-regulator.c b/drivers/regulator/max77686-regulator.c index c8e579e99316..9089ec608fcc 100644 --- a/drivers/regulator/max77686-regulator.c +++ b/drivers/regulator/max77686-regulator.c @@ -256,8 +256,9 @@ static int max77686_of_parse_cb(struct device_node *np, case MAX77686_BUCK8: case MAX77686_BUCK9: case MAX77686_LDO20 ... MAX77686_LDO22: - config->ena_gpiod = gpiod_get_from_of_node(np, - "maxim,ena-gpios", + config->ena_gpiod = fwnode_gpiod_get_index( + of_fwnode_handle(np), + "maxim,ena", 0, GPIOD_OUT_HIGH | GPIOD_FLAGS_BIT_NONEXCLUSIVE, "max77686-regulator"); diff --git a/drivers/regulator/max8907-regulator.c b/drivers/regulator/max8907-regulator.c index 76152aaa330b..96dc0eea7659 100644 --- a/drivers/regulator/max8907-regulator.c +++ b/drivers/regulator/max8907-regulator.c @@ -296,7 +296,10 @@ static int max8907_regulator_probe(struct platform_device *pdev) memcpy(pmic->desc, max8907_regulators, sizeof(pmic->desc)); /* Backwards compatibility with MAX8907B; SD1 uses different voltages */ - regmap_read(max8907->regmap_gen, MAX8907_REG_II2RR, &val); + ret = regmap_read(max8907->regmap_gen, MAX8907_REG_II2RR, &val); + if (ret) + return ret; + if ((val & MAX8907_II2RR_VERSION_MASK) == MAX8907_II2RR_VERSION_REV_B) { pmic->desc[MAX8907_SD1].min_uV = 637500; @@ -333,14 +336,20 @@ static int max8907_regulator_probe(struct platform_device *pdev) } if (pmic->desc[i].ops == &max8907_ldo_ops) { - regmap_read(config.regmap, pmic->desc[i].enable_reg, + ret = regmap_read(config.regmap, pmic->desc[i].enable_reg, &val); + if (ret) + return ret; + if ((val & MAX8907_MASK_LDO_SEQ) != MAX8907_MASK_LDO_SEQ) pmic->desc[i].ops = &max8907_ldo_hwctl_ops; } else if (pmic->desc[i].ops == &max8907_out5v_ops) { - regmap_read(config.regmap, pmic->desc[i].enable_reg, + ret = regmap_read(config.regmap, pmic->desc[i].enable_reg, &val); + if (ret) + return ret; + if ((val & (MAX8907_MASK_OUT5V_VINEN | MAX8907_MASK_OUT5V_ENSRC)) != MAX8907_MASK_OUT5V_ENSRC) diff --git a/drivers/regulator/pbias-regulator.c b/drivers/regulator/pbias-regulator.c index 92b41a6a4dc2..bfc15dd3f730 100644 --- a/drivers/regulator/pbias-regulator.c +++ b/drivers/regulator/pbias-regulator.c @@ -38,15 +38,6 @@ struct pbias_reg_info { int n_voltages; }; -struct pbias_regulator_data { - struct regulator_desc desc; - void __iomem *pbias_addr; - struct regulator_dev *dev; - struct regmap *syscon; - const struct pbias_reg_info *info; - int voltage; -}; - struct pbias_of_data { unsigned int offset; }; @@ -157,14 +148,13 @@ MODULE_DEVICE_TABLE(of, pbias_of_match); static int pbias_regulator_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; - struct pbias_regulator_data *drvdata; struct resource *res; struct regulator_config cfg = { }; + struct regulator_desc *desc; + struct regulator_dev *rdev; struct regmap *syscon; const struct pbias_reg_info *info; - int ret = 0; - int count, idx, data_idx = 0; - const struct of_device_id *match; + int ret, count, idx; const struct pbias_of_data *data; unsigned int offset; @@ -173,19 +163,16 @@ static int pbias_regulator_probe(struct platform_device *pdev) if (count < 0) return count; - drvdata = devm_kcalloc(&pdev->dev, - count, sizeof(struct pbias_regulator_data), - GFP_KERNEL); - if (!drvdata) + desc = devm_kcalloc(&pdev->dev, count, sizeof(*desc), GFP_KERNEL); + if (!desc) return -ENOMEM; syscon = syscon_regmap_lookup_by_phandle(np, "syscon"); if (IS_ERR(syscon)) return PTR_ERR(syscon); - match = of_match_device(of_match_ptr(pbias_of_match), &pdev->dev); - if (match && match->data) { - data = match->data; + data = of_device_get_match_data(&pdev->dev); + if (data) { offset = data->offset; } else { res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -200,7 +187,7 @@ static int pbias_regulator_probe(struct platform_device *pdev) cfg.regmap = syscon; cfg.dev = &pdev->dev; - for (idx = 0; idx < PBIAS_NUM_REGS && data_idx < count; idx++) { + for (idx = 0; idx < PBIAS_NUM_REGS && count; idx++) { if (!pbias_matches[idx].init_data || !pbias_matches[idx].of_node) continue; @@ -209,41 +196,35 @@ static int pbias_regulator_probe(struct platform_device *pdev) if (!info) return -ENODEV; - drvdata[data_idx].syscon = syscon; - drvdata[data_idx].info = info; - drvdata[data_idx].desc.name = info->name; - drvdata[data_idx].desc.owner = THIS_MODULE; - drvdata[data_idx].desc.type = REGULATOR_VOLTAGE; - drvdata[data_idx].des |