--- zzzz-none-000/linux-3.10.107/drivers/hwmon/emc2103.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/hwmon/emc2103.c 2021-02-04 17:41:59.000000000 +0000 @@ -66,7 +66,8 @@ }; struct emc2103_data { - struct device *hwmon_dev; + struct i2c_client *client; + const struct attribute_group *groups[4]; struct mutex update_lock; bool valid; /* registers are valid */ bool fan_rpm_control; @@ -146,8 +147,8 @@ static struct emc2103_data *emc2103_update_device(struct device *dev) { - struct i2c_client *client = to_i2c_client(dev); - struct emc2103_data *data = i2c_get_clientdata(client); + struct emc2103_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; mutex_lock(&data->update_lock); @@ -242,17 +243,15 @@ const char *buf, size_t count) { int nr = to_sensor_dev_attr(da)->index; - struct i2c_client *client = to_i2c_client(dev); - struct emc2103_data *data = i2c_get_clientdata(client); + struct emc2103_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; long val; int result = kstrtol(buf, 10, &val); if (result < 0) - return -EINVAL; + return result; - val = DIV_ROUND_CLOSEST(val, 1000); - if ((val < -63) || (val > 127)) - return -EINVAL; + val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -63, 127); mutex_lock(&data->update_lock); data->temp_min[nr] = val; @@ -266,17 +265,15 @@ const char *buf, size_t count) { int nr = to_sensor_dev_attr(da)->index; - struct i2c_client *client = to_i2c_client(dev); - struct emc2103_data *data = i2c_get_clientdata(client); + struct emc2103_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; long val; int result = kstrtol(buf, 10, &val); if (result < 0) - return -EINVAL; + return result; - val = DIV_ROUND_CLOSEST(val, 1000); - if ((val < -63) || (val > 127)) - return -EINVAL; + val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -63, 127); mutex_lock(&data->update_lock); data->temp_max[nr] = val; @@ -314,13 +311,13 @@ const char *buf, size_t count) { struct emc2103_data *data = emc2103_update_device(dev); - struct i2c_client *client = to_i2c_client(dev); + struct i2c_client *client = data->client; int new_range_bits, old_div = 8 / data->fan_multiplier; long new_div; int status = kstrtol(buf, 10, &new_div); if (status < 0) - return -EINVAL; + return status; if (new_div == old_div) /* No change */ return count; @@ -349,7 +346,7 @@ dev_dbg(&client->dev, "reg 0x%02x, err %d\n", REG_FAN_CONF1, status); mutex_unlock(&data->update_lock); - return -EIO; + return status; } status &= 0x9F; status |= (new_range_bits << 5); @@ -389,16 +386,15 @@ const char *buf, size_t count) { struct emc2103_data *data = emc2103_update_device(dev); - struct i2c_client *client = to_i2c_client(dev); - long rpm_target; + struct i2c_client *client = data->client; + unsigned long rpm_target; - int result = kstrtol(buf, 10, &rpm_target); + int result = kstrtoul(buf, 10, &rpm_target); if (result < 0) - return -EINVAL; + return result; /* Datasheet states 16384 as maximum RPM target (table 3.2) */ - if ((rpm_target < 0) || (rpm_target > 16384)) - return -EINVAL; + rpm_target = clamp_val(rpm_target, 0, 16384); mutex_lock(&data->update_lock); @@ -433,14 +429,14 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); - struct emc2103_data *data = i2c_get_clientdata(client); + struct emc2103_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; long new_value; u8 conf_reg; int result = kstrtol(buf, 10, &new_value); if (result < 0) - return -EINVAL; + return result; mutex_lock(&data->update_lock); switch (new_value) { @@ -585,7 +581,8 @@ emc2103_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct emc2103_data *data; - int status; + struct device *hwmon_dev; + int status, idx = 0; if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; @@ -596,6 +593,7 @@ return -ENOMEM; i2c_set_clientdata(client, data); + data->client = client; mutex_init(&data->update_lock); /* 2103-2 and 2103-4 have 3 external diodes, 2103-1 has 1 */ @@ -629,60 +627,21 @@ } } - /* Register sysfs hooks */ - status = sysfs_create_group(&client->dev.kobj, &emc2103_group); - if (status) - return status; - - if (data->temp_count >= 3) { - status = sysfs_create_group(&client->dev.kobj, - &emc2103_temp3_group); - if (status) - goto exit_remove; - } - - if (data->temp_count == 4) { - status = sysfs_create_group(&client->dev.kobj, - &emc2103_temp4_group); - if (status) - goto exit_remove_temp3; - } - - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - status = PTR_ERR(data->hwmon_dev); - goto exit_remove_temp4; - } - - dev_info(&client->dev, "%s: sensor '%s'\n", - dev_name(data->hwmon_dev), client->name); - - return 0; - -exit_remove_temp4: - if (data->temp_count == 4) - sysfs_remove_group(&client->dev.kobj, &emc2103_temp4_group); -exit_remove_temp3: + /* sysfs hooks */ + data->groups[idx++] = &emc2103_group; if (data->temp_count >= 3) - sysfs_remove_group(&client->dev.kobj, &emc2103_temp3_group); -exit_remove: - sysfs_remove_group(&client->dev.kobj, &emc2103_group); - return status; -} - -static int emc2103_remove(struct i2c_client *client) -{ - struct emc2103_data *data = i2c_get_clientdata(client); - - hwmon_device_unregister(data->hwmon_dev); - + data->groups[idx++] = &emc2103_temp3_group; if (data->temp_count == 4) - sysfs_remove_group(&client->dev.kobj, &emc2103_temp4_group); + data->groups[idx++] = &emc2103_temp4_group; - if (data->temp_count >= 3) - sysfs_remove_group(&client->dev.kobj, &emc2103_temp3_group); + hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev, + client->name, data, + data->groups); + if (IS_ERR(hwmon_dev)) + return PTR_ERR(hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &emc2103_group); + dev_info(&client->dev, "%s: sensor '%s'\n", + dev_name(hwmon_dev), client->name); return 0; } @@ -722,7 +681,6 @@ .name = "emc2103", }, .probe = emc2103_probe, - .remove = emc2103_remove, .id_table = emc2103_ids, .detect = emc2103_detect, .address_list = normal_i2c,