We can reduce boilerplate code and eliminate the driver remove() function by using devm_regulator_get_optional_enable_get_voltage(). A new external_vref flag is added since we no longer have the handle to the regulator to check if it is present. Signed-off-by: David Lechner <dlechner@xxxxxxxxxxxx> --- drivers/hwmon/adc128d818.c | 55 ++++++++++++++-------------------------------- 1 file changed, 17 insertions(+), 38 deletions(-) diff --git a/drivers/hwmon/adc128d818.c b/drivers/hwmon/adc128d818.c index 46e3c8c50765..119e2841720f 100644 --- a/drivers/hwmon/adc128d818.c +++ b/drivers/hwmon/adc128d818.c @@ -58,7 +58,6 @@ static const u8 num_inputs[] = { 7, 8, 4, 6 }; struct adc128_data { struct i2c_client *client; - struct regulator *regulator; int vref; /* Reference voltage in mV */ struct mutex update_lock; u8 mode; /* Operation mode */ @@ -389,7 +388,7 @@ static int adc128_detect(struct i2c_client *client, struct i2c_board_info *info) return 0; } -static int adc128_init_client(struct adc128_data *data) +static int adc128_init_client(struct adc128_data *data, bool external_vref) { struct i2c_client *client = data->client; int err; @@ -408,7 +407,7 @@ static int adc128_init_client(struct adc128_data *data) regval |= data->mode << 1; /* If external vref is selected, configure the chip to use it */ - if (data->regulator) + if (external_vref) regval |= 0x01; /* Write advanced configuration register */ @@ -430,30 +429,25 @@ static int adc128_init_client(struct adc128_data *data) static int adc128_probe(struct i2c_client *client) { struct device *dev = &client->dev; - struct regulator *regulator; struct device *hwmon_dev; struct adc128_data *data; - int err, vref; + bool external_vref; + int err; data = devm_kzalloc(dev, sizeof(struct adc128_data), GFP_KERNEL); if (!data) return -ENOMEM; /* vref is optional. If specified, is used as chip reference voltage */ - regulator = devm_regulator_get_optional(dev, "vref"); - if (!IS_ERR(regulator)) { - data->regulator = regulator; - err = regulator_enable(regulator); - if (err < 0) - return err; - vref = regulator_get_voltage(regulator); - if (vref < 0) { - err = vref; - goto error; - } - data->vref = DIV_ROUND_CLOSEST(vref, 1000); - } else { + err = devm_regulator_get_optional_enable_get_voltage(dev, "vref"); + if (err == -ENODEV) { + external_vref = false; data->vref = 2560; /* 2.56V, in mV */ + } else if (err < 0) { + return err; + } else { + external_vref = true; + data->vref = DIV_ROUND_CLOSEST(err, 1000); } /* Operation mode is optional. If unspecified, keep current mode */ @@ -461,13 +455,12 @@ static int adc128_probe(struct i2c_client *client) if (data->mode > 3) { dev_err(dev, "invalid operation mode %d\n", data->mode); - err = -EINVAL; - goto error; + return -EINVAL; } } else { err = i2c_smbus_read_byte_data(client, ADC128_REG_CONFIG_ADV); if (err < 0) - goto error; + return err; data->mode = (err >> 1) & ADC128_REG_MASK; } @@ -476,31 +469,18 @@ static int adc128_probe(struct i2c_client *client) mutex_init(&data->update_lock); /* Initialize the chip */ - err = adc128_init_client(data); + err = adc128_init_client(data, external_vref); if (err < 0) - goto error; + return err; hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, data, adc128_groups); if (IS_ERR(hwmon_dev)) { err = PTR_ERR(hwmon_dev); - goto error; + return err; } return 0; - -error: - if (data->regulator) - regulator_disable(data->regulator); - return err; -} - -static void adc128_remove(struct i2c_client *client) -{ - struct adc128_data *data = i2c_get_clientdata(client); - - if (data->regulator) - regulator_disable(data->regulator); } static const struct i2c_device_id adc128_id[] = { @@ -522,7 +502,6 @@ static struct i2c_driver adc128_driver = { .of_match_table = of_match_ptr(adc128_of_match), }, .probe = adc128_probe, - .remove = adc128_remove, .id_table = adc128_id, .detect = adc128_detect, .address_list = normal_i2c, -- 2.43.2