--- zzzz-none-000/linux-3.10.107/drivers/hwmon/w83l786ng.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/hwmon/w83l786ng.c 2021-02-04 17:41:59.000000000 +0000 @@ -124,7 +124,7 @@ } struct w83l786ng_data { - struct device *hwmon_dev; + struct i2c_client *client; struct mutex update_lock; char valid; /* !=0 if following fields are valid */ unsigned long last_updated; /* In jiffies */ @@ -148,32 +148,6 @@ u8 tolerance[2]; }; -static int w83l786ng_probe(struct i2c_client *client, - const struct i2c_device_id *id); -static int w83l786ng_detect(struct i2c_client *client, - struct i2c_board_info *info); -static int w83l786ng_remove(struct i2c_client *client); -static void w83l786ng_init_client(struct i2c_client *client); -static struct w83l786ng_data *w83l786ng_update_device(struct device *dev); - -static const struct i2c_device_id w83l786ng_id[] = { - { "w83l786ng", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, w83l786ng_id); - -static struct i2c_driver w83l786ng_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "w83l786ng", - }, - .probe = w83l786ng_probe, - .remove = w83l786ng_remove, - .id_table = w83l786ng_id, - .detect = w83l786ng_detect, - .address_list = normal_i2c, -}; - static u8 w83l786ng_read_value(struct i2c_client *client, u8 reg) { @@ -186,6 +160,77 @@ return i2c_smbus_write_byte_data(client, reg, value); } +static struct w83l786ng_data *w83l786ng_update_device(struct device *dev) +{ + struct w83l786ng_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + int i, j; + u8 reg_tmp, pwmcfg; + + mutex_lock(&data->update_lock); + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + dev_dbg(&client->dev, "Updating w83l786ng data.\n"); + + /* Update the voltages measured value and limits */ + for (i = 0; i < 3; i++) { + data->in[i] = w83l786ng_read_value(client, + W83L786NG_REG_IN(i)); + data->in_min[i] = w83l786ng_read_value(client, + W83L786NG_REG_IN_MIN(i)); + data->in_max[i] = w83l786ng_read_value(client, + W83L786NG_REG_IN_MAX(i)); + } + + /* Update the fan counts and limits */ + for (i = 0; i < 2; i++) { + data->fan[i] = w83l786ng_read_value(client, + W83L786NG_REG_FAN(i)); + data->fan_min[i] = w83l786ng_read_value(client, + W83L786NG_REG_FAN_MIN(i)); + } + + /* Update the fan divisor */ + reg_tmp = w83l786ng_read_value(client, W83L786NG_REG_FAN_DIV); + data->fan_div[0] = reg_tmp & 0x07; + data->fan_div[1] = (reg_tmp >> 4) & 0x07; + + pwmcfg = w83l786ng_read_value(client, W83L786NG_REG_FAN_CFG); + for (i = 0; i < 2; i++) { + data->pwm_mode[i] = + ((pwmcfg >> W83L786NG_PWM_MODE_SHIFT[i]) & 1) + ? 0 : 1; + data->pwm_enable[i] = + ((pwmcfg >> W83L786NG_PWM_ENABLE_SHIFT[i]) & 3) + 1; + data->pwm[i] = + (w83l786ng_read_value(client, W83L786NG_REG_PWM[i]) + & 0x0f) * 0x11; + } + + + /* Update the temperature sensors */ + for (i = 0; i < 2; i++) { + for (j = 0; j < 3; j++) { + data->temp[i][j] = w83l786ng_read_value(client, + W83L786NG_REG_TEMP[i][j]); + } + } + + /* Update Smart Fan I/II tolerance */ + reg_tmp = w83l786ng_read_value(client, W83L786NG_REG_TOLERANCE); + data->tolerance[0] = reg_tmp & 0x0f; + data->tolerance[1] = (reg_tmp >> 4) & 0x0f; + + data->last_updated = jiffies; + data->valid = 1; + + } + + mutex_unlock(&data->update_lock); + + return data; +} + /* following are the sysfs callback functions */ #define show_in_reg(reg) \ static ssize_t \ @@ -207,8 +252,8 @@ const char *buf, size_t count) \ { \ int nr = to_sensor_dev_attr(attr)->index; \ - struct i2c_client *client = to_i2c_client(dev); \ - struct w83l786ng_data *data = i2c_get_clientdata(client); \ + struct w83l786ng_data *data = dev_get_drvdata(dev); \ + struct i2c_client *client = data->client; \ unsigned long val; \ int err = kstrtoul(buf, 10, &val); \ if (err) \ @@ -249,7 +294,7 @@ int nr = to_sensor_dev_attr(attr)->index; \ struct w83l786ng_data *data = w83l786ng_update_device(dev); \ return sprintf(buf, "%d\n", \ - FAN_FROM_REG(data->fan[nr], DIV_FROM_REG(data->fan_div[nr]))); \ + FAN_FROM_REG(data->reg[nr], DIV_FROM_REG(data->fan_div[nr]))); \ } show_fan_reg(fan); @@ -260,8 +305,8 @@ const char *buf, size_t count) { int nr = to_sensor_dev_attr(attr)->index; - struct i2c_client *client = to_i2c_client(dev); - struct w83l786ng_data *data = i2c_get_clientdata(client); + struct w83l786ng_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; unsigned long val; int err; @@ -298,8 +343,8 @@ const char *buf, size_t count) { int nr = to_sensor_dev_attr(attr)->index; - struct i2c_client *client = to_i2c_client(dev); - struct w83l786ng_data *data = i2c_get_clientdata(client); + struct w83l786ng_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; unsigned long min; u8 tmp_fan_div; @@ -389,8 +434,8 @@ to_sensor_dev_attr_2(attr); int nr = sensor_attr->nr; int index = sensor_attr->index; - struct i2c_client *client = to_i2c_client(dev); - struct w83l786ng_data *data = i2c_get_clientdata(client); + struct w83l786ng_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; long val; int err; @@ -444,8 +489,8 @@ const char *buf, size_t count) { int nr = to_sensor_dev_attr(attr)->index; - struct i2c_client *client = to_i2c_client(dev); - struct w83l786ng_data *data = i2c_get_clientdata(client); + struct w83l786ng_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; u8 reg; unsigned long val; int err; @@ -472,8 +517,8 @@ const char *buf, size_t count) { int nr = to_sensor_dev_attr(attr)->index; - struct i2c_client *client = to_i2c_client(dev); - struct w83l786ng_data *data = i2c_get_clientdata(client); + struct w83l786ng_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; unsigned long val; int err; @@ -496,8 +541,8 @@ const char *buf, size_t count) { int nr = to_sensor_dev_attr(attr)->index; - struct i2c_client *client = to_i2c_client(dev); - struct w83l786ng_data *data = i2c_get_clientdata(client); + struct w83l786ng_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; u8 reg; unsigned long val; int err; @@ -552,8 +597,8 @@ const char *buf, size_t count) { int nr = to_sensor_dev_attr(attr)->index; - struct i2c_client *client = to_i2c_client(dev); - struct w83l786ng_data *data = i2c_get_clientdata(client); + struct w83l786ng_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; u8 tol_tmp, tol_mask; unsigned long val; int err; @@ -608,7 +653,7 @@ #define TOLERANCE_UNIT_ATTRS(X) \ &sda_tolerance[X].dev_attr.attr -static struct attribute *w83l786ng_attributes[] = { +static struct attribute *w83l786ng_attrs[] = { IN_UNIT_ATTRS(0), IN_UNIT_ATTRS(1), IN_UNIT_ATTRS(2), @@ -623,9 +668,7 @@ NULL }; -static const struct attribute_group w83l786ng_group = { - .attrs = w83l786ng_attributes, -}; +ATTRIBUTE_GROUPS(w83l786ng); static int w83l786ng_detect(struct i2c_client *client, struct i2c_board_info *info) @@ -662,20 +705,33 @@ return 0; } +static void w83l786ng_init_client(struct i2c_client *client) +{ + u8 tmp; + + if (reset) + w83l786ng_write_value(client, W83L786NG_REG_CONFIG, 0x80); + + /* Start monitoring */ + tmp = w83l786ng_read_value(client, W83L786NG_REG_CONFIG); + if (!(tmp & 0x01)) + w83l786ng_write_value(client, W83L786NG_REG_CONFIG, tmp | 0x01); +} + static int w83l786ng_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device *dev = &client->dev; struct w83l786ng_data *data; - int i, err = 0; + struct device *hwmon_dev; + int i; u8 reg_tmp; - data = devm_kzalloc(&client->dev, sizeof(struct w83l786ng_data), - GFP_KERNEL); + data = devm_kzalloc(dev, sizeof(struct w83l786ng_data), GFP_KERNEL); if (!data) return -ENOMEM; - i2c_set_clientdata(client, data); + data->client = client; mutex_init(&data->update_lock); /* Initialize the chip */ @@ -692,121 +748,28 @@ data->fan_div[0] = reg_tmp & 0x07; data->fan_div[1] = (reg_tmp >> 4) & 0x07; - /* Register sysfs hooks */ - err = sysfs_create_group(&client->dev.kobj, &w83l786ng_group); - if (err) - goto exit_remove; - - data->hwmon_dev = hwmon_device_register(dev); - if (IS_ERR(data->hwmon_dev)) { - err = PTR_ERR(data->hwmon_dev); - goto exit_remove; - } - - return 0; - - /* Unregister sysfs hooks */ - -exit_remove: - sysfs_remove_group(&client->dev.kobj, &w83l786ng_group); - return err; -} - -static int -w83l786ng_remove(struct i2c_client *client) -{ - struct w83l786ng_data *data = i2c_get_clientdata(client); - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &w83l786ng_group); - - return 0; + hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, + data, + w83l786ng_groups); + return PTR_ERR_OR_ZERO(hwmon_dev); } -static void -w83l786ng_init_client(struct i2c_client *client) -{ - u8 tmp; - - if (reset) - w83l786ng_write_value(client, W83L786NG_REG_CONFIG, 0x80); - - /* Start monitoring */ - tmp = w83l786ng_read_value(client, W83L786NG_REG_CONFIG); - if (!(tmp & 0x01)) - w83l786ng_write_value(client, W83L786NG_REG_CONFIG, tmp | 0x01); -} - -static struct w83l786ng_data *w83l786ng_update_device(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct w83l786ng_data *data = i2c_get_clientdata(client); - int i, j; - u8 reg_tmp, pwmcfg; - - mutex_lock(&data->update_lock); - if (time_after(jiffies, data->last_updated + HZ + HZ / 2) - || !data->valid) { - dev_dbg(&client->dev, "Updating w83l786ng data.\n"); - - /* Update the voltages measured value and limits */ - for (i = 0; i < 3; i++) { - data->in[i] = w83l786ng_read_value(client, - W83L786NG_REG_IN(i)); - data->in_min[i] = w83l786ng_read_value(client, - W83L786NG_REG_IN_MIN(i)); - data->in_max[i] = w83l786ng_read_value(client, - W83L786NG_REG_IN_MAX(i)); - } - - /* Update the fan counts and limits */ - for (i = 0; i < 2; i++) { - data->fan[i] = w83l786ng_read_value(client, - W83L786NG_REG_FAN(i)); - data->fan_min[i] = w83l786ng_read_value(client, - W83L786NG_REG_FAN_MIN(i)); - } - - /* Update the fan divisor */ - reg_tmp = w83l786ng_read_value(client, W83L786NG_REG_FAN_DIV); - data->fan_div[0] = reg_tmp & 0x07; - data->fan_div[1] = (reg_tmp >> 4) & 0x07; - - pwmcfg = w83l786ng_read_value(client, W83L786NG_REG_FAN_CFG); - for (i = 0; i < 2; i++) { - data->pwm_mode[i] = - ((pwmcfg >> W83L786NG_PWM_MODE_SHIFT[i]) & 1) - ? 0 : 1; - data->pwm_enable[i] = - ((pwmcfg >> W83L786NG_PWM_ENABLE_SHIFT[i]) & 3) + 1; - data->pwm[i] = - (w83l786ng_read_value(client, W83L786NG_REG_PWM[i]) - & 0x0f) * 0x11; - } - - - /* Update the temperature sensors */ - for (i = 0; i < 2; i++) { - for (j = 0; j < 3; j++) { - data->temp[i][j] = w83l786ng_read_value(client, - W83L786NG_REG_TEMP[i][j]); - } - } - - /* Update Smart Fan I/II tolerance */ - reg_tmp = w83l786ng_read_value(client, W83L786NG_REG_TOLERANCE); - data->tolerance[0] = reg_tmp & 0x0f; - data->tolerance[1] = (reg_tmp >> 4) & 0x0f; - - data->last_updated = jiffies; - data->valid = 1; - - } - - mutex_unlock(&data->update_lock); +static const struct i2c_device_id w83l786ng_id[] = { + { "w83l786ng", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, w83l786ng_id); - return data; -} +static struct i2c_driver w83l786ng_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "w83l786ng", + }, + .probe = w83l786ng_probe, + .id_table = w83l786ng_id, + .detect = w83l786ng_detect, + .address_list = normal_i2c, +}; module_i2c_driver(w83l786ng_driver);