--- zzzz-none-000/linux-3.10.107/drivers/hwmon/lm63.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/hwmon/lm63.c 2021-02-04 17:41:59.000000000 +0000 @@ -1,7 +1,7 @@ /* * lm63.c - driver for the National Semiconductor LM63 temperature sensor * with integrated fan control - * Copyright (C) 2004-2008 Jean Delvare + * Copyright (C) 2004-2008 Jean Delvare * Based on the lm90 driver. * * The LM63 is a sensor chip made by National Semiconductor. It measures @@ -126,24 +126,17 @@ #define FAN_TO_REG(val) ((val) <= 82 ? 0xFFFC : \ (5400000 / (val)) & 0xFFFC) #define TEMP8_FROM_REG(reg) ((reg) * 1000) -#define TEMP8_TO_REG(val) ((val) <= -128000 ? -128 : \ - (val) >= 127000 ? 127 : \ - (val) < 0 ? ((val) - 500) / 1000 : \ - ((val) + 500) / 1000) -#define TEMP8U_TO_REG(val) ((val) <= 0 ? 0 : \ - (val) >= 255000 ? 255 : \ - ((val) + 500) / 1000) +#define TEMP8_TO_REG(val) DIV_ROUND_CLOSEST(clamp_val((val), -128000, \ + 127000), 1000) +#define TEMP8U_TO_REG(val) DIV_ROUND_CLOSEST(clamp_val((val), 0, \ + 255000), 1000) #define TEMP11_FROM_REG(reg) ((reg) / 32 * 125) -#define TEMP11_TO_REG(val) ((val) <= -128000 ? 0x8000 : \ - (val) >= 127875 ? 0x7FE0 : \ - (val) < 0 ? ((val) - 62) / 125 * 32 : \ - ((val) + 62) / 125 * 32) -#define TEMP11U_TO_REG(val) ((val) <= 0 ? 0 : \ - (val) >= 255875 ? 0xFFE0 : \ - ((val) + 62) / 125 * 32) -#define HYST_TO_REG(val) ((val) <= 0 ? 0 : \ - (val) >= 127000 ? 127 : \ - ((val) + 500) / 1000) +#define TEMP11_TO_REG(val) (DIV_ROUND_CLOSEST(clamp_val((val), -128000, \ + 127875), 125) * 32) +#define TEMP11U_TO_REG(val) (DIV_ROUND_CLOSEST(clamp_val((val), 0, \ + 255875), 125) * 32) +#define HYST_TO_REG(val) DIV_ROUND_CLOSEST(clamp_val((val), 0, 127000), \ + 1000) #define UPDATE_INTERVAL(max, rate) \ ((1000 << (LM63_MAX_CONVRATE - (rate))) / (max)) @@ -155,8 +148,9 @@ */ struct lm63_data { - struct device *hwmon_dev; + struct i2c_client *client; struct mutex update_lock; + const struct attribute_group *groups[5]; char valid; /* zero until following fields are valid */ char lut_valid; /* zero until lut fields are valid */ unsigned long last_updated; /* in jiffies */ @@ -218,9 +212,9 @@ * Update the lookup table register cache. * client->update_lock must be held when calling this function. */ -static void lm63_update_lut(struct i2c_client *client) +static void lm63_update_lut(struct lm63_data *data) { - struct lm63_data *data = i2c_get_clientdata(client); + struct i2c_client *client = data->client; int i; if (time_after(jiffies, data->lut_last_updated + 5 * HZ) || @@ -241,15 +235,14 @@ static struct lm63_data *lm63_update_device(struct device *dev) { - struct i2c_client *client = to_i2c_client(dev); - struct lm63_data *data = i2c_get_clientdata(client); + struct lm63_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; unsigned long next_update; mutex_lock(&data->update_lock); - next_update = data->last_updated - + msecs_to_jiffies(data->update_interval) + 1; - + next_update = data->last_updated + + msecs_to_jiffies(data->update_interval); if (time_after(jiffies, next_update) || !data->valid) { if (data->config & 0x04) { /* tachometer enabled */ /* order matters for fan1_input */ @@ -311,7 +304,7 @@ data->valid = 1; } - lm63_update_lut(client); + lm63_update_lut(data); mutex_unlock(&data->update_lock); @@ -322,18 +315,17 @@ * Trip points in the lookup table should be in ascending order for both * temperatures and PWM output values. */ -static int lm63_lut_looks_bad(struct i2c_client *client) +static int lm63_lut_looks_bad(struct device *dev, struct lm63_data *data) { - struct lm63_data *data = i2c_get_clientdata(client); int i; mutex_lock(&data->update_lock); - lm63_update_lut(client); + lm63_update_lut(data); for (i = 1; i < data->lut_size; i++) { if (data->pwm1[1 + i - 1] > data->pwm1[1 + i] || data->temp8[3 + i - 1] > data->temp8[3 + i]) { - dev_warn(&client->dev, + dev_warn(dev, "Lookup table doesn't look sane (check entries %d and %d)\n", i, i + 1); break; @@ -359,8 +351,8 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *dummy, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); - struct lm63_data *data = i2c_get_clientdata(client); + struct lm63_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; unsigned long val; int err; @@ -400,8 +392,8 @@ const char *buf, size_t count) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct i2c_client *client = to_i2c_client(dev); - struct lm63_data *data = i2c_get_clientdata(client); + struct lm63_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; int nr = attr->index; unsigned long val; int err; @@ -436,8 +428,8 @@ struct device_attribute *dummy, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); - struct lm63_data *data = i2c_get_clientdata(client); + struct lm63_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; unsigned long val; int err; @@ -451,7 +443,7 @@ * Only let the user switch to automatic mode if the lookup table * looks sane. */ - if (val == 2 && lm63_lut_looks_bad(client)) + if (val == 2 && lm63_lut_looks_bad(dev, data)) return -EPERM; mutex_lock(&data->update_lock); @@ -462,7 +454,7 @@ else data->config_fan &= ~0x20; i2c_smbus_write_byte_data(client, LM63_REG_CONFIG_FAN, - data->config_fan); + data->config_fan); mutex_unlock(&data->update_lock); return count; } @@ -506,8 +498,8 @@ const char *buf, size_t count) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct i2c_client *client = to_i2c_client(dev); - struct lm63_data *data = i2c_get_clientdata(client); + struct lm63_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; int nr = attr->index; long val; int err; @@ -580,8 +572,8 @@ }; struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct i2c_client *client = to_i2c_client(dev); - struct lm63_data *data = i2c_get_clientdata(client); + struct lm63_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; long val; int err; int nr = attr->index; @@ -636,8 +628,8 @@ struct device_attribute *dummy, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); - struct lm63_data *data = i2c_get_clientdata(client); + struct lm63_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; long val; int err; long hyst; @@ -658,11 +650,11 @@ * Set conversion rate. * client->update_lock must be held when calling this function. */ -static void lm63_set_convrate(struct i2c_client *client, struct lm63_data *data, - unsigned int interval) +static void lm63_set_convrate(struct lm63_data *data, unsigned int interval) { - int i; + struct i2c_client *client = data->client; unsigned int update_interval; + int i; /* Shift calculations to avoid rounding errors */ interval <<= 6; @@ -690,8 +682,7 @@ struct device_attribute *attr, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); - struct lm63_data *data = i2c_get_clientdata(client); + struct lm63_data *data = dev_get_drvdata(dev); unsigned long val; int err; @@ -700,7 +691,7 @@ return err; mutex_lock(&data->update_lock); - lm63_set_convrate(client, data, clamp_val(val, 0, 100000)); + lm63_set_convrate(data, clamp_val(val, 0, 100000)); mutex_unlock(&data->update_lock); return count; @@ -709,8 +700,7 @@ static ssize_t show_type(struct device *dev, struct device_attribute *attr, char *buf) { - struct i2c_client *client = to_i2c_client(dev); - struct lm63_data *data = i2c_get_clientdata(client); + struct lm63_data *data = dev_get_drvdata(dev); return sprintf(buf, data->trutherm ? "1\n" : "2\n"); } @@ -718,8 +708,8 @@ static ssize_t set_type(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); - struct lm63_data *data = i2c_get_clientdata(client); + struct lm63_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; unsigned long val; int ret; u8 reg; @@ -916,6 +906,15 @@ NULL }; +static struct attribute *lm63_attributes_temp2_type[] = { + &dev_attr_temp2_type.attr, + NULL +}; + +static const struct attribute_group lm63_group_temp2_type = { + .attrs = lm63_attributes_temp2_type, +}; + static struct attribute *lm63_attributes_extra_lut[] = { &sensor_dev_attr_pwm1_auto_point9_pwm.dev_attr.attr, &sensor_dev_attr_pwm1_auto_point9_temp.dev_attr.attr, @@ -947,8 +946,7 @@ struct attribute *attr, int index) { struct device *dev = container_of(kobj, struct device, kobj); - struct i2c_client *client = to_i2c_client(dev); - struct lm63_data *data = i2c_get_clientdata(client); + struct lm63_data *data = dev_get_drvdata(dev); if (attr == &sensor_dev_attr_temp2_crit.dev_attr.attr && (data->kind == lm64 || @@ -1027,9 +1025,10 @@ * Ideally we shouldn't have to initialize anything, since the BIOS * should have taken care of everything */ -static void lm63_init_client(struct i2c_client *client) +static void lm63_init_client(struct lm63_data *data) { - struct lm63_data *data = i2c_get_clientdata(client); + struct i2c_client *client = data->client; + struct device *dev = &client->dev; u8 convrate; data->config = i2c_smbus_read_byte_data(client, LM63_REG_CONFIG1); @@ -1038,7 +1037,7 @@ /* Start converting if needed */ if (data->config & 0x40) { /* standby */ - dev_dbg(&client->dev, "Switching to operational mode\n"); + dev_dbg(dev, "Switching to operational mode\n"); data->config &= 0xA7; i2c_smbus_write_byte_data(client, LM63_REG_CONFIG1, data->config); @@ -1091,13 +1090,13 @@ /* Show some debug info about the LM63 configuration */ if (data->kind == lm63) - dev_dbg(&client->dev, "Alert/tach pin configured for %s\n", + dev_dbg(dev, "Alert/tach pin configured for %s\n", (data->config & 0x04) ? "tachometer input" : "alert output"); - dev_dbg(&client->dev, "PWM clock %s kHz, output frequency %u Hz\n", + dev_dbg(dev, "PWM clock %s kHz, output frequency %u Hz\n", (data->config_fan & 0x08) ? "1.4" : "360", ((data->config_fan & 0x08) ? 700 : 180000) / data->pwm1_freq); - dev_dbg(&client->dev, "PWM output active %s, %s mode\n", + dev_dbg(dev, "PWM output active %s, %s mode\n", (data->config_fan & 0x10) ? "low" : "high", (data->config_fan & 0x20) ? "manual" : "auto"); } @@ -1105,15 +1104,16 @@ static int lm63_probe(struct i2c_client *client, const struct i2c_device_id *id) { + struct device *dev = &client->dev; + struct device *hwmon_dev; struct lm63_data *data; - int err; + int groups = 0; - data = devm_kzalloc(&client->dev, sizeof(struct lm63_data), GFP_KERNEL); + data = devm_kzalloc(dev, sizeof(struct lm63_data), GFP_KERNEL); if (!data) return -ENOMEM; - i2c_set_clientdata(client, data); - data->valid = 0; + data->client = client; mutex_init(&data->update_lock); /* Set the device type */ @@ -1122,59 +1122,21 @@ data->temp2_offset = 16000; /* Initialize chip */ - lm63_init_client(client); + lm63_init_client(data); /* Register sysfs hooks */ - err = sysfs_create_group(&client->dev.kobj, &lm63_group); - if (err) - return err; - if (data->config & 0x04) { /* tachometer enabled */ - err = sysfs_create_group(&client->dev.kobj, &lm63_group_fan1); - if (err) - goto exit_remove_files; - } - if (data->kind == lm96163) { - err = device_create_file(&client->dev, &dev_attr_temp2_type); - if (err) - goto exit_remove_files; - - err = sysfs_create_group(&client->dev.kobj, - &lm63_group_extra_lut); - if (err) - goto exit_remove_files; - } - - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - err = PTR_ERR(data->hwmon_dev); - goto exit_remove_files; - } + data->groups[groups++] = &lm63_group; + if (data->config & 0x04) /* tachometer enabled */ + data->groups[groups++] = &lm63_group_fan1; - return 0; - -exit_remove_files: - sysfs_remove_group(&client->dev.kobj, &lm63_group); - sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1); if (data->kind == lm96163) { - device_remove_file(&client->dev, &dev_attr_temp2_type); - sysfs_remove_group(&client->dev.kobj, &lm63_group_extra_lut); + data->groups[groups++] = &lm63_group_temp2_type; + data->groups[groups++] = &lm63_group_extra_lut; } - return err; -} - -static int lm63_remove(struct i2c_client *client) -{ - struct lm63_data *data = i2c_get_clientdata(client); - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &lm63_group); - sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1); - if (data->kind == lm96163) { - device_remove_file(&client->dev, &dev_attr_temp2_type); - sysfs_remove_group(&client->dev.kobj, &lm63_group_extra_lut); - } - - return 0; + hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, + data, data->groups); + return PTR_ERR_OR_ZERO(hwmon_dev); } /* @@ -1195,7 +1157,6 @@ .name = "lm63", }, .probe = lm63_probe, - .remove = lm63_remove, .id_table = lm63_id, .detect = lm63_detect, .address_list = normal_i2c, @@ -1203,6 +1164,6 @@ module_i2c_driver(lm63_driver); -MODULE_AUTHOR("Jean Delvare "); +MODULE_AUTHOR("Jean Delvare "); MODULE_DESCRIPTION("LM63 driver"); MODULE_LICENSE("GPL");