diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-03-19 17:02:01 -0700 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-03-19 17:02:01 -0700 |
commit | 10ce3cc919f50c2043b41ca968b43c26a3672600 (patch) | |
tree | ea409366a5208aced495bc0516a08b81fd43222e /drivers/hwmon | |
parent | 24e3e5ae1e4c2a3a32f5b1f96b4e3fd721806acd (diff) | |
parent | 5c6a7a62c130afef3d61c1dee153012231ff5cd9 (diff) |
Merge branch 'next' into for-linus
Diffstat (limited to 'drivers/hwmon')
77 files changed, 1439 insertions, 686 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 91be41f6080..02260406b9e 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -367,11 +367,11 @@ config SENSORS_F71882FG will be called f71882fg. config SENSORS_F75375S - tristate "Fintek F75375S/SP and F75373" + tristate "Fintek F75375S/SP, F75373 and F75387" depends on I2C help If you say yes here you get support for hardware monitoring - features of the Fintek F75375S/SP and F75373 + features of the Fintek F75375S/SP, F75373 and F75387 This driver can also be built as a module. If so, the module will be called f75375s. @@ -474,8 +474,8 @@ config SENSORS_IT87 select HWMON_VID help If you say yes here you get support for ITE IT8705F, IT8712F, - IT8716F, IT8718F, IT8720F, IT8721F, IT8726F and IT8758E sensor - chips, and the SiS960 clone. + IT8716F, IT8718F, IT8720F, IT8721F, IT8726F, IT8728F and IT8758E + sensor chips, and the SiS960 clone. This driver can also be built as a module. If so, the module will be called it87. @@ -515,11 +515,11 @@ config SENSORS_LINEAGE will be called lineage-pem. config SENSORS_LM63 - tristate "National Semiconductor LM63 and LM64" + tristate "National Semiconductor LM63 and compatibles" depends on I2C help If you say yes here you get support for the National - Semiconductor LM63 and LM64 remote diode digital temperature + Semiconductor LM63, LM64, and LM96163 remote diode digital temperature sensors with integrated fan control. Such chips are found on the Tyan S4882 (Thunder K8QS Pro) motherboard, among others. diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c index 65a35cf5b3c..3b728e8f169 100644 --- a/drivers/hwmon/abituguru.c +++ b/drivers/hwmon/abituguru.c @@ -145,7 +145,7 @@ static const u8 abituguru_pwm_max[5] = { 0, 255, 255, 75, 75 }; /* Insmod parameters */ -static int force; +static bool force; module_param(force, bool, 0); MODULE_PARM_DESC(force, "Set to one to force detection."); static int bank1_types[ABIT_UGURU_MAX_BANK1_SENSORS] = { -1, -1, -1, -1, -1, diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c index d30855a7578..34a14a77e00 100644 --- a/drivers/hwmon/abituguru3.c +++ b/drivers/hwmon/abituguru3.c @@ -603,11 +603,11 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { /* Insmod parameters */ -static int force; +static bool force; module_param(force, bool, 0); MODULE_PARM_DESC(force, "Set to one to force detection."); /* Default verbose is 1, since this driver is still in the testing phase */ -static int verbose = 1; +static bool verbose = 1; module_param(verbose, bool, 0644); MODULE_PARM_DESC(verbose, "Enable/disable verbose error reporting"); diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c index 66f67293341..554f046bcf2 100644 --- a/drivers/hwmon/acpi_power_meter.c +++ b/drivers/hwmon/acpi_power_meter.c @@ -58,7 +58,7 @@ ACPI_MODULE_NAME(ACPI_POWER_METER_NAME); #define POWER_ALARM_NAME "power1_alarm" static int cap_in_hardware; -static int force_cap_on; +static bool force_cap_on; static int can_cap_in_hardware(void) { @@ -170,7 +170,7 @@ static ssize_t set_avg_interval(struct device *dev, unsigned long long data; acpi_status status; - res = strict_strtoul(buf, 10, &temp); + res = kstrtoul(buf, 10, &temp); if (res) return res; @@ -241,7 +241,7 @@ static ssize_t set_cap(struct device *dev, struct device_attribute *devattr, unsigned long long data; acpi_status status; - res = strict_strtoul(buf, 10, &temp); + res = kstrtoul(buf, 10, &temp); if (res) return res; @@ -311,7 +311,7 @@ static ssize_t set_trip(struct device *dev, struct device_attribute *devattr, int res; unsigned long temp; - res = strict_strtoul(buf, 10, &temp); + res = kstrtoul(buf, 10, &temp); if (res) return res; diff --git a/drivers/hwmon/ad7314.c b/drivers/hwmon/ad7314.c index 318e38e8537..5d760f3d21c 100644 --- a/drivers/hwmon/ad7314.c +++ b/drivers/hwmon/ad7314.c @@ -160,7 +160,6 @@ MODULE_DEVICE_TABLE(spi, ad7314_id); static struct spi_driver ad7314_driver = { .driver = { .name = "ad7314", - .bus = &spi_bus_type, .owner = THIS_MODULE, }, .probe = ad7314_probe, diff --git a/drivers/hwmon/adcxx.c b/drivers/hwmon/adcxx.c index b2cacbe707a..ceb24a36517 100644 --- a/drivers/hwmon/adcxx.c +++ b/drivers/hwmon/adcxx.c @@ -125,7 +125,7 @@ static ssize_t adcxx_set_max(struct device *dev, struct adcxx *adc = spi_get_drvdata(spi); unsigned long value; - if (strict_strtoul(buf, 10, &value)) + if (kstrtoul(buf, 10, &value)) return -EINVAL; if (mutex_lock_interruptible(&adc->lock)) diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c index 1ad0a885c5a..0158cc35cb2 100644 --- a/drivers/hwmon/adm1021.c +++ b/drivers/hwmon/adm1021.c @@ -103,7 +103,7 @@ static int adm1021_remove(struct i2c_client *client); static struct adm1021_data *adm1021_update_device(struct device *dev); /* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */ -static int read_only; +static bool read_only; static const struct i2c_device_id adm1021_id[] = { diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c index 0683e6be662..97e2cfb0bc9 100644 --- a/drivers/hwmon/adm1031.c +++ b/drivers/hwmon/adm1031.c @@ -155,7 +155,8 @@ adm1031_write_value(struct i2c_client *client, u8 reg, unsigned int value) #define TEMP_OFFSET_FROM_REG(val) TEMP_FROM_REG((val) < 0 ? \ (val) | 0x70 : (val)) -#define FAN_FROM_REG(reg, div) ((reg) ? (11250 * 60) / ((reg) * (div)) : 0) +#define FAN_FROM_REG(reg, div) ((reg) ? \ + (11250 * 60) / ((reg) * (div)) : 0) static int FAN_TO_REG(int reg, int div) { @@ -174,8 +175,8 @@ static int FAN_TO_REG(int reg, int div) (((reg) & 0x1F) | (((val) << 5) & 0xe0)) #define AUTO_TEMP_MIN_TO_REG(val, reg) \ - ((((val)/500) & 0xf8)|((reg) & 0x7)) -#define AUTO_TEMP_RANGE_FROM_REG(reg) (5000 * (1<< ((reg)&0x7))) + ((((val) / 500) & 0xf8) | ((reg) & 0x7)) +#define AUTO_TEMP_RANGE_FROM_REG(reg) (5000 * (1 << ((reg) & 0x7))) #define AUTO_TEMP_MIN_FROM_REG(reg) (1000 * ((((reg) >> 3) & 0x1f) << 2)) #define AUTO_TEMP_MIN_FROM_REG_DEG(reg) ((((reg) >> 3) & 0x1f) << 2) @@ -202,7 +203,7 @@ static int AUTO_TEMP_MAX_TO_REG(int val, int reg, int pwm) /* FAN auto control */ #define GET_FAN_AUTO_BITFIELD(data, idx) \ - (*(data)->chan_select_table)[FAN_CHAN_FROM_REG((data)->conf1)][idx%2] + (*(data)->chan_select_table)[FAN_CHAN_FROM_REG((data)->conf1)][idx % 2] /* The tables below contains the possible values for the auto fan * control bitfields. the index in the table is the register value. @@ -230,7 +231,7 @@ static const auto_chan_table_t auto_channel_select_table_adm1030 = { */ static int get_fan_auto_nearest(struct adm1031_data *data, - int chan, u8 val, u8 reg, u8 * new_reg) + int chan, u8 val, u8 reg, u8 *new_reg) { int i; int first_match = -1, exact_match = -1; @@ -258,13 +259,13 @@ get_fan_auto_nearest(struct adm1031_data *data, } } - if (exact_match >= 0) { + if (exact_match >= 0) *new_reg = exact_match; - } else if (first_match >= 0) { + else if (first_match >= 0) *new_reg = first_match; - } else { + else return -EINVAL; - } + return 0; } @@ -283,23 +284,28 @@ set_fan_auto_channel(struct device *dev, struct device_attribute *attr, struct i2c_client *client = to_i2c_client(dev); struct adm1031_data *data = i2c_get_clientdata(client); int nr = to_sensor_dev_attr(attr)->index; - int val = simple_strtol(buf, NULL, 10); + long val; u8 reg; int ret; u8 old_fan_mode; + ret = kstrtol(buf, 10, &val); + if (ret) + return ret; + old_fan_mode = data->conf1; mutex_lock(&data->update_lock); - if ((ret = get_fan_auto_nearest(data, nr, val, data->conf1, ®))) { + ret = get_fan_auto_nearest(data, nr, val, data->conf1, ®); + if (ret) { mutex_unlock(&data->update_lock); return ret; } data->conf1 = FAN_CHAN_TO_REG(reg, data->conf1); if ((data->conf1 & ADM1031_CONF1_AUTO_MODE) ^ (old_fan_mode & ADM1031_CONF1_AUTO_MODE)) { - if (data->conf1 & ADM1031_CONF1_AUTO_MODE){ + if (data->conf1 & ADM1031_CONF1_AUTO_MODE) { /* Switch to Auto Fan Mode * Save PWM registers * Set PWM registers to 33% Both */ @@ -350,7 +356,12 @@ set_auto_temp_min(struct device *dev, struct device_attribute *attr, struct i2c_client *client = to_i2c_client(dev); struct adm1031_data *data = i2c_get_clientdata(client); int nr = to_sensor_dev_attr(attr)->index; - int val = simple_strtol(buf, NULL, 10); + long val; + int ret; + + ret = kstrtol(buf, 10, &val); + if (ret) + return ret; mutex_lock(&data->update_lock); data->auto_temp[nr] = AUTO_TEMP_MIN_TO_REG(val, data->auto_temp[nr]); @@ -374,10 +385,16 @@ set_auto_temp_max(struct device *dev, struct device_attribute *attr, struct i2c_client *client = to_i2c_client(dev); struct adm1031_data *data = i2c_get_clientdata(client); int nr = to_sensor_dev_attr(attr)->index; - int val = simple_strtol(buf, NULL, 10); + long val; + int ret; + + ret = kstrtol(buf, 10, &val); + if (ret) + return ret; mutex_lock(&data->update_lock); - data->temp_max[nr] = AUTO_TEMP_MAX_TO_REG(val, data->auto_temp[nr], data->pwm[nr]); + data->temp_max[nr] = AUTO_TEMP_MAX_TO_REG(val, data->auto_temp[nr], + data->pwm[nr]); adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr), data->temp_max[nr]); mutex_unlock(&data->update_lock); @@ -410,8 +427,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, struct i2c_client *client = to_i2c_client(dev); struct adm1031_data *data = i2c_get_clientdata(client); int nr = to_sensor_dev_attr(attr)->index; - int val = simple_strtol(buf, NULL, 10); - int reg; + long val; + int ret, reg; + + ret = kstrtol(buf, 10, &val); + if (ret) + return ret; mutex_lock(&data->update_lock); if ((data->conf1 & ADM1031_CONF1_AUTO_MODE) && @@ -449,9 +470,13 @@ static int trust_fan_readings(struct adm1031_data *data, int chan) if (data->conf1 & ADM1031_CONF1_AUTO_MODE) { switch (data->conf1 & 0x60) { - case 0x00: /* remote temp1 controls fan1 remote temp2 controls fan2 */ + case 0x00: + /* + * remote temp1 controls fan1, + * remote temp2 controls fan2 + */ res = data->temp[chan+1] >= - AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[chan+1]); + AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[chan+1]); break; case 0x20: /* remote temp1 controls both fans */ res = @@ -515,7 +540,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, struct i2c_client *client = to_i2c_client(dev); struct adm1031_data *data = i2c_get_clientdata(client); int nr = to_sensor_dev_attr(attr)->index; - int val = simple_strtol(buf, NULL, 10); + long val; + int ret; + + ret = kstrtol(buf, 10, &val); + if (ret) + return ret; mutex_lock(&data->update_lock); if (val) { @@ -534,10 +564,15 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, struct i2c_client *client = to_i2c_client(dev); struct adm1031_data *data = i2c_get_clientdata(client); int nr = to_sensor_dev_attr(attr)->index; - int val = simple_strtol(buf, NULL, 10); + long val; u8 tmp; int old_div; int new_min; + int ret; + + ret = kstrtol(buf, 10, &val); + if (ret) + return ret; tmp = val == 8 ? 0xc0 : val == 4 ? 0x80 : @@ -631,9 +666,13 @@ static ssize_t set_temp_offset(struct device *dev, struct i2c_client *client = to_i2c_client(dev); struct adm1031_data *data = i2c_get_clientdata(client); int nr = to_sensor_dev_attr(attr)->index; - int val; + long val; + int ret; + + ret = kstrtol(buf, 10, &val); + if (ret) + return ret; - val = simple_strtol(buf, NULL, 10); val = SENSORS_LIMIT(val, -15000, 15000); mutex_lock(&data->update_lock); data->temp_offset[nr] = TEMP_OFFSET_TO_REG(val); @@ -648,9 +687,13 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, struct i2c_client *client = to_i2c_client(dev); struct adm1031_data *data = i2c_get_clientdata(client); int nr = to_sensor_dev_attr(attr)->index; - int val; + long val; + int ret; + + ret = kstrtol(buf, 10, &val); + if (ret) + return ret; - val = simple_strtol(buf, NULL, 10); val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875); mutex_lock(&data->update_lock); data->temp_min[nr] = TEMP_TO_REG(val); @@ -665,9 +708,13 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, struct i2c_client *client = to_i2c_client(dev); struct adm1031_data *data = i2c_get_clientdata(client); int nr = to_sensor_dev_attr(attr)->index; - int val; + long val; + int ret; + + ret = kstrtol(buf, 10, &val); + if (ret) + return ret; - val = simple_strtol(buf, NULL, 10); val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875); mutex_lock(&data->update_lock); data->temp_max[nr] = TEMP_TO_REG(val); @@ -682,9 +729,13 @@ static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr, struct i2c_client *client = to_i2c_client(dev); struct adm1031_data *data = i2c_get_clientdata(client); int nr = to_sensor_dev_attr(attr)->index; - int val; + long val; + int ret; + + ret = kstrtol(buf, 10, &val); + if (ret) + return ret; - val = simple_strtol(buf, NULL, 10); val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875); mutex_lock(&data->update_lock); data->temp_crit[nr] = TEMP_TO_REG(val); @@ -711,7 +762,8 @@ temp_reg(2); temp_reg(3); /* Alarms */ -static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, + char *buf) { struct adm1031_data *data = adm1031_update_device(dev); return sprintf(buf, "%d\n", data->alarm); @@ -767,7 +819,7 @@ static ssize_t set_update_interval(struct device *dev, int i, err; u8 reg; - err = strict_strtoul(buf, 10, &val); + err = kstrtoul(buf, 10, &val); if (err) return err; @@ -919,12 +971,13 @@ static int adm1031_probe(struct i2c_client *client, adm1031_init_client(client); /* Register sysfs hooks */ - if ((err = sysfs_create_group(&client->dev.kobj, &adm1031_group))) + err = sysfs_create_group(&client->dev.kobj, &adm1031_group); + if (err) goto exit_free; if (data->chip_type == adm1031) { - if ((err = sysfs_create_group(&client->dev.kobj, - &adm1031_group_opt))) + err = sysfs_create_group(&client->dev.kobj, &adm1031_group_opt); + if (err) goto exit_remove; } @@ -970,14 +1023,13 @@ static void adm1031_init_client(struct i2c_client *client) } /* Initialize the ADM1031 chip (enables fan speed reading ) */ read_val = adm1031_read_value(client, ADM1031_REG_CONF2); - if ((read_val | mask) != read_val) { - adm1031_write_value(client, ADM1031_REG_CONF2, read_val | mask); - } + if ((read_val | mask) != read_val) + adm1031_write_value(client, ADM1031_REG_CONF2, read_val | mask); read_val = adm1031_read_value(client, ADM1031_REG_CONF1); if ((read_val | ADM1031_CONF1_MONITOR_ENABLE) != read_val) { - adm1031_write_value(client, ADM1031_REG_CONF1, read_val | - ADM1031_CONF1_MONITOR_ENABLE); + adm1031_write_value(client, ADM1031_REG_CONF1, + read_val | ADM1031_CONF1_MONITOR_ENABLE); } /* Read the chip's update rate */ @@ -1024,8 +1076,7 @@ static struct adm1031_data *adm1031_update_device(struct device *dev) /* oldh is actually newer */ if (newh != oldh) dev_warn(&client->dev, - "Remote temperature may be " - "wrong.\n"); + "Remote temperature may be wrong.\n"); #endif } data->temp[chan] = newh; @@ -1052,22 +1103,24 @@ static struct adm1031_data *adm1031_update_device(struct device *dev) data->conf2 = adm1031_read_value(client, ADM1031_REG_CONF2); data->alarm = adm1031_read_value(client, ADM1031_REG_STATUS(0)) - | (adm1031_read_value(client, ADM1031_REG_STATUS(1)) - << 8); - if (data->chip_type == adm1030) { + | (adm1031_read_value(client, ADM1031_REG_STATUS(1)) << 8); + if (data->chip_type == adm1030) data->alarm &= 0xc0ff; - } - for (chan=0; chan<(data->chip_type == adm1030 ? 1 : 2); chan++) { + for (chan = 0; chan < (data->chip_type == adm1030 ? 1 : 2); + chan++) { data->fan_div[chan] = - adm1031_read_value(client, ADM1031_REG_FAN_DIV(chan)); + adm1031_read_value(client, + ADM1031_REG_FAN_DIV(chan)); data->fan_min[chan] = - adm1031_read_value(client, ADM1031_REG_FAN_MIN(chan)); + adm1031_read_value(client, + ADM1031_REG_FAN_MIN(chan)); data->fan[chan] = - adm1031_read_value(client, ADM1031_REG_FAN_SPEED(chan)); + adm1031_read_value(client, + ADM1031_REG_FAN_SPEED(chan)); data->pwm[chan] = - 0xf & (adm1031_read_value(client, ADM1031_REG_PWM) >> - (4*chan)); + (adm1031_read_value(client, + ADM1031_REG_PWM) >> (4 * chan)) & 0x0f; } data->last_updated = jiffies; data->valid = 1; diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index 9e234b981b8..3f63f5f9741 100644 --- a/drivers/hwmon/adm9240.c +++ b/drivers/hwmon/adm9240.c @@ -503,7 +503,7 @@ static ssize_t chassis_clear(struct device *dev, struct adm9240_data *data = i2c_get_clientdata(client); unsigned long val; - if (strict_strtoul(buf, 10, &val) || val != 0) + if (kstrtoul(buf, 10, &val) || val != 0) return -EINVAL; mutex_lock(&data->update_lock); diff --git a/drivers/hwmon/ads1015.c b/drivers/hwmon/ads1015.c index eedca3cf996..dd87ae96c26 100644 --- a/drivers/hwmon/ads1015.c +++ b/drivers/hwmon/ads1015.c @@ -271,7 +271,7 @@ static int ads1015_probe(struct i2c_client *client, continue; err = device_create_file(&client->dev, &ads1015_in[k].dev_attr); if (err) - goto exit_free; + goto exit_remove; } data->hwmon_dev = hwmon_device_register(&client->dev); @@ -285,7 +285,6 @@ static int ads1015_probe(struct i2c_client *client, exit_remove: for (k = 0; k < ADS1015_CHANNELS; ++k) device_remove_file(&client->dev, &ads1015_in[k].dev_attr); -exit_free: kfree(data); exit: return err; diff --git a/drivers/hwmon/ads7828.c b/drivers/hwmon/ads7828.c index cfcc3b6fb6b..ed60242d6a0 100644 --- a/drivers/hwmon/ads7828.c +++ b/drivers/hwmon/ads7828.c @@ -48,8 +48,8 @@ static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, I2C_CLIENT_END }; /* Module parameters */ -static int se_input = 1; /* Default is SE, 0 == diff */ -static int int_vref = 1; /* Default is internal ref ON */ +static bool se_input = 1; /* Default is SE, 0 == diff */ +static bool int_vref = 1; /* Default is internal ref ON */ static int vref_mv = ADS7828_INT_VREF_MV; /* set if vref != 2.5V */ module_param(se_input, bool, S_IRUGO); module_param(int_vref, bool, S_IRUGO); diff --git a/drivers/hwmon/ads7871.c b/drivers/hwmon/ads7871.c index 52319340e18..04450f8bf5d 100644 --- a/drivers/hwmon/ads7871.c +++ b/drivers/hwmon/ads7871.c @@ -227,7 +227,6 @@ static int __devexit ads7871_remove(struct spi_device *spi) static struct spi_driver ads7871_driver = { .driver = { .name = DEVICE_NAME, - .bus = &spi_bus_type, .owner = THIS_MODULE, }, diff --git a/drivers/hwmon/adt7411.c b/drivers/hwmon/adt7411.c index 5cc3e3784b4..5b02f7a9101 100644 --- a/drivers/hwmon/adt7411.c +++ b/drivers/hwmon/adt7411.c @@ -197,7 +197,7 @@ static ssize_t adt7411_set_bit(struct device *dev, int ret; unsigned long flag; - ret = strict_strtoul(buf, 0, &flag); + ret = kstrtoul(buf, 0, &flag); if (ret || flag > 1) return -EINVAL; diff --git a/drivers/hwmon/adt7462.c b/drivers/hwmon/adt7462.c index 2af0c7b6b4e..7a1494846cf 100644 --- a/drivers/hwmon/adt7462.c +++ b/drivers/hwmon/adt7462.c @@ -833,7 +833,7 @@ static ssize_t set_temp_min(struct device *dev, struct adt7462_data *data = i2c_get_clientdata(client); long temp; - if (strict_strtol(buf, 10, &temp) || !temp_enabled(data, attr->index)) + if (kstrtol(buf, 10, &temp) || !temp_enabled(data, attr->index)) return -EINVAL; temp = DIV_ROUND_CLOSEST(temp, 1000) + 64; @@ -871,7 +871,7 @@ static ssize_t set_temp_max(struct device *dev, struct adt7462_data *data = i2c_get_clientdata(client); long temp; - if (strict_strtol(buf, 10, &temp) || !temp_enabled(data, attr->index)) + if (kstrtol(buf, 10, &temp) || !temp_enabled(data, attr->index)) return -EINVAL; temp = DIV_ROUND_CLOSEST(temp, 1000) + 64; @@ -935,7 +935,7 @@ static ssize_t set_volt_max(struct device *dev, int x = voltage_multiplier(data, attr->index); long temp; - if (strict_strtol(buf, 10, &temp) || !x) + if (kstrtol(buf, 10, &temp) || !x) return -EINVAL; temp *= 1000; /* convert mV to uV */ @@ -977,7 +977,7 @@ static ssize_t set_volt_min(struct device *dev, int x = voltage_multiplier(data, attr->index); long temp; - if (strict_strtol(buf, 10, &temp) || !x) + if (kstrtol(buf, 10, &temp) || !x) return -EINVAL; temp *= 1000; /* convert mV to uV */ @@ -1066,7 +1066,7 @@ static ssize_t set_fan_min(struct device *dev, struct adt7462_data *data = i2c_get_clientdata(client); long temp; - if (strict_strtol(buf, 10, &temp) || !temp || + if (kstrtol(buf, 10, &temp) || !temp || !fan_enabled(data, attr->index)) return -EINVAL; @@ -1115,7 +1115,7 @@ static ssize_t set_force_pwm_max(struct device *dev, long temp; u8 reg; - if (strict_strtol(buf, 10, &temp)) + if (kstrtol(buf, 10, &temp)) return -EINVAL; mutex_lock(&data->lock); @@ -1147,7 +1147,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, struct adt7462_data *data = i2c_get_clientdata(client); long temp; - if (strict_strtol(buf, 10, &temp)) + if (kstrtol(buf, 10, &temp)) return -EINVAL; temp = SENSORS_LIMIT(temp, 0, 255); @@ -1177,7 +1177,7 @@ static ssize_t set_pwm_max(struct device *dev, struct adt7462_data *data = i2c_get_clientdata(client); long temp; - if (strict_strtol(buf, 10, &temp)) + if (kstrtol(buf, 10, &temp)) return -EINVAL; temp = SENSORS_LIMIT(temp, 0, 255); @@ -1209,7 +1209,7 @@ static ssize_t set_pwm_min(struct device *dev, struct adt7462_data *data = i2c_get_clientdata(client); long temp; - if (strict_strtol(buf, 10, &temp)) + if (kstrtol(buf, 10, &temp)) return -EINVAL; temp = SENSORS_LIMIT(temp, 0, 255); @@ -1243,7 +1243,7 @@ static ssize_t set_pwm_hyst(struct device *dev, struct adt7462_data *data = i2c_get_clientdata(client); long temp; - if (strict_strtol(buf, 10, &temp)) + if (kstrtol(buf, 10, &temp)) return -EINVAL; temp = DIV_ROUND_CLOSEST(temp, 1000); @@ -1289,7 +1289,7 @@ static ssize_t set_pwm_tmax(struct device *dev, int tmin, trange_value; long trange; - if (strict_strtol(buf, 10, &trange)) + if (kstrtol(buf, 10, &trange)) return -EINVAL; /* trange = tmax - tmin */ @@ -1330,7 +1330,7 @@ static ssize_t set_pwm_tmin(struct device *dev, struct adt7462_data *data = i2c_get_clientdata(client); long temp; - if (strict_strtol(buf, 10, &temp)) + if (kstrtol(buf, 10, &temp)) return -EINVAL; temp = DIV_ROUND_CLOSEST(temp, 1000) + 64; @@ -1387,7 +1387,7 @@ static ssize_t set_pwm_auto(struct device *dev, struct adt7462_data *data = i2c_get_clientdata(client); long temp; - if (strict_strtol(buf, 10, &temp)) + if (kstrtol(buf, 10, &temp)) return -EINVAL; switch (temp) { @@ -1446,7 +1446,7 @@ static ssize_t set_pwm_auto_temp(struct device *dev, struct adt7462_data *data = i2c_get_clientdata(client); long temp; - if (strict_strtol(buf, 10, &temp)) + if (kstrtol(buf, 10, &temp)) return -EINVAL; temp = cvt_auto_temp(temp); diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c index c6d1ce059ae..5e10c79f2df 100644 --- a/drivers/hwmon/adt7470.c +++ b/drivers/hwmon/adt7470.c @@ -449,7 +449,7 @@ static ssize_t set_auto_update_interval(struct device *dev, struct adt7470_data *data = i2c_get_clientdata(client); long temp; - if (strict_strtol(buf, 10, &temp)) + if (kstrtol(buf, 10, &temp)) return -EINVAL; temp = SENSORS_LIMIT(temp, 0, 60000); @@ -478,7 +478,7 @@ static ssize_t set_num_temp_sensors(struct device *dev, struct adt7470_data *data = i2c_get_clientdata(client); long temp; - if (strict_strtol(buf, 10, &temp)) + if (kstrtol(buf, 10, &temp)) return -EINVAL; temp = SENSORS_LIMIT(temp, -1, 10); @@ -511,7 +511,7 @@ static ssize_t set_temp_min(struct device *dev, struct adt7470_data *data = i2c_get_clientdata(client); long temp; - if (strict_strtol(buf, 10, &temp)) + if (kstrtol(buf, 10, &temp)) return -EINVAL; temp = DIV_ROUND_CLOSEST(temp, 1000); @@ -545,7 +545,7 @@ static ssize_t set_temp_max(struct device *dev, struct adt7470_data *data = i2c_get_clientdata(client); long temp; - if (strict_strtol(buf, 10, &temp)) + if (kstrtol(buf, 10, &temp)) return -EINVAL; temp = DIV_ROUND_CLOSEST(temp, 1000); @@ -600,7 +600,7 @@ static ssize_t set_fan_max(struct device *dev, struct adt7470_data *data = i2c_get_clientdata(client); long temp; - if (strict_strtol(buf, 10, &temp) || !temp) + if (kstrtol(buf, 10, &temp) || !temp) return -EINVAL; temp = FAN_RPM_TO_PERIOD(temp); @@ -637,7 +637,7 @@ static ssize_t set_fan_min(struct device *dev, struct adt7470_data *data = i2c_get_clientdata(client); long temp; - if (strict_strtol(buf, 10, &temp) || !temp) + if (kstrtol(buf, 10, &temp) || !temp) return -EINVAL; temp = FAN_RPM_TO_PERIOD(temp); @@ -682,7 +682,7 @@ static ssize_t set_force_pwm_max(struct device *dev, long temp; u8 reg; - if (strict_strtol(buf, 10, &temp)) + if (kstrtol(buf, 10, &temp)) return -EINVAL; mutex_lock(&data->lock); @@ -714,7 +714,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, struct adt7470_data *data = i2c_get_clientdata(client); long temp; - if (strict_strtol(buf, 10, &temp)) + if (kstrtol(buf, 10, &temp)) return -EINVAL; temp = SENSORS_LIMIT(temp, 0, 255); @@ -746,7 +746,7 @@ static ssize_t set_pwm_max(struct device *dev, struct adt7470_data *data = i2c_get_clientdata(client); long temp; - if (strict_strtol(buf, 10, &temp)) + if (kstrtol(buf, 10, &temp)) return -EINVAL; temp = SENSORS_LIMIT(temp, 0, 255); @@ -779,7 +779,7 @@ static ssize_t set_pwm_min(struct device *dev, struct adt7470_data *data = i2c_get_clientdata(client); long temp; - if (strict_strtol(buf, 10, &temp)) + if (kstrtol(buf, 10, &temp)) return -EINVAL; temp = SENSORS_LIMIT(temp, 0, 255); @@ -822,7 +822,7 @@ static ssize_t set_pwm_tmin(struct device *dev, struct adt7470_data *data = i2c_get_clientdata(client); long temp; - if (strict_strtol(buf, 10, &temp)) + if (kstrtol(buf, 10, &temp)) return -EINVAL; temp = DIV_ROUND_CLOSEST(temp, 1000); @@ -859,7 +859,7 @@ static ssize_t set_pwm_auto(struct device *dev, long temp; u8 reg; - if (strict_strtol(buf, 10, &temp)) + if (kstrtol(buf, 10, &temp)) return -EINVAL; if (attr->index % 2) @@ -919,7 +919,7 @@ static ssize_t set_pwm_auto_temp(struct device *dev, long temp; u8 reg; - if (strict_strtol(buf, 10, &temp)) + if (kstrtol(buf, 10, &temp)) return -EINVAL; temp = cvt_auto_temp(temp); diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c index b5fcd87931c..7dab3547fee 100644 --- a/drivers/hwmon/adt7475.c +++ b/drivers/hwmon/adt7475.c @@ -343,7 +343,7 @@ static ssize_t set_voltage(struct device *dev, struct device_attribute *attr, unsigned char reg; long val; - if (strict_strtol(buf, 10, &val)) + if (kstrtol(buf, 10, &val)) return -EINVAL; mutex_lock(&data->lock); @@ -432,7 +432,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr, int temp; long val; - if (strict_strtol(buf, 10, &val)) + if (kstrtol(buf, 10, &val)) return -EINVAL; mutex_lock(&data->lock); @@ -546,7 +546,7 @@ static ssize_t set_point2(struct device *dev, struct device_attribute *attr, int temp; long val; - if (strict_strtol(buf, 10, &val)) + if (kstrtol(buf, 10, &val)) return -EINVAL; mutex_lock(&data->lock); @@ -602,7 +602,7 @@ static ssize_t set_tach(struct device *dev, struct device_attribute *attr, struct adt7475_data *data = i2c_get_clientdata(client); unsigned long val; - if (strict_strtoul(buf, 10, &val)) + if (kstrtoul(buf, 10, &val)) return -EINVAL; mutex_lock(&data->lock); @@ -653,7 +653,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, unsigned char reg = 0; long val; - if (strict_strtol(buf, 10, &val)) + if (kstrtol(buf, 10, &val)) return -EINVAL; mutex_lock(&data->lock); @@ -758,7 +758,7 @@ static ssize_t set_pwmchan(struct device *dev, struct device_attribute *attr, int r; long val; - if (strict_strtol(buf, 10, &val)) + if (kstrtol(buf, 10, &val)) return -EINVAL; mutex_lock(&data->lock); @@ -781,7 +781,7 @@ static ssize_t set_pwmctrl(struct device *dev, struct device_attribute *attr, int r; long val; - if (strict_strtol(buf, 10, &val)) + if (kstrtol(buf, 10, &val)) return -EINVAL; mutex_lock(&data->lock); @@ -819,7 +819,7 @@ static ssize_t set_pwmfreq(struct device *dev, struct device_attribute *attr, int out; long val; - if (strict_strtol(buf, 10, &val)) + if (kstrtol(buf, 10, &val)) return -EINVAL; out = find_nearest(val, pwmfreq_table, ARRAY_SIZE(pwmfreq_table)); @@ -853,7 +853,7 @@ static ssize_t set_pwm_at_crit(struct device *dev, struct adt7475_data *data = i2c_get_clientdata(client); long val; - if (strict_strtol(buf, 10, &val)) + if (kstrtol(buf, 10, &val)) return -EINVAL; if (val != 0 && val != 1) return -EINVAL; @@ -883,7 +883,7 @@ static ssize_t set_vrm(struct device *dev, struct device_attribute *devattr, struct adt7475_data *data = dev_get_drvdata(dev); long val; - if (strict_strtol(buf, 10, &val)) + if (kstrtol(buf, 10, &val)) return -EINVAL; if (val < 0 || val > 255) return -EINVAL; diff --git a/drivers/hwmon/amc6821.c b/drivers/hwmon/amc6821.c index 4033974d1bb..89a6b9da0ec 100644 --- a/drivers/hwmon/amc6821.c +++ b/drivers/hwmon/amc6821.c @@ -238,7 +238,7 @@ static ssize_t set_temp( int ix = to_sensor_dev_attr(attr)->index; long val; - int ret = strict_strtol(buf, 10, &val); + int ret = kstrtol(buf, 10, &val); if (ret) return ret; val = SENSORS_LIMIT(val / 1000, -128, 127); @@ -327,7 +327,7 @@ static ssize_t set_pwm1( struct i2c_client *client = to_i2c_client(dev); struct amc6821_data *data = i2c_get_clientdata(client); long val; - int ret = strict_strtol(buf, 10, &val); + int ret = kstrtol(buf, 10, &val); if (ret) return ret; @@ -356,7 +356,7 @@ static ssize_t set_pwm1_enable( struct i2c_client *client = to_i2c_client(dev); struct amc6821_data *data = i2c_get_clientdata(client); long val; - int config = strict_strtol(buf, 10, &val); + int config = kstrtol(buf, 10, &val); if (config) return config; @@ -477,7 +477,7 @@ static ssize_t set_temp_auto_point_temp( u8 reg; int dpwm; long val; - int ret = strict_strtol(buf, 10, &val); + int ret = kstrtol(buf, 10, &val); if (ret) return ret; @@ -556,7 +556,7 @@ static ssize_t set_pwm1_auto_point_pwm( struct amc6821_data *data = i2c_get_clientdata(client); int dpwm; long val; - int ret = strict_strtol(buf, 10, &val); + int ret = kstrtol(buf, 10, &val); if (ret) return ret; @@ -623,7 +623,7 @@ static ssize_t set_fan( struct amc6821_data *data = i2c_get_clientdata(client); long val; int ix = to_sensor_dev_attr(attr)->index; - int ret = strict_strtol(buf, 10, &val); + int ret = kstrtol(buf, 10, &val); if (ret) return ret; val = 1 > val ? 0xFFFF : 6000000/val; @@ -665,7 +665,7 @@ static ssize_t set_fan1_div( struct i2c_client *client = to_i2c_client(dev); struct amc6821_data *data = i2c_get_clientdata(client); long val; - int config = strict_strtol(buf, 10, &val); + int config = kstrtol(buf, 10, &val); if (config) return config; diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 4c0743660e9..b9895531240 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -782,7 +782,7 @@ static ssize_t applesmc_store_fan_speed(struct device *dev, char newkey[5]; u8 buffer[2]; - if (strict_strtoul(sysfsbuf, 10, &speed) < 0 || speed >= 0x4000) + if (kstrtoul(sysfsbuf, 10, &speed) < 0 || speed >= 0x4000) return -EINVAL; /* Bigger than a 14-bit value */ sprintf(newkey, fan_speed_fmt[to_option(attr)], to_index(attr)); @@ -822,7 +822,7 @@ static ssize_t applesmc_store_fan_manual(struct device *dev, unsigned long input; u16 val; - if (strict_strtoul(sysfsbuf, 10, &input) < 0) + if (kstrtoul(sysfsbuf, 10, &input) < 0) return -EINVAL; ret = applesmc_read_key(FANS_MANUAL, buffer, 2); @@ -977,7 +977,7 @@ static ssize_t applesmc_key_at_index_store(struct device *dev, { unsigned long newkey; - if (strict_strtoul(sysfsbuf, 10, &newkey) < 0 + if (kstrtoul(sysfsbuf, 10, &newkey) < 0 || newkey >= smcreg.key_count) return -EINVAL; diff --git a/drivers/hwmon/asc7621.c b/drivers/hwmon/asc7621.c index d2596cec18b..3efd3244998 100644 --- a/drivers/hwmon/asc7621.c +++ b/drivers/hwmon/asc7621.c @@ -188,7 +188,7 @@ static ssize_t store_u8(struct device *dev, struct device_attribute *attr, SETUP_STORE_data_param(dev, attr); long reqval; - if (strict_strtol(buf, 10, &reqval)) + if (kstrtol(buf, 10, &reqval)) return -EINVAL; reqval = SENSORS_LIMIT(reqval, 0, 255); @@ -221,7 +221,7 @@ static ssize_t store_bitmask(struct device *dev, long reqval; u8 currval; - if (strict_strtol(buf, 10, &reqval)) + if (kstrtol(buf, 10, &reqval)) return -EINVAL; reqval = SENSORS_LIMIT(reqval, 0, param->mask[0]); @@ -265,7 +265,7 @@ static ssize_t store_fan16(struct device *dev, SETUP_STORE_data_param(dev, attr); long reqval; - if (strict_strtol(buf, 10, &reqval)) + if (kstrtol(buf, 10, &reqval)) return -EINVAL; /* If a minimum RPM of zero is requested, then we set the register to @@ -338,7 +338,7 @@ static ssize_t store_in8(struct device *dev, struct device_attribute *attr, long reqval; u8 nr = sda->index; - if (strict_strtol(buf, 10, &reqval)) + if (kstrtol(buf, 10, &reqval)) return -EINVAL; reqval = SENSORS_LIMIT(reqval, 0, 0xffff); @@ -371,7 +371,7 @@ static ssize_t store_temp8(struct device *dev, long reqval; s8 temp; - if (strict_strtol(buf, 10, &reqval)) + if (kstrtol(buf, 10, &reqval)) return -EINVAL; reqval = SENSORS_LIMIT(reqval, -127000, 127000); @@ -427,7 +427,7 @@ static ssize_t store_temp62(struct device *dev, long reqval, i, f; s8 temp; - if (strict_strtol(buf, 10, &reqval)) + if (kstrtol(buf, 10, &reqval)) return -EINVAL; reqval = SENSORS_LIMIT(reqval, -32000, 31750); @@ -482,7 +482,7 @@ static ssize_t store_ap2_temp(struct device *dev, int i; u8 currval, newval = 0; - if (strict_strtol(buf, 10, &reqval)) + if (kstrtol(buf, 10, &reqval)) return -EINVAL; mutex_lock(&data->update_lock); @@ -538,7 +538,7 @@ static ssize_t store_pwm_ac(struct device *dev, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, }; - if (strict_strtoul(buf, 10, &reqval)) + if (kstrtoul(buf, 10, &reqval)) return -EINVAL; if (reqval > 31) @@ -601,7 +601,7 @@ static ssize_t store_pwm_enable(struct device *dev, long reqval; u8 currval, config, altbit, newval, minoff = 255; - if (strict_strtol(buf, 10, &reqval)) + if (kstrtol(buf, 10, &reqval)) return -EINVAL; switch (reqval) { @@ -675,7 +675,7 @@ static ssize_t store_pwm_freq(struct device *dev, u8 currval, newval = 255; int i; - if (strict_strtoul(buf, 10, &reqval)) + if (kstrtoul(buf, 10, &reqval)) return -EINVAL; for (i = 0; i < ARRAY_SIZE(asc7621_pwm_freq_map); i++) { @@ -724,7 +724,7 @@ static ssize_t store_pwm_ast(struct device *dev, u8 currval, newval = 255; u32 i; - if (strict_strtol(buf, 10, &reqval)) + if (kstrtol(buf, 10, &reqval)) return -EINVAL; for (i = 0; i < ARRAY_SIZE(asc7621_pwm_auto_spinup_map); i++) { @@ -771,7 +771,7 @@ static ssize_t store_temp_st(struct device *dev, u8 currval, newval = 255; u32 i; - if (strict_strtol(buf, 10, &reqval)) + if (kstrtol(buf, 10, &reqval)) return -EINVAL; for (i = 0; i < ARRAY_SIZE(asc7621_temp_smoothing_time_map); i++) { diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 104b3767516..a6c6ec36615 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -57,16 +57,15 @@ MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius"); #define TOTAL_ATTRS (MAX_CORE_ATTRS + 1) #define MAX_CORE_DATA (NUM_REAL_CORES + BASE_SYSFS_ATTR_NO) -#ifdef CONFIG_SMP #define TO_PHYS_ID(cpu) cpu_data(cpu).phys_proc_id #define TO_CORE_ID(cpu) cpu_data(cpu).cpu_core_id +#define TO_ATTR_NO(cpu) (TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO) + +#ifdef CONFIG_SMP #define for_each_sibling(i, cpu) for_each_cpu(i, cpu_sibling_mask(cpu)) #else -#define TO_PHYS_ID(cpu) (cpu) -#define TO_CORE_ID(cpu) (cpu) #define for_each_sibling(i, cpu) for (i = 0; false; ) #endif -#define TO_ATTR_NO(cpu) (TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO) /* * Per-Core Temperature Data @@ -191,7 +190,8 @@ static ssize_t show_temp(struct device *dev, return tdata->valid ? sprintf(buf, "%d\n", tdata->temp) : -EAGAIN; } -static int adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) +static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, + struct device *dev) { /* The 100C is default for both mobile and non mobile CPUs */ @@ -285,7 +285,8 @@ static int adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) return tjmax; } -static int get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) +static int __cpuinit get_tjmax(struct cpuinfo_x86 *c, u32 id, + struct device *dev) { int err; u32 eax, edx; @@ -324,7 +325,8 @@ static int get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) return adjust_tjmax(c, id, dev); } -static int create_name_attr(struct platform_data *pdata, struct device *dev) +static int __devinit create_name_attr(struct platform_data *pdata, + struct device *dev) { sysfs_attr_init(&pdata->name_attr.attr); pdata->name_attr.attr.name = "name"; @@ -333,8 +335,8 @@ static int create_name_attr(struct platform_data *pdata, struct device *dev) return device_create_file(dev, &pdata->name_attr); } -static int create_core_attrs(struct temp_data *tdata, struct device *dev, - int attr_no) +static int __cpuinit create_core_attrs(struct temp_data *tdata, + struct device *dev, int attr_no) { int err, i; static ssize_t (*const rd_ptr[TOTAL_ATTRS]) (struct device *dev, @@ -384,7 +386,7 @@ static int __cpuinit chk_ucode_version(unsigned int cpu) return 0; } -static struct platform_device *coretemp_get_pdev(unsigned int cpu) +static struct platform_device __cpuinit *coretemp_get_pdev(unsigned int cpu) { u16 phys_proc_id = TO_PHYS_ID(cpu); struct pdev_entry *p; @@ -401,7 +403,8 @@ static struct platform_device *coretemp_get_pdev(unsigned int cpu) return NULL; } -static struct temp_data *init_temp_data(unsigned int cpu, int pkg_flag) +static struct temp_data __cpuinit *init_temp_data(unsigned int cpu, + int pkg_flag) { struct temp_data *tdata; @@ -419,7 +422,7 @@ static struct temp_data *init_temp_data(unsigned int cpu, int pkg_flag) return tdata; } -static int create_core_data(struct platform_device *pdev, +static int __cpuinit create_core_data(struct platform_device *pdev, unsigned int cpu, int pkg_flag) { struct temp_data *tdata; @@ -490,7 +493,7 @@ exit_free: return err; } -static void coretemp_add_core(unsigned int cpu, int pkg_flag) +static void __cpuinit coretemp_add_core(unsigned int cpu, int pkg_flag) { struct platform_device *pdev = coretemp_get_pdev(cpu); int err; @@ -619,7 +622,7 @@ exit: return err; } -static void coretemp_device_remove(unsigned int cpu) +static void __cpuinit coretemp_device_remove(unsigned int cpu) { struct pdev_entry *p, *n; u16 phys_proc_id = TO_PHYS_ID(cpu); @@ -635,7 +638,7 @@ static void coretemp_device_remove(unsigned int cpu) mutex_unlock(&pdev_list_mutex); } -static bool is_any_core_online(struct platform_data *pdata) +static bool __cpuinit is_any_core_online(struct platform_data *pdata) { int i; diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c index d9c59271391..ffb229af786 100644 --- a/drivers/hwmon/dme1737.c +++ b/drivers/hwmon/dme1737.c @@ -45,7 +45,7 @@ static struct platform_device *pdev; /* Module load parameters */ -static int force_start; +static bool force_start; module_param(force_start, bool, 0); MODULE_PARM_DESC(force_start, "Force the chip to start monitoring inputs"); @@ -53,7 +53,7 @@ static unsigned short force_id; module_param(force_id, ushort, 0); MODULE_PARM_DESC(force_id, "Override the detected device ID"); -static int probe_all_addr; +static bool probe_all_addr; module_param(probe_all_addr, bool, 0); MODULE_PARM_DESC(probe_all_addr, "Include probing of non-standard LPC " "addresses"); @@ -1223,7 +1223,7 @@ static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, } static struct attribute *dme1737_pwm_chmod_attr[]; -static void dme1737_chmod_file(struct device*, struct attribute*, mode_t); +static void dme1737_chmod_file(struct device*, struct attribute*, umode_t); static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -1961,7 +1961,7 @@ static inline void dme1737_sio_outb(int sio_cip, int reg, int val) static int dme1737_i2c_get_features(int, struct dme1737_data*); static void dme1737_chmod_file(struct device *dev, - struct attribute *attr, mode_t mode) + struct attribute *attr, umode_t mode) { if (sysfs_chmod_file(&dev->kobj, attr, mode)) { dev_warn(dev, "Failed to change permissions of %s.\n", @@ -1971,7 +1971,7 @@ static void dme1737_chmod_file(struct device *dev, static void dme1737_chmod_group(struct device *dev, const struct attribute_group *group, - mode_t mode) + umode_t mode) { struct attribute **attr; diff --git a/drivers/hwmon/ds620.c b/drivers/hwmon/ds620.c index 225ae4f3658..300c3d4d67d 100644 --- a/drivers/hwmon/ds620.c +++ b/drivers/hwmon/ds620.c @@ -161,7 +161,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da, struct i2c_client *client = to_i2c_client(dev); struct ds620_data *data = i2c_get_clientdata(client); - res = strict_strtol(buf, 10, &val); + res = kstrtol(buf, 10, &val); if (res) return res; diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c index cd2a6e437ae..270ffab711c 100644 --- a/drivers/hwmon/emc1403.c +++ b/drivers/hwmon/emc1403.c @@ -80,7 +80,7 @@ static ssize_t store_temp(struct device *dev, unsigned long val; int retval; - if (strict_strtoul(buf, 10, &val)) + if (kstrtoul(buf, 10, &val)) return -EINVAL; retval = i2c_smbus_write_byte_data(client, sda->index, DIV_ROUND_CLOSEST(val, 1000)); @@ -98,7 +98,7 @@ static ssize_t store_bit(struct device *dev, unsigned long val; int retval; - if (strict_strtoul(buf, 10, &val)) + if (kstrtoul(buf, 10, &val)) return -EINVAL; mutex_lock(&data->mutex); @@ -151,7 +151,7 @@ static ssize_t store_hyst(struct device *dev, int hyst; unsigned long val; - if (strict_strtoul(buf, 10, &val)) + if (kstrtoul(buf, 10, &val)) return -EINVAL; mutex_lock(&data->mutex); diff --git a/drivers/hwmon/emc2103.c b/drivers/hwmon/emc2103.c index af914ad93ec..865063914d7 100644 --- a/drivers/hwmon/emc2103.c +++ b/drivers/hwmon/emc2103.c @@ -55,7 +55,7 @@ static const u8 REG_TEMP_MAX[4] = { 0x34, 0x30, 0x31, 0x32 }; * it. Default is to leave the device in the state it's already in (-1). * This parameter allows APD mode to be optionally forced on or off */ static int apd = -1; -module_param(apd, bool, 0); +module_param(apd, bint, 0); MODULE_PARM_DESC(init, "Set to zero to disable anti-parallel diode mode"); struct temperature { @@ -244,7 +244,7 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *da, struct emc2103_data *data = i2c_get_clientdata(client); long val; - int result = strict_strtol(buf, 10, &val); + int result = kstrtol(buf, 10, &val); if (result < 0) return -EINVAL; @@ -268,7 +268,7 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *da, struct emc2103_data *data = i2c_get_clientdata(client); long val; - int result = strict_strtol(buf, 10, &val); + int result = kstrtol(buf, 10, &val); if (result < 0) return -EINVAL; @@ -314,7 +314,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *da, int new_range_bits, old_div = 8 / data->fan_multiplier; long new_div; - int status = strict_strtol(buf, 10, &new_div); + int status = kstrtol(buf, 10, &new_div); if (status < 0) return -EINVAL; @@ -388,7 +388,7 @@ static ssize_t set_fan_target(struct device *dev, struct device_attribute *da, struct i2c_client *client = to_i2c_client(dev); long rpm_target; - int result = strict_strtol(buf, 10, &rpm_target); + int result = kstrtol(buf, 10, &rpm_target); if (result < 0) return -EINVAL; @@ -434,7 +434,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *da, long new_value; u8 conf_reg; - int result = strict_strtol(buf, 10, &new_value); + int result = kstrtol(buf, 10, &new_value); if (result < 0) return -EINVAL; diff --git a/drivers/hwmon/emc6w201.c b/drivers/hwmon/emc6w201.c index 0064432f361..6ebb9b738c9 100644 --- a/drivers/hwmon/emc6w201.c +++ b/drivers/hwmon/emc6w201.c @@ -212,7 +212,7 @@ static ssize_t set_in(struct device *dev, struct device_attribute *devattr, long val; u8 reg; - err = strict_strtol(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err < 0) return err; @@ -249,7 +249,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *devattr, long val; u8 reg; - err = strict_strtol(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err < 0) return err; @@ -291,7 +291,7 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *devattr, int err; unsigned long val; - err = strict_strtoul(buf, 10, &val); + err = kstrtoul(buf, 10, &val); if (err < 0) return err; diff --git a/drivers/hwmon/exynos4_tmu.c b/drivers/hwmon/exynos4_tmu.c index faa0884f61f..f2359a0093b 100644 --- a/drivers/hwmon/exynos4_tmu.c +++ b/drivers/hwmon/exynos4_tmu.c @@ -506,17 +506,7 @@ static struct platform_driver exynos4_tmu_driver = { .resume = exynos4_tmu_resume, }; -static int __init exynos4_tmu_driver_init(void) -{ - return platform_driver_register(&exynos4_tmu_driver); -} -module_init(exynos4_tmu_driver_init); - -static void __exit exynos4_tmu_driver_exit(void) -{ - platform_driver_unregister(&exynos4_tmu_driver); -} -module_exit(exynos4_tmu_driver_exit); +module_platform_driver(exynos4_tmu_driver); MODULE_DESCRIPTION("EXYNOS4 TMU Driver"); MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>"); diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c index 92f949767ec..6dbfd3e516e 100644 --- a/drivers/hwmon/f71805f.c +++ b/drivers/hwmon/f71805f.c @@ -283,11 +283,11 @@ static inline long temp_from_reg(u8 reg) static inline u8 temp_to_reg(long val) { - if (val < 0) - val = 0; - else if (val > 1000 * 0xff) - val = 0xff; - return ((val + 500) / 1000); + if (val <= 0) + return 0; + if (val >= 1000 * 0xff) + return 0xff; + return (val + 500) / 1000; } /* diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index 59dd881c71d..e50305819f0 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c @@ -1333,7 +1333,7 @@ static ssize_t store_fan_full_speed(struct device *dev, int err, nr = to_sensor_dev_attr_2(devattr)->index; long val; - err = strict_strtol(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err) return err; @@ -1367,7 +1367,7 @@ static ssize_t store_fan_beep(struct device *dev, struct device_attribute int err, nr = to_sensor_dev_attr_2(devattr)->index; unsigned long val; - err = strict_strtoul(buf, 10, &val); + err = kstrtoul(buf, 10, &val); if (err) return err; @@ -1420,7 +1420,7 @@ static ssize_t store_in_max(struct device *dev, struct device_attribute int err; long val; - err = strict_strtol(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err) return err; @@ -1454,7 +1454,7 @@ static ssize_t store_in_beep(struct device *dev, struct device_attribute int err, nr = to_sensor_dev_attr_2(devattr)->index; unsigned long val; - err = strict_strtoul(buf, 10, &val); + err = kstrtoul(buf, 10, &val); if (err) return err; @@ -1524,7 +1524,7 @@ static ssize_t store_temp_max(struct device *dev, struct device_attribute int err, nr = to_sensor_dev_attr_2(devattr)->index; long val; - err = strict_strtol(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err) return err; @@ -1566,7 +1566,7 @@ static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute u8 reg; long val; - err = strict_strtol(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err) return err; @@ -1609,7 +1609,7 @@ static ssize_t store_temp_crit(struct device *dev, struct device_attribute int err, nr = to_sensor_dev_attr_2(devattr)->index; long val; - err = strict_strtol(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err) return err; @@ -1670,7 +1670,7 @@ static ssize_t store_temp_beep(struct device *dev, struct device_attribute int err, nr = to_sensor_dev_attr_2(devattr)->index; unsigned long val; - err = strict_strtoul(buf, 10, &val); + err = kstrtoul(buf, 10, &val); if (err) return err; @@ -1737,7 +1737,7 @@ static ssize_t store_pwm(struct device *dev, int err, nr = to_sensor_dev_attr_2(devattr)->index; long val; - err = strict_strtol(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err) return err; @@ -1788,7 +1788,7 @@ static ssize_t store_simple_pwm(struct device *dev, int err, nr = to_sensor_dev_attr_2(devattr)->index; long val; - err = strict_strtol(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err) return err; @@ -1835,7 +1835,7 @@ static ssize_t store_pwm_enable(struct device *dev, struct device_attribute int err, nr = to_sensor_dev_attr_2(devattr)->index; long val; - err = strict_strtol(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err) return err; @@ -1915,7 +1915,7 @@ static ssize_t store_pwm_auto_point_pwm(struct device *dev, int point = to_sensor_dev_attr_2(devattr)->nr; long val; - err = strict_strtol(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err) return err; @@ -1969,7 +1969,7 @@ static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev, u8 reg; long val; - err = strict_strtol(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err) return err; @@ -2015,7 +2015,7 @@ static ssize_t store_pwm_interpolate(struct device *dev, int err, nr = to_sensor_dev_attr_2(devattr)->index; unsigned long val; - err = strict_strtoul(buf, 10, &val); + err = kstrtoul(buf, 10, &val); if (err) return err; @@ -2055,7 +2055,7 @@ static ssize_t store_pwm_auto_point_channel(struct device *dev, int err, nr = to_sensor_dev_attr_2(devattr)->index; long val; - err = strict_strtol(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err) return err; @@ -2106,7 +2106,7 @@ static ssize_t store_pwm_auto_point_temp(struct device *dev, int point = to_sensor_dev_attr_2(devattr)->nr; long val; - err = strict_strtol(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err) return err; diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c index 95cbfb3a707..6aa5a9fad87 100644 --- a/drivers/hwmon/f75375s.c +++ b/drivers/hwmon/f75375s.c @@ -1,16 +1,19 @@ /* - * f75375s.c - driver for the Fintek F75375/SP and F75373 - * hardware monitoring features + * f75375s.c - driver for the Fintek F75375/SP, F75373 and + * F75387SG/RG hardware monitoring features * Copyright (C) 2006-2007 Riku Voipio * * Datasheets available at: * * f75375: - * http://www.fintek.com.tw/files/productfiles/F75375_V026P.pdf + * http://www.fintek.com.tw/files/productfiles/F75375_V026P.pdf * * f75373: * http://www.fintek.com.tw/files/productfiles/F75373_V025P.pdf * + * f75387: + * http://www.fintek.com.tw/files/productfiles/F75387_V027P.pdf + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -40,7 +43,7 @@ /* Addresses to scan */ static const unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END }; -enum chips { f75373, f75375 }; +enum chips { f75373, f75375, f75387 }; /* Fintek F75375 registers */ #define F75375_REG_CONFIG0 0x0 @@ -59,6 +62,7 @@ enum chips { f75373, f75375 }; #define F75375_REG_VOLT_LOW(nr) (0x21 + (nr) * 2) #define F75375_REG_TEMP(nr) (0x14 + (nr)) +#define F75387_REG_TEMP11_LSB(nr) (0x1a + (nr)) #define F75375_REG_TEMP_HIGH(nr) (0x28 + (nr) * 2) #define F75375_REG_TEMP_HYST(nr) (0x29 + (nr) * 2) @@ -78,8 +82,11 @@ enum chips { f75373, f75375 }; #define F75375_REG_PWM1_DROP_DUTY 0x6B #define F75375_REG_PWM2_DROP_DUTY 0x6C -#define FAN_CTRL_LINEAR(nr) (4 + nr) +#define F75375_FAN_CTRL_LINEAR(nr) (4 + nr) +#define F75387_FAN_CTRL_LINEAR(nr) (1 + ((nr) * 4)) #define FAN_CTRL_MODE(nr) (4 + ((nr) * 2)) +#define F75387_FAN_DUTY_MODE(nr) (2 + ((nr) * 4)) +#define F75387_FAN_MANU_MODE(nr) ((nr) * 4) /* * Data structures and manipulation thereof @@ -102,13 +109,18 @@ struct f75375_data { u8 in_min[4]; u16 fan[2]; u16 fan_min[2]; - u16 fan_full[2]; - u16 fan_exp[2]; + u16 fan_max[2]; + u16 fan_target[2]; u8 fan_timer; u8 pwm[2]; u8 pwm_mode[2]; u8 pwm_enable[2]; - s8 temp[2]; + /* + * f75387: For remote temperature reading, it uses signed 11-bit + * values with LSB = 0.125 degree Celsius, left-justified in 16-bit + * registers. For original 8-bit temp readings, the LSB just is 0. + */ + s16 temp11[2]; s8 temp_high[2]; s8 temp_max_hyst[2]; }; @@ -122,6 +134,7 @@ static int f75375_remove(struct i2c_client *client); static const struct i2c_device_id f75375_id[] = { { "f75373", f75373 }, { "f75375", f75375 }, + { "f75387", f75387 }, { } }; MODULE_DEVICE_TABLE(i2c, f75375_id); @@ -146,8 +159,8 @@ static inline int f75375_read8(struct i2c_client *client, u8 reg) /* in most cases, should be called while holding update_lock */ static inline u16 f75375_read16(struct i2c_client *client, u8 reg) { - return ((i2c_smbus_read_byte_data(client, reg) << 8) - | i2c_smbus_read_byte_data(client, reg + 1)); + return (i2c_smbus_read_byte_data(client, reg) << 8) + | i2c_smbus_read_byte_data(client, reg + 1); } static inline void f75375_write8(struct i2c_client *client, u8 reg, @@ -159,12 +172,22 @@ static inline void f75375_write8(struct i2c_client *client, u8 reg, static inline void f75375_write16(struct i2c_client *client, u8 reg, u16 value) { - int err = i2c_smbus_write_byte_data(client, reg, (value << 8)); + int err = i2c_smbus_write_byte_data(client, reg, (value >> 8)); if (err) return; i2c_smbus_write_byte_data(client, reg + 1, (value & 0xFF)); } +static void f75375_write_pwm(struct i2c_client *client, int nr) +{ + struct f75375_data *data = i2c_get_clientdata(client); + if (data->kind == f75387) + f75375_write16(client, F75375_REG_FAN_EXP(nr), data->pwm[nr]); + else + f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), + data->pwm[nr]); +} + static struct f75375_data *f75375_update_device(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -181,15 +204,12 @@ static struct f75375_data *f75375_update_device(struct device *dev) f75375_read8(client, F75375_REG_TEMP_HIGH(nr)); data->temp_max_hyst[nr] = f75375_read8(client, F75375_REG_TEMP_HYST(nr)); - data->fan_full[nr] = + data->fan_max[nr] = f75375_read16(client, F75375_REG_FAN_FULL(nr)); data->fan_min[nr] = f75375_read16(client, F75375_REG_FAN_MIN(nr)); - data->fan_exp[nr] = + data->fan_target[nr] = f75375_read16(client, F75375_REG_FAN_EXP(nr)); - data->pwm[nr] = f75375_read8(client, - F75375_REG_FAN_PWM_DUTY(nr)); - } for (nr = 0; nr < 4; nr++) { data->in_max[nr] = @@ -205,8 +225,16 @@ static struct f75375_data *f75375_update_device(struct device *dev) if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { for (nr = 0; nr < 2; nr++) { - data->temp[nr] = - f75375_read8(client, F75375_REG_TEMP(nr)); + data->pwm[nr] = f75375_read8(client, + F75375_REG_FAN_PWM_DUTY(nr)); + /* assign MSB, therefore shift it by 8 bits */ + data->temp11[nr] = + f75375_read8(client, F75375_REG_TEMP(nr)) << 8; + if (data->kind == f75387) + /* merge F75387's temperature LSB (11-bit) */ + data->temp11[nr] |= + f75375_read8(client, + F75387_REG_TEMP11_LSB(nr)); data->fan[nr] = f75375_read16(client, F75375_REG_FAN(nr)); } @@ -226,14 +254,44 @@ static inline u16 rpm_from_reg(u16 reg) { if (reg == 0 || reg == 0xffff) return 0; - return (1500000 / reg); + return 1500000 / reg; } static inline u16 rpm_to_reg(int rpm) { if (rpm < 367 || rpm > 0xffff) return 0xffff; - return (1500000 / rpm); + return 1500000 / rpm; +} + +static bool duty_mode_enabled(u8 pwm_enable) +{ + switch (pwm_enable) { + case 0: /* Manual, duty mode (full speed) */ + case 1: /* Manual, duty mode */ + case 4: /* Auto, duty mode */ + return true; + case 2: /* Auto, speed mode */ + case 3: /* Manual, speed mode */ + return false; + default: + BUG(); + } +} + +static bool auto_mode_enabled(u8 pwm_enable) +{ + switch (pwm_enable) { + case 0: /* Manual, duty mode (full speed) */ + case 1: /* Manual, duty mode */ + case 3: /* Manual, speed mode */ + return false; + case 2: /* Auto, speed mode */ + case 4: /* Auto, duty mode */ + return true; + default: + BUG(); + } } static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, @@ -242,7 +300,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct f75375_data *data = i2c_get_clientdata(client); - int val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err < 0) + return err; mutex_lock(&data->update_lock); data->fan_min[nr] = rpm_to_reg(val); @@ -251,17 +314,27 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, return count; } -static ssize_t set_fan_exp(struct device *dev, struct device_attribute *attr, +static ssize_t set_fan_target(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct f75375_data *data = i2c_get_clientdata(client); - int val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err < 0) + return err; + + if (auto_mode_enabled(data->pwm_enable[nr])) + return -EINVAL; + if (data->kind == f75387 && duty_mode_enabled(data->pwm_enable[nr])) + return -EINVAL; mutex_lock(&data->update_lock); - data->fan_exp[nr] = rpm_to_reg(val); - f75375_write16(client, F75375_REG_FAN_EXP(nr), data->fan_exp[nr]); + data->fan_target[nr] = rpm_to_reg(val); + f75375_write16(client, F75375_REG_FAN_EXP(nr), data->fan_target[nr]); mutex_unlock(&data->update_lock); return count; } @@ -272,11 +345,20 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct f75375_data *data = i2c_get_clientdata(client); - int val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err < 0) + return err; + + if (auto_mode_enabled(data->pwm_enable[nr]) || + !duty_mode_enabled(data->pwm_enable[nr])) + return -EINVAL; mutex_lock(&data->update_lock); data->pwm[nr] = SENSORS_LIMIT(val, 0, 255); - f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), data->pwm[nr]); + f75375_write_pwm(client, nr); mutex_unlock(&data->update_lock); return count; } @@ -298,26 +380,58 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val) return -EINVAL; fanmode = f75375_read8(client, F75375_REG_FAN_TIMER); - fanmode &= ~(3 << FAN_CTRL_MODE(nr)); - - switch (val) { - case 0: /* Full speed */ - fanmode |= (3 << FAN_CTRL_MODE(nr)); - data->pwm[nr] = 255; - f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), - data->pwm[nr]); - break; - case 1: /* PWM */ - fanmode |= (3 << FAN_CTRL_MODE(nr)); - break; - case 2: /* AUTOMATIC*/ - fanmode |= (2 << FAN_CTRL_MODE(nr)); - break; - case 3: /* fan speed */ - break; + if (data->kind == f75387) { + /* For now, deny dangerous toggling of duty mode */ + if (duty_mode_enabled(data->pwm_enable[nr]) != + duty_mode_enabled(val)) + return -EOPNOTSUPP; + /* clear each fanX_mode bit before setting them properly */ + fanmode &= ~(1 << F75387_FAN_DUTY_MODE(nr)); + fanmode &= ~(1 << F75387_FAN_MANU_MODE(nr)); + switch (val) { + case 0: /* full speed */ + fanmode |= (1 << F75387_FAN_MANU_MODE(nr)); + fanmode |= (1 << F75387_FAN_DUTY_MODE(nr)); + data->pwm[nr] = 255; + break; + case 1: /* PWM */ + fanmode |= (1 << F75387_FAN_MANU_MODE(nr)); + fanmode |= (1 << F75387_FAN_DUTY_MODE(nr)); + break; + case 2: /* Automatic, speed mode */ + break; + case 3: /* fan speed */ + fanmode |= (1 << F75387_FAN_MANU_MODE(nr)); + break; + case 4: /* Automatic, pwm */ + fanmode |= (1 << F75387_FAN_DUTY_MODE(nr)); + break; + } + } else { + /* clear each fanX_mode bit before setting them properly */ + fanmode &= ~(3 << FAN_CTRL_MODE(nr)); + switch (val) { + case 0: /* full speed */ + fanmode |= (3 << FAN_CTRL_MODE(nr)); + data->pwm[nr] = 255; + break; + case 1: /* PWM */ + fanmode |= (3 << FAN_CTRL_MODE(nr)); + break; + case 2: /* AUTOMATIC*/ + fanmode |= (1 << FAN_CTRL_MODE(nr)); + break; + case 3: /* fan speed */ + break; + case 4: /* Automatic pwm */ + return -EINVAL; + } } + f75375_write8(client, F75375_REG_FAN_TIMER, fanmode); data->pwm_enable[nr] = val; + if (val == 0) + f75375_write_pwm(client, nr); return 0; } @@ -327,8 +441,12 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct f75375_data *data = i2c_get_clientdata(client); - int val = simple_strtoul(buf, NULL, 10); - int err = 0; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err < 0) + return err; mutex_lock(&data->update_lock); err = set_pwm_enable_direct(client, nr, val); @@ -342,20 +460,39 @@ static ssize_t set_pwm_mode(struct device *dev, struct device_attribute *attr, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct f75375_data *data = i2c_get_clientdata(client); - int val = simple_strtoul(buf, NULL, 10); - u8 conf = 0; + unsigned long val; + int err; + u8 conf; + char reg, ctrl; + + err = kstrtoul(buf, 10, &val); + if (err < 0) + return err; if (!(val == 0 || val == 1)) return -EINVAL; + /* F75373 does not support DC (linear voltage) fan control mode */ + if (data->kind == f75373 && val == 0) + return -EINVAL; + + /* take care for different registers */ + if (data->kind == f75387) { + reg = F75375_REG_FAN_TIMER; + ctrl = F75387_FAN_CTRL_LINEAR(nr); + } else { + reg = F75375_REG_CONFIG1; + ctrl = F75375_FAN_CTRL_LINEAR(nr); + } + mutex_lock(&data->update_lock); - conf = f75375_read8(client, F75375_REG_CONFIG1); - conf &= ~(1 << FAN_CTRL_LINEAR(nr)); + conf = f75375_read8(client, reg); + conf &= ~(1 << ctrl); if (val == 0) - conf |= (1 << FAN_CTRL_LINEAR(nr)) ; + conf |= (1 << ctrl); - f75375_write8(client, F75375_REG_CONFIG1, conf); + f75375_write8(client, reg, conf); data->pwm_mode[nr] = val; mutex_unlock(&data->update_lock); return count; @@ -410,7 +547,13 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct f75375_data *data = i2c_get_clientdata(client); - int val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err < 0) + return err; + val = SENSORS_LIMIT(VOLT_TO_REG(val), 0, 0xff); mutex_lock(&data->update_lock); data->in_max[nr] = val; @@ -425,7 +568,13 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct f75375_data *data = i2c_get_clientdata(client); - int val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err < 0) + return err; + val = SENSORS_LIMIT(VOLT_TO_REG(val), 0, 0xff); mutex_lock(&data->update_lock); data->in_min[nr] = val; @@ -435,13 +584,14 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, } #define TEMP_FROM_REG(val) ((val) * 1000) #define TEMP_TO_REG(val) ((val) / 1000) +#define TEMP11_FROM_REG(reg) ((reg) / 32 * 125) -static ssize_t show_temp(struct device *dev, struct device_attribute *attr, +static ssize_t show_temp11(struct device *dev, struct device_attribute *attr, char *buf) { int nr = to_sensor_dev_attr(attr)->index; struct f75375_data *data = f75375_update_device(dev); - return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr])); + return sprintf(buf, "%d\n", TEMP11_FROM_REG(data->temp11[nr])); } static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr, @@ -466,7 +616,13 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct f75375_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err < 0) + return err; + val = SENSORS_LIMIT(TEMP_TO_REG(val), 0, 127); mutex_lock(&data->update_lock); data->temp_high[nr] = val; @@ -481,7 +637,13 @@ static ssize_t set_temp_max_hyst(struct device *dev, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct f75375_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err < 0) + return err; + val = SENSORS_LIMIT(TEMP_TO_REG(val), 0, 127); mutex_lock(&data->update_lock); data->temp_max_hyst[nr] = val; @@ -502,8 +664,8 @@ static ssize_t show_##thing(struct device *dev, struct device_attribute *attr, \ show_fan(fan); show_fan(fan_min); -show_fan(fan_full); -show_fan(fan_exp); +show_fan(fan_max); +show_fan(fan_target); static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_in, NULL, 0); static SENSOR_DEVICE_ATTR(in0_max, S_IRUGO|S_IWUSR, @@ -525,28 +687,28 @@ static SENSOR_DEVICE_ATTR(in3_max, S_IRUGO|S_IWUSR, show_in_max, set_in_max, 3); static SENSOR_DEVICE_ATTR(in3_min, S_IRUGO|S_IWUSR, show_in_min, set_in_min, 3); -static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp11, NULL, 0); static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, set_temp_max_hyst, 0); static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO|S_IWUSR, show_temp_max, set_temp_max, 0); -static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); +static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 1); static SENSOR_DEVICE_ATTR(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, set_temp_max_hyst, 1); static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO|S_IWUSR, show_temp_max, set_temp_max, 1); static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); -static SENSOR_DEVICE_ATTR(fan1_full, S_IRUGO, show_fan_full, NULL, 0); +static SENSOR_DEVICE_ATTR(fan1_max, S_IRUGO, show_fan_max, NULL, 0); static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO|S_IWUSR, show_fan_min, set_fan_min, 0); -static SENSOR_DEVICE_ATTR(fan1_exp, S_IRUGO|S_IWUSR, - show_fan_exp, set_fan_exp, 0); +static SENSOR_DEVICE_ATTR(fan1_target, S_IRUGO|S_IWUSR, + show_fan_target, set_fan_target, 0); static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); -static SENSOR_DEVICE_ATTR(fan2_full, S_IRUGO, show_fan_full, NULL, 1); +static SENSOR_DEVICE_ATTR(fan2_max, S_IRUGO, show_fan_max, NULL, 1); static SENSOR_DEVICE_ATTR(fan2_min, S_IRUGO|S_IWUSR, show_fan_min, set_fan_min, 1); -static SENSOR_DEVICE_ATTR(fan2_exp, S_IRUGO|S_IWUSR, - show_fan_exp, set_fan_exp, 1); +static SENSOR_DEVICE_ATTR(fan2_target, S_IRUGO|S_IWUSR, + show_fan_target, set_fan_target, 1); static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO|S_IWUSR, show_pwm, set_pwm, 0); static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO|S_IWUSR, @@ -568,13 +730,13 @@ static struct attribute *f75375_attributes[] = { &sensor_dev_attr_temp2_max.dev_attr.attr, &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, &sensor_dev_attr_fan1_input.dev_attr.attr, - &sensor_dev_attr_fan1_full.dev_attr.attr, + &sensor_dev_attr_fan1_max.dev_attr.attr, &sensor_dev_attr_fan1_min.dev_attr.attr, - &sensor_dev_attr_fan1_exp.dev_attr.attr, + &sensor_dev_attr_fan1_target.dev_attr.attr, &sensor_dev_attr_fan2_input.dev_attr.attr, - &sensor_dev_attr_fan2_full.dev_attr.attr, + &sensor_dev_attr_fan2_max.dev_attr.attr, &sensor_dev_attr_fan2_min.dev_attr.attr, - &sensor_dev_attr_fan2_exp.dev_attr.attr, + &sensor_dev_attr_fan2_target.dev_attr.attr, &sensor_dev_attr_pwm1.dev_attr.attr, &sensor_dev_attr_pwm1_enable.dev_attr.attr, &sensor_dev_attr_pwm1_mode.dev_attr.attr, @@ -604,12 +766,62 @@ static void f75375_init(struct i2c_client *client, struct f75375_data *data, struct f75375s_platform_data *f75375s_pdata) { int nr; + + if (!f75375s_pdata) { + u8 conf, mode; + int nr; + + conf = f75375_read8(client, F75375_REG_CONFIG1); + mode = f75375_read8(client, F75375_REG_FAN_TIMER); + for (nr = 0; nr < 2; nr++) { + if (data->kind == f75387) { + bool manu, duty; + + if (!(mode & (1 << F75387_FAN_CTRL_LINEAR(nr)))) + data->pwm_mode[nr] = 1; + + manu = ((mode >> F75387_FAN_MANU_MODE(nr)) & 1); + duty = ((mode >> F75387_FAN_DUTY_MODE(nr)) & 1); + if (!manu && duty) + /* auto, pwm */ + data->pwm_enable[nr] = 4; + else if (manu && !duty) + /* manual, speed */ + data->pwm_enable[nr] = 3; + else if (!manu && !duty) + /* automatic, speed */ + data->pwm_enable[nr] = 2; + else + /* manual, pwm */ + data->pwm_enable[nr] = 1; + } else { + if (!(conf & (1 << F75375_FAN_CTRL_LINEAR(nr)))) + data->pwm_mode[nr] = 1; + + switch ((mode >> FAN_CTRL_MODE(nr)) & 3) { + case 0: /* speed */ + data->pwm_enable[nr] = 3; + break; + case 1: /* automatic */ + data->pwm_enable[nr] = 2; + break; + default: /* manual */ + data->pwm_enable[nr] = 1; + break; + } + } + } + return; + } + set_pwm_enable_direct(client, 0, f75375s_pdata->pwm_enable[0]); set_pwm_enable_direct(client, 1, f75375s_pdata->pwm_enable[1]); for (nr = 0; nr < 2; nr++) { + if (auto_mode_enabled(f75375s_pdata->pwm_enable[nr]) || + !duty_mode_enabled(f75375s_pdata->pwm_enable[nr])) + continue; data->pwm[nr] = SENSORS_LIMIT(f75375s_pdata->pwm[nr], 0, 255); - f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), - data->pwm[nr]); + f75375_write_pwm(client, nr); } } @@ -624,17 +836,19 @@ static int f75375_probe(struct i2c_client *client, if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; - if (!(data = kzalloc(sizeof(struct f75375_data), GFP_KERNEL))) + data = kzalloc(sizeof(struct f75375_data), GFP_KERNEL); + if (!data) return -ENOMEM; i2c_set_clientdata(client, data); mutex_init(&data->update_lock); data->kind = id->driver_data; - if ((err = sysfs_create_group(&client->dev.kobj, &f75375_group))) + err = sysfs_create_group(&client->dev.kobj, &f75375_group); + if (err) goto exit_free; - if (data->kind == f75375) { + if (data->kind != f75373) { err = sysfs_chmod_file(&client->dev.kobj, &sensor_dev_attr_pwm1_mode.dev_attr.attr, S_IRUGO | S_IWUSR); @@ -653,8 +867,7 @@ static int f75375_probe(struct i2c_client *client, goto exit_remove; } - if (f75375s_pdata != NULL) - f75375_init(client, data, f75375s_pdata); + f75375_init(client, data, f75375s_pdata); return 0; @@ -685,10 +898,15 @@ static int f75375_detect(struct i2c_client *client, vendid = f75375_read16(client, F75375_REG_VENDOR); chipid = f75375_read16(client, F75375_CHIP_ID); - if (chipid == 0x0306 && vendid == 0x1934) + if (vendid != 0x1934) + return -ENODEV; + + if (chipid == 0x0306) name = "f75375"; - else if (chipid == 0x0204 && vendid == 0x1934) + else if (chipid == 0x0204) name = "f75373"; + else if (chipid == 0x0410) + name = "f75387"; else return -ENODEV; @@ -711,7 +929,7 @@ static void __exit sensors_f75375_exit(void) MODULE_AUTHOR("Riku Voipio"); MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("F75373/F75375 hardware monitoring driver"); +MODULE_DESCRIPTION("F75373/F75375/F75387 hardware monitoring driver"); module_init(sensors_f75375_init); module_exit(sensors_f75375_exit); diff --git a/drivers/hwmon/g760a.c b/drivers/hwmon/g760a.c index 1d6a6fa31fb..781277ddbaa 100644 --- a/drivers/hwmon/g760a.c +++ b/drivers/hwmon/g760a.c @@ -166,7 +166,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *da, struct g760a_data *data = g760a_update_client(dev); unsigned long val; - if (strict_strtoul(buf, 10, &val)) + if (kstrtoul(buf, 10, &val)) return -EINVAL; mutex_lock(&data->update_lock); diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c index 89aa9fb743a..2ce8c44a0e0 100644 --- a/drivers/hwmon/gpio-fan.c +++ b/drivers/hwmon/gpio-fan.c @@ -224,7 +224,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, int speed_index; int ret = count; - if (strict_strtoul(buf, 10, &pwm) || pwm > 255) + if (kstrtoul(buf, 10, &pwm) || pwm > 255) return -EINVAL; mutex_lock(&fan_data->lock); @@ -257,7 +257,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, struct gpio_fan_data *fan_data = dev_get_drvdata(dev); unsigned long val; - if (strict_strtoul(buf, 10, &val) || val > 1) + if (kstrtoul(buf, 10, &val) || val > 1) return -EINVAL; if (fan_data->pwm_enable == val) @@ -314,7 +314,7 @@ static ssize_t set_rpm(struct device *dev, struct device_attribute *attr, unsigned long rpm; int ret = count; - if (strict_strtoul(buf, 10, &rpm)) + if (kstrtoul(buf, 10, &rpm)) return -EINVAL; mutex_lock(&fan_data->lock); @@ -539,18 +539,7 @@ static struct platform_driver gpio_fan_driver = { }, }; -static int __init gpio_fan_init(void) -{ - return platform_driver_register(&gpio_fan_driver); -} - -static void __exit gpio_fan_exit(void) -{ - platform_driver_unregister(&gpio_fan_driver); -} - -module_init(gpio_fan_init); -module_exit(gpio_fan_exit); +module_platform_driver(gpio_fan_driver); MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>"); MODULE_DESCRIPTION("GPIO FAN driver"); diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c index 6a967d7dbde..cc2981f749a 100644 --- a/drivers/hwmon/ibmaem.c +++ b/drivers/hwmon/ibmaem.c @@ -904,7 +904,7 @@ static ssize_t aem_set_power_period(struct device *dev, unsigned long temp; int res; - res = strict_strtoul(buf, 10, &temp); + res = kstrtoul(buf, 10, &temp); if (res) return res; diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index d912649fac5..0054d6f9cec 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -17,6 +17,7 @@ * IT8720F Super I/O chip w/LPC interface * IT8721F Super I/O chip w/LPC interface * IT8726F Super I/O chip w/LPC interface + * IT8728F Super I/O chip w/LPC interface * IT8758E Super I/O chip w/LPC interface * Sis950 A clone of the IT8705F * @@ -58,7 +59,7 @@ #define DRVNAME "it87" -enum chips { it87, it8712, it8716, it8718, it8720, it8721 }; +enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728 }; static unsigned short force_id; module_param(force_id, ushort, 0); @@ -135,6 +136,7 @@ static inline void superio_exit(void) #define IT8720F_DEVID 0x8720 #define IT8721F_DEVID 0x8721 #define IT8726F_DEVID 0x8726 +#define IT8728F_DEVID 0x8728 #define IT87_ACT_REG 0x30 #define IT87_BASE_REG 0x60 @@ -146,10 +148,10 @@ static inline void superio_exit(void) #define IT87_SIO_BEEP_PIN_REG 0xf6 /* Beep pin mapping */ /* Update battery voltage after every reading if true */ -static int update_vbat; +static bool update_vbat; /* Not all BIOSes properly configure the PWM registers */ -static int fix_pwm_polarity; +static bool fix_pwm_polarity; /* Many IT87 constants specified below */ @@ -274,11 +276,31 @@ struct it87_data { s8 auto_temp[3][5]; /* [nr][0] is point1_temp_hyst */ }; +static inline int has_12mv_adc(const struct it87_data *data) +{ + /* + * IT8721F and later have a 12 mV ADC, also with internal scaling + * on selected inputs. + */ + return data->type == it8721 + || data->type == it8728; +} + +static inline int has_newer_autopwm(const struct it87_data *data) +{ + /* + * IT8721F and later have separate registers for the temperature + * mapping and the manual duty cycle. + */ + return data->type == it8721 + || data->type == it8728; +} + static u8 in_to_reg(const struct it87_data *data, int nr, long val) { long lsb; - if (data->type == it8721) { + if (has_12mv_adc(data)) { if (data->in_scaled & (1 << nr)) lsb = 24; else @@ -292,7 +314,7 @@ static u8 in_to_reg(const struct it87_data *data, int nr, long val) static int in_from_reg(const struct it87_data *data, int nr, int val) { - if (data->type == it8721) { + if (has_12mv_adc(data)) { if (data->in_scaled & (1 << nr)) return val * 24; else @@ -329,7 +351,7 @@ static inline u16 FAN16_TO_REG(long rpm) static u8 pwm_to_reg(const struct it87_data *data, long val) { - if (data->type == it8721) + if (has_newer_autopwm(data)) return val; else return val >> 1; @@ -337,7 +359,7 @@ static u8 pwm_to_reg(const struct it87_data *data, long val) static int pwm_from_reg(const struct it87_data *data, u8 reg) { - if (data->type == it8721) + if (has_newer_autopwm(data)) return reg; else return (reg & 0x7f) << 1; @@ -374,7 +396,8 @@ static inline int has_16bit_fans(const struct it87_data *data) || data->type == it8716 || data->type == it8718 || data->type == it8720 - || data->type == it8721; + || data->type == it8721 + || data->type == it8728; } static inline int has_old_autopwm(const struct it87_data *data) @@ -444,7 +467,7 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, struct it87_data *data = dev_get_drvdata(dev); unsigned long val; - if (strict_strtoul(buf, 10, &val) < 0) + if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; mutex_lock(&data->update_lock); @@ -463,7 +486,7 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, struct it87_data *data = dev_get_drvdata(dev); unsigned long val; - if (strict_strtoul(buf, 10, &val) < 0) + if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; mutex_lock(&data->update_lock); @@ -539,7 +562,7 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, struct it87_data *data = dev_get_drvdata(dev); long val; - if (strict_strtol(buf, 10, &val) < 0) + if (kstrtol(buf, 10, &val) < 0) return -EINVAL; mutex_lock(&data->update_lock); @@ -557,7 +580,7 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, struct it87_data *data = dev_get_drvdata(dev); long val; - if (strict_strtol(buf, 10, &val) < 0) + if (kstrtol(buf, 10, &val) < 0) return -EINVAL; mutex_lock(&data->update_lock); @@ -604,7 +627,7 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr, long val; u8 reg; - if (strict_strtol(buf, 10, &val) < 0) + if (kstrtol(buf, 10, &val) < 0) return -EINVAL; reg = it87_read_value(data, IT87_REG_TEMP_ENABLE); @@ -718,7 +741,7 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, long val; u8 reg; - if (strict_strtol(buf, 10, &val) < 0) + if (kstrtol(buf, 10, &val) < 0) return -EINVAL; mutex_lock(&data->update_lock); @@ -751,7 +774,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, int min; u8 old; - if (strict_strtoul(buf, 10, &val) < 0) + if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; mutex_lock(&data->update_lock); @@ -820,7 +843,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct it87_data *data = dev_get_drvdata(dev); long val; - if (strict_strtol(buf, 10, &val) < 0 || val < 0 || val > 2) + if (kstrtol(buf, 10, &val) < 0 || val < 0 || val > 2) return -EINVAL; /* Check trip points before switching to automatic mode */ @@ -842,7 +865,7 @@ static ssize_t set_pwm_enable(struct device *dev, data->fan_main_ctrl); } else { if (val == 1) /* Manual mode */ - data->pwm_ctrl[nr] = data->type == it8721 ? + data->pwm_ctrl[nr] = has_newer_autopwm(data) ? data->pwm_temp_map[nr] : data->pwm_duty[nr]; else /* Automatic mode */ @@ -866,11 +889,11 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, struct it87_data *data = dev_get_drvdata(dev); long val; - if (strict_strtol(buf, 10, &val) < 0 || val < 0 || val > 255) + if (kstrtol(buf, 10, &val) < 0 || val < 0 || val > 255) return -EINVAL; mutex_lock(&data->update_lock); - if (data->type == it8721) { + if (has_newer_autopwm(data)) { /* If we are in automatic mode, the PWM duty cycle register * is read-only so we can't write the value */ if (data->pwm_ctrl[nr] & 0x80) { @@ -900,7 +923,7 @@ static ssize_t set_pwm_freq(struct device *dev, unsigned long val; int i; - if (strict_strtoul(buf, 10, &val) < 0) + if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; /* Search for the nearest available frequency */ @@ -949,7 +972,7 @@ static ssize_t set_pwm_temp_map(struct device *dev, return -EINVAL; } - if (strict_strtol(buf, 10, &val) < 0) + if (kstrtol(buf, 10, &val) < 0) return -EINVAL; switch (val) { @@ -1001,7 +1024,7 @@ static ssize_t set_auto_pwm(struct device *dev, int point = sensor_attr->index; long val; - if (strict_strtol(buf, 10, &val) < 0 || val < 0 || val > 255) + if (kstrtol(buf, 10, &val) < 0 || val < 0 || val > 255) return -EINVAL; mutex_lock(&data->update_lock); @@ -1034,7 +1057,7 @@ static ssize_t set_auto_temp(struct device *dev, int point = sensor_attr->index; long val; - if (strict_strtol(buf, 10, &val) < 0 || val < -128000 || val > 127000) + if (kstrtol(buf, 10, &val) < 0 || val < -128000 || val > 127000) return -EINVAL; mutex_lock(&data->update_lock); @@ -1126,7 +1149,7 @@ static ssize_t set_fan16_min(struct device *dev, struct device_attribute *attr, struct it87_data *data = dev_get_drvdata(dev); long val; - if (strict_strtol(buf, 10, &val) < 0) + if (kstrtol(buf, 10, &val) < 0) return -EINVAL; mutex_lock(&data->update_lock); @@ -1180,7 +1203,7 @@ static ssize_t clear_intrusion(struct device *dev, struct device_attribute long val; int config; - if (strict_strtol(buf, 10, &val) < 0 || val != 0) + if (kstrtol(buf, 10, &val) < 0 || val != 0) return -EINVAL; mutex_lock(&data->update_lock); @@ -1231,7 +1254,7 @@ static ssize_t set_beep(struct device *dev, struct device_attribute *attr, struct it87_data *data = dev_get_drvdata(dev); long val; - if (strict_strtol(buf, 10, &val) < 0 + if (kstrtol(buf, 10, &val) < 0 || (val != 0 && val != 1)) return -EINVAL; @@ -1278,7 +1301,7 @@ static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, struct it87_data *data = dev_get_drvdata(dev); unsigned long val; - if (strict_strtoul(buf, 10, &val) < 0) + if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; data->vrm = val; @@ -1311,8 +1334,8 @@ static ssize_t show_label(struct device *dev, struct device_attribute *attr, struct it87_data *data = dev_get_drvdata(dev); int nr = to_sensor_dev_attr(attr)->index; - return sprintf(buf, "%s\n", data->type == it8721 ? labels_it8721[nr] - : labels[nr]); + return sprintf(buf, "%s\n", has_12mv_adc(data) ? labels_it8721[nr] + : labels[nr]); } static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, 0); static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_label, NULL, 1); @@ -1605,6 +1628,9 @@ static int __init it87_find(unsigned short *address, case IT8721F_DEVID: sio_data->type = it8721; break; + case IT8728F_DEVID: + sio_data->type = it8728; + break; case 0xffff: /* No device at all */ goto exit; default: @@ -1646,8 +1672,11 @@ static int __init it87_find(unsigned short *address, superio_select(GPIO); reg = superio_inb(IT87_SIO_GPIO3_REG); - if (sio_data->type == it8721) { - /* The IT8721F/IT8758E doesn't have VID pins at all */ + if (sio_data->type == it8721 || sio_data->type == it8728) { + /* + * The IT8721F/IT8758E doesn't have VID pins at all, + * not sure about the IT8728F. + */ sio_data->skip_vid = 1; } else { /* We need at least 4 VID pins */ @@ -1692,7 +1721,8 @@ static int __init it87_find(unsigned short *address, } if (reg & (1 << 0)) sio_data->internal |= (1 << 0); - if ((reg & (1 << 1)) || sio_data->type == it8721) + if ((reg & (1 << 1)) || sio_data->type == it8721 || + sio_data->type == it8728) sio_data->internal |= (1 << 1); sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; @@ -1770,6 +1800,7 @@ static int __devinit it87_probe(struct platform_device *pdev) "it8718", "it8720", "it8721", + "it8728", }; res = platform_get_resource(pdev, IORESOURCE_IO, 0); @@ -1807,7 +1838,7 @@ static int __devinit it87_probe(struct platform_device *pdev) enable_pwm_interface = it87_check_pwm(dev); /* Starting with IT8721F, we handle scaling of internal voltages */ - if (data->type == it8721) { + if (has_12mv_adc(data)) { if (sio_data->internal & (1 << 0)) data->in_scaled |= (1 << 3); /* in3 is AVCC */ if (sio_data->internal & (1 << 1)) @@ -2093,7 +2124,7 @@ static void __devinit it87_init_device(struct platform_device *pdev) static void it87_update_pwm_ctrl(struct it87_data *data, int nr) { data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr)); - if (data->type == it8721) { + if (has_newer_autopwm(data)) { data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03; data->pwm_duty[nr] = it87_read_value(data, IT87_REG_PWM_DUTY(nr)); diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c index 2d3d72805ff..28c09eead36 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c @@ -309,7 +309,7 @@ static ssize_t set_##value(struct device *dev, \ struct jc42_data *data = i2c_get_clientdata(client); \ int err, ret = count; \ long val; \ - if (strict_strtol(buf, 10, &val) < 0) \ + if (kstrtol(buf, 10, &val) < 0) \ return -EINVAL; \ mutex_lock(&data->update_lock); \ data->value = jc42_temp_to_reg(val, data->extended); \ @@ -337,7 +337,7 @@ static ssize_t set_temp_crit_hyst(struct device *dev, int err; int ret = count; - if (strict_strtoul(buf, 10, &val) < 0) + if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; diff = jc42_temp_from_reg(data->temp_crit) - val; @@ -413,7 +413,7 @@ static struct attribute *jc42_attributes[] = { NULL }; -static mode_t jc42_attribute_mode(struct kobject *kobj, +static umode_t jc42_attribute_mode(struct kobject *kobj, struct attribute *attr, int index) { struct device *dev = container_of(kobj, struct device, kobj); diff --git a/drivers/hwmon/jz4740-hwmon.c b/drivers/hwmon/jz4740-hwmon.c index fea292d4340..5253d23361d 100644 --- a/drivers/hwmon/jz4740-hwmon.c +++ b/drivers/hwmon/jz4740-hwmon.c @@ -59,7 +59,7 @@ static ssize_t jz4740_hwmon_read_adcin(struct device *dev, { struct jz4740_hwmon *hwmon = dev_get_drvdata(dev); struct completion *completion = &hwmon->read_completion; - unsigned long t; + long t; unsigned long val; int ret; @@ -203,7 +203,7 @@ static int __devexit jz4740_hwmon_remove(struct platform_device *pdev) return 0; } -struct platform_driver jz4740_hwmon_driver = { +static struct platform_driver jz4740_hwmon_driver = { .probe = jz4740_hwmon_probe, .remove = __devexit_p(jz4740_hwmon_remove), .driver = { @@ -212,17 +212,7 @@ struct platform_driver jz4740_hwmon_driver = { }, }; -static int __init jz4740_hwmon_init(void) -{ - return platform_driver_register(&jz4740_hwmon_driver); -} -module_init(jz4740_hwmon_init); - -static void __exit jz4740_hwmon_exit(void) -{ - platform_driver_unregister(&jz4740_hwmon_driver); -} -module_exit(jz4740_hwmon_exit); +module_platform_driver(jz4740_hwmon_driver); MODULE_DESCRIPTION("JZ4740 SoC HWMON driver"); MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c index 508cb291f71..5e6457a6644 100644 --- a/drivers/hwmon/lm63.c +++ b/drivers/hwmon/lm63.c @@ -47,10 +47,14 @@ #include <linux/err.h> #include <linux/mutex.h> #include <linux/sysfs.h> +#include <linux/types.h> /* * Addresses to scan - * Address is fully defined internally and cannot be changed. + * Address is fully defined internally and cannot be changed except for + * LM64 which has one pin dedicated to address selection. + * LM63 and LM96163 have address 0x4c. + * LM64 can have address 0x18 or 0x4e. */ static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END }; @@ -60,6 +64,7 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END }; */ #define LM63_REG_CONFIG1 0x03 +#define LM63_REG_CONVRATE 0x04 #define LM63_REG_CONFIG2 0xBF #define LM63_REG_CONFIG_FAN 0x4A @@ -70,6 +75,9 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END }; #define LM63_REG_PWM_VALUE 0x4C #define LM63_REG_PWM_FREQ 0x4D +#define LM63_REG_LUT_TEMP_HYST 0x4F +#define LM63_REG_LUT_TEMP(nr) (0x50 + 2 * (nr)) +#define LM63_REG_LUT_PWM(nr) (0x51 + 2 * (nr)) #define LM63_REG_LOCAL_TEMP 0x00 #define LM63_REG_LOCAL_HIGH 0x05 @@ -91,6 +99,16 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END }; #define LM63_REG_MAN_ID 0xFE #define LM63_REG_CHIP_ID 0xFF +#define LM96163_REG_TRUTHERM 0x30 +#define LM96163_REG_REMOTE_TEMP_U_MSB 0x31 +#define LM96163_REG_REMOTE_TEMP_U_LSB 0x32 +#define LM96163_REG_CONFIG_ENHANCED 0x45 + +#define LM63_MAX_CONVRATE 9 + +#define LM63_MAX_CONVRATE_HZ 32 +#define LM96163_MAX_CONVRATE_HZ 26 + /* * Conversions and various macros * For tachometer counts, the LM63 uses 16-bit values. @@ -112,15 +130,24 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END }; (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 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 UPDATE_INTERVAL(max, rate) \ + ((1000 << (LM63_MAX_CONVRATE - (rate))) / (max)) + /* * Functions declaration */ @@ -134,7 +161,7 @@ static struct lm63_data *lm63_update_device(struct device *dev); static int lm63_detect(struct i2c_client *client, struct i2c_board_info *info); static void lm63_init_client(struct i2c_client *client); -enum chips { lm63, lm64 }; +enum chips { lm63, lm64, lm96163 }; /* * Driver data (common to all clients) @@ -143,6 +170,7 @@ enum chips { lm63, lm64 }; static const struct i2c_device_id lm63_id[] = { { "lm63", lm63 }, { "lm64", lm64 }, + { "lm96163", lm96163 }, { } }; MODULE_DEVICE_TABLE(i2c, lm63_id); @@ -167,26 +195,53 @@ struct lm63_data { struct device *hwmon_dev; struct mutex update_lock; char valid; /* zero until following fields are valid */ + char lut_valid; /* zero until lut fields are valid */ unsigned long last_updated; /* in jiffies */ - int kind; + unsigned long lut_last_updated; /* in jiffies */ + enum chips kind; int temp2_offset; + int update_interval; /* in milliseconds */ + int max_convrate_hz; + int lut_size; /* 8 or 12 */ + /* registers values */ u8 config, config_fan; u16 fan[2]; /* 0: input 1: low limit */ u8 pwm1_freq; - u8 pwm1_value; - s8 temp8[3]; /* 0: local input + u8 pwm1[13]; /* 0: current output + 1-12: lookup table */ + s8 temp8[15]; /* 0: local input 1: local high limit - 2: remote critical limit */ - s16 temp11[3]; /* 0: remote input + 2: remote critical limit + 3-14: lookup table */ + s16 temp11[4]; /* 0: remote input 1: remote low limit - 2: remote high limit */ + 2: remote high limit + 3: remote offset */ + u16 temp11u; /* remote input (unsigned) */ u8 temp2_crit_hyst; + u8 lut_temp_hyst; u8 alarms; + bool pwm_highres; + bool lut_temp_highres; + bool remote_unsigned; /* true if unsigned remote upper limits */ + bool trutherm; }; +static inline int temp8_from_reg(struct lm63_data *data, int nr) +{ + if (data->remote_unsigned) + return TEMP8_FROM_REG((u8)data->temp8[nr]); + return TEMP8_FROM_REG(data->temp8[nr]); +} + +static inline int lut_temp_from_reg(struct lm63_data *data, int nr) +{ + return data->temp8[nr] * (data->lut_temp_highres ? 500 : 1000); +} + /* * Sysfs callback functions and files */ @@ -204,7 +259,12 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *dummy, { struct i2c_client *client = to_i2c_client(dev); struct lm63_data *data = i2c_get_clientdata(client); - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->fan[1] = FAN_TO_REG(val); @@ -216,13 +276,22 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *dummy, return count; } -static ssize_t show_pwm1(struct device *dev, struct device_attribute *dummy, +static ssize_t show_pwm1(struct device *dev, struct device_attribute *devattr, char *buf) { + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct lm63_data *data = lm63_update_device(dev); - return sprintf(buf, "%d\n", data->pwm1_value >= 2 * data->pwm1_freq ? - 255 : (data->pwm1_value * 255 + data->pwm1_freq) / - (2 * data->pwm1_freq)); + int nr = attr->index; + int pwm; + + if (data->pwm_highres) + pwm = data->pwm1[nr]; + else + pwm = data->pwm1[nr] >= 2 * data->pwm1_freq ? + 255 : (data->pwm1[nr] * 255 + data->pwm1_freq) / + (2 * data->pwm1_freq); + + return sprintf(buf, "%d\n", pwm); } static ssize_t set_pwm1(struct device *dev, struct device_attribute *dummy, @@ -231,22 +300,26 @@ static ssize_t set_pwm1(struct device *dev, struct device_attribute *dummy, struct i2c_client *client = to_i2c_client(dev); struct lm63_data *data = i2c_get_clientdata(client); unsigned long val; - + int err; + if (!(data->config_fan & 0x20)) /* register is read-only */ return -EPERM; - val = simple_strtoul(buf, NULL, 10); + err = kstrtoul(buf, 10, &val); + if (err) + return err; + + val = SENSORS_LIMIT(val, 0, 255); mutex_lock(&data->update_lock); - data->pwm1_value = val <= 0 ? 0 : - val >= 255 ? 2 * data->pwm1_freq : - (val * data->pwm1_freq * 2 + 127) / 255; - i2c_smbus_write_byte_data(client, LM63_REG_PWM_VALUE, data->pwm1_value); + data->pwm1[0] = data->pwm_highres ? val : + (val * data->pwm1_freq * 2 + 127) / 255; + i2c_smbus_write_byte_data(client, LM63_REG_PWM_VALUE, data->pwm1[0]); mutex_unlock(&data->update_lock); return count; } -static ssize_t show_pwm1_enable(struct device *dev, struct device_attribute *dummy, - char *buf) +static ssize_t show_pwm1_enable(struct device *dev, + struct device_attribute *dummy, char *buf) { struct lm63_data *data = lm63_update_device(dev); return sprintf(buf, "%d\n", data->config_fan & 0x20 ? 1 : 2); @@ -273,21 +346,47 @@ static ssize_t show_remote_temp8(struct device *dev, { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct lm63_data *data = lm63_update_device(dev); - return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[attr->index]) + return sprintf(buf, "%d\n", temp8_from_reg(data, attr->index) + + data->temp2_offset); +} + +static ssize_t show_lut_temp(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct lm63_data *data = lm63_update_device(dev); + return sprintf(buf, "%d\n", lut_temp_from_reg(data, attr->index) + data->temp2_offset); } -static ssize_t set_local_temp8(struct device *dev, - struct device_attribute *dummy, - const char *buf, size_t count) +static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr, + 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); - long val = simple_strtol(buf, NULL, 10); + int nr = attr->index; + int reg = nr == 2 ? LM63_REG_REMOTE_TCRIT : LM63_REG_LOCAL_HIGH; + long val; + int err; + int temp; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); - data->temp8[1] = TEMP8_TO_REG(val); - i2c_smbus_write_byte_data(client, LM63_REG_LOCAL_HIGH, data->temp8[1]); + if (nr == 2) { + if (data->remote_unsigned) + temp = TEMP8U_TO_REG(val - data->temp2_offset); + else + temp = TEMP8_TO_REG(val - data->temp2_offset); + } else { + temp = TEMP8_TO_REG(val); + } + data->temp8[nr] = temp; + i2c_smbus_write_byte_data(client, reg, temp); mutex_unlock(&data->update_lock); return count; } @@ -297,28 +396,56 @@ static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr, { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct lm63_data *data = lm63_update_device(dev); - return sprintf(buf, "%d\n", TEMP11_FROM_REG(data->temp11[attr->index]) - + data->temp2_offset); + int nr = attr->index; + int temp; + + if (!nr) { + /* + * Use unsigned temperature unless its value is zero. + * If it is zero, use signed temperature. + */ + if (data->temp11u) + temp = TEMP11_FROM_REG(data->temp11u); + else + temp = TEMP11_FROM_REG(data->temp11[nr]); + } else { + if (data->remote_unsigned && nr == 2) + temp = TEMP11_FROM_REG((u16)data->temp11[nr]); + else + temp = TEMP11_FROM_REG(data->temp11[nr]); + } + return sprintf(buf, "%d\n", temp + data->temp2_offset); } static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { - static const u8 reg[4] = { + static const u8 reg[6] = { LM63_REG_REMOTE_LOW_MSB, LM63_REG_REMOTE_LOW_LSB, LM63_REG_REMOTE_HIGH_MSB, LM63_REG_REMOTE_HIGH_LSB, + LM63_REG_REMOTE_OFFSET_MSB, + LM63_REG_REMOTE_OFFSET_LSB, }; 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); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; int nr = attr->index; + err = kstrtol(buf, 10, &val); + if (err) + return err; + mutex_lock(&data->update_lock); - data->temp11[nr] = TEMP11_TO_REG(val - data->temp2_offset); + if (data->remote_unsigned && nr == 2) + data->temp11[nr] = TEMP11U_TO_REG(val - data->temp2_offset); + else + data->temp11[nr] = TEMP11_TO_REG(val - data->temp2_offset); + i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2], data->temp11[nr] >> 8); i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1], @@ -327,35 +454,143 @@ static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, return count; } -/* Hysteresis register holds a relative value, while we want to present - an absolute to user-space */ -static ssize_t show_temp2_crit_hyst(struct device *dev, struct device_attribute *dummy, - char *buf) +/* + * Hysteresis register holds a relative value, while we want to present + * an absolute to user-space + */ +static ssize_t show_temp2_crit_hyst(struct device *dev, + struct device_attribute *dummy, char *buf) { struct lm63_data *data = lm63_update_device(dev); - return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[2]) + return sprintf(buf, "%d\n", temp8_from_reg(data, 2) + data->temp2_offset - TEMP8_FROM_REG(data->temp2_crit_hyst)); } -/* And now the other way around, user-space provides an absolute - hysteresis value and we have to store a relative one */ -static ssize_t set_temp2_crit_hyst(struct device *dev, struct device_attribute *dummy, +static ssize_t show_lut_temp_hyst(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct lm63_data *data = lm63_update_device(dev); + + return sprintf(buf, "%d\n", lut_temp_from_reg(data, attr->index) + + data->temp2_offset + - TEMP8_FROM_REG(data->lut_temp_hyst)); +} + +/* + * And now the other way around, user-space provides an absolute + * hysteresis value and we have to store a relative one + */ +static ssize_t set_temp2_crit_hyst(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); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; long hyst; + err = kstrtol(buf, 10, &val); + if (err) + return err; + mutex_lock(&data->update_lock); - hyst = TEMP8_FROM_REG(data->temp8[2]) + data->temp2_offset - val; + hyst = temp8_from_reg(data, 2) + data->temp2_offset - val; i2c_smbus_write_byte_data(client, LM63_REG_REMOTE_TCRIT_HYST, HYST_TO_REG(hyst)); mutex_unlock(&data->update_lock); return count; } +/* + * 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) +{ + int i; + unsigned int update_interval; + + /* Shift calculations to avoid rounding errors */ + interval <<= 6; + + /* find the nearest update rate */ + update_interval = (1 << (LM63_MAX_CONVRATE + 6)) * 1000 + / data->max_convrate_hz; + for (i = 0; i < LM63_MAX_CONVRATE; i++, update_interval >>= 1) + if (interval >= update_interval * 3 / 4) + break; + + i2c_smbus_write_byte_data(client, LM63_REG_CONVRATE, i); + data->update_interval = UPDATE_INTERVAL(data->max_convrate_hz, i); +} + +static ssize_t show_update_interval(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct lm63_data *data = dev_get_drvdata(dev); + + return sprintf(buf, "%u\n", data->update_interval); +} + +static ssize_t set_update_interval(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); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; + + mutex_lock(&data->update_lock); + lm63_set_convrate(client, data, SENSORS_LIMIT(val, 0, 100000)); + mutex_unlock(&data->update_lock); + + return count; +} + +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); + + return sprintf(buf, data->trutherm ? "1\n" : "2\n"); +} + +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); + unsigned long val; + int ret; + u8 reg; + + ret = kstrtoul(buf, 10, &val); + if (ret < 0) + return ret; + if (val != 1 && val != 2) + return -EINVAL; + + mutex_lock(&data->update_lock); + data->trutherm = val == 1; + reg = i2c_smbus_read_byte_data(client, LM96163_REG_TRUTHERM) & ~0x02; + i2c_smbus_write_byte_data(client, LM96163_REG_TRUTHERM, + reg | (data->trutherm ? 0x02 : 0x00)); + data->valid = 0; + mutex_unlock(&data->update_lock); + + return count; +} + static ssize_t show_alarms(struct device *dev, struct device_attribute *dummy, char *buf) { @@ -377,27 +612,87 @@ static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan, set_fan, 1); -static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm1, set_pwm1); +static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm1, set_pwm1, 0); static DEVICE_ATTR(pwm1_enable, S_IRUGO, show_pwm1_enable, NULL); +static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IRUGO, show_pwm1, NULL, 1); +static SENSOR_DEVICE_ATTR(pwm1_auto_point1_temp, S_IRUGO, + show_lut_temp, NULL, 3); +static SENSOR_DEVICE_ATTR(pwm1_auto_point1_temp_hyst, S_IRUGO, + show_lut_temp_hyst, NULL, 3); +static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IRUGO, show_pwm1, NULL, 2); +static SENSOR_DEVICE_ATTR(pwm1_auto_point2_temp, S_IRUGO, + show_lut_temp, NULL, 4); +static SENSOR_DEVICE_ATTR(pwm1_auto_point2_temp_hyst, S_IRUGO, + show_lut_temp_hyst, NULL, 4); +static SENSOR_DEVICE_ATTR(pwm1_auto_point3_pwm, S_IRUGO, show_pwm1, NULL, 3); +static SENSOR_DEVICE_ATTR(pwm1_auto_point3_temp, S_IRUGO, + show_lut_temp, NULL, 5); +static SENSOR_DEVICE_ATTR(pwm1_auto_point3_temp_hyst, S_IRUGO, + show_lut_temp_hyst, NULL, 5); +static SENSOR_DEVICE_ATTR(pwm1_auto_point4_pwm, S_IRUGO, show_pwm1, NULL, 4); +static SENSOR_DEVICE_ATTR(pwm1_auto_point4_temp, S_IRUGO, + show_lut_temp, NULL, 6); +static SENSOR_DEVICE_ATTR(pwm1_auto_point4_temp_hyst, S_IRUGO, + show_lut_temp_hyst, NULL, 6); +static SENSOR_DEVICE_ATTR(pwm1_auto_point5_pwm, S_IRUGO, show_pwm1, NULL, 5); +static SENSOR_DEVICE_ATTR(pwm1_auto_point5_temp, S_IRUGO, + show_lut_temp, NULL, 7); +static SENSOR_DEVICE_ATTR(pwm1_auto_point5_temp_hyst, S_IRUGO, + show_lut_temp_hyst, NULL, 7); +static SENSOR_DEVICE_ATTR(pwm1_auto_point6_pwm, S_IRUGO, show_pwm1, NULL, 6); +static SENSOR_DEVICE_ATTR(pwm1_auto_point6_temp, S_IRUGO, + show_lut_temp, NULL, 8); +static SENSOR_DEVICE_ATTR(pwm1_auto_point6_temp_hyst, S_IRUGO, + show_lut_temp_hyst, NULL, 8); +static SENSOR_DEVICE_ATTR(pwm1_auto_point7_pwm, S_IRUGO, show_pwm1, NULL, 7); +static SENSOR_DEVICE_ATTR(pwm1_auto_point7_temp, S_IRUGO, + show_lut_temp, NULL, 9); +static SENSOR_DEVICE_ATTR(pwm1_auto_point7_temp_hyst, S_IRUGO, + show_lut_temp_hyst, NULL, 9); +static SENSOR_DEVICE_ATTR(pwm1_auto_point8_pwm, S_IRUGO, show_pwm1, NULL, 8); +static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp, S_IRUGO, + show_lut_temp, NULL, 10); +static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp_hyst, S_IRUGO, + show_lut_temp_hyst, NULL, 10); +static SENSOR_DEVICE_ATTR(pwm1_auto_point9_pwm, S_IRUGO, show_pwm1, NULL, 9); +static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp, S_IRUGO, + show_lut_temp, NULL, 11); +static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp_hyst, S_IRUGO, + show_lut_temp_hyst, NULL, 11); +static SENSOR_DEVICE_ATTR(pwm1_auto_point10_pwm, S_IRUGO, show_pwm1, NULL, 10); +static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp, S_IRUGO, + show_lut_temp, NULL, 12); +static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp_hyst, S_IRUGO, + show_lut_temp_hyst, NULL, 12); +static SENSOR_DEVICE_ATTR(pwm1_auto_point11_pwm, S_IRUGO, show_pwm1, NULL, 11); +static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp, S_IRUGO, + show_lut_temp, NULL, 13); +static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp_hyst, S_IRUGO, + show_lut_temp_hyst, NULL, 13); +static SENSOR_DEVICE_ATTR(pwm1_auto_point12_pwm, S_IRUGO, show_pwm1, NULL, 12); +static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp, S_IRUGO, + show_lut_temp, NULL, 14); +static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp_hyst, S_IRUGO, + show_lut_temp_hyst, NULL, 14); static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_local_temp8, NULL, 0); static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_local_temp8, - set_local_temp8, 1); + set_temp8, 1); static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0); static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11, set_temp11, 1); static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp11, set_temp11, 2); -/* - * On LM63, temp2_crit can be set only once, which should be job - * of the bootloader. - */ +static SENSOR_DEVICE_ATTR(temp2_offset, S_IWUSR | S_IRUGO, show_temp11, + set_temp11, 3); static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_remote_temp8, - NULL, 2); + set_temp8, 2); static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp2_crit_hyst, set_temp2_crit_hyst); +static DEVICE_ATTR(temp2_type, S_IWUSR | S_IRUGO, show_type, set_type); + /* Individual alarm files */ static SENSOR_DEVICE_ATTR(fan1_min_alarm, S_IRUGO, show_alarm, NULL, 0); static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1); @@ -408,14 +703,43 @@ static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6); /* Raw alarm file for compatibility */ static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); +static DEVICE_ATTR(update_interval, S_IRUGO | S_IWUSR, show_update_interval, + set_update_interval); + static struct attribute *lm63_attributes[] = { - &dev_attr_pwm1.attr, + &sensor_dev_attr_pwm1.dev_attr.attr, &dev_attr_pwm1_enable.attr, + &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point1_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point1_temp_hyst.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point2_temp_hyst.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point3_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point3_temp_hyst.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point4_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point4_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point4_temp_hyst.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point5_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point5_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point5_temp_hyst.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point6_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point6_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point6_temp_hyst.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point7_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point7_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point7_temp_hyst.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point8_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point8_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point8_temp_hyst.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_temp2_input.dev_attr.attr, &sensor_dev_attr_temp2_min.dev_attr.attr, &sensor_dev_attr_temp1_max.dev_attr.attr, &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp2_offset.dev_attr.attr, &sensor_dev_attr_temp2_crit.dev_attr.attr, &dev_attr_temp2_crit_hyst.attr, @@ -425,10 +749,54 @@ static struct attribute *lm63_attributes[] = { &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, &dev_attr_alarms.attr, + &dev_attr_update_interval.attr, NULL }; +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, + &sensor_dev_attr_pwm1_auto_point9_temp_hyst.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point10_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point10_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point10_temp_hyst.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point11_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point11_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point11_temp_hyst.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point12_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point12_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point12_temp_hyst.dev_attr.attr, + NULL +}; + +static const struct attribute_group lm63_group_extra_lut = { + .attrs = lm63_attributes_extra_lut, +}; + +/* + * On LM63, temp2_crit can be set only once, which should be job + * of the bootloader. + * On LM64, temp2_crit can always be set. + * On LM96163, temp2_crit can be set if bit 1 of the configuration + * register is true. + */ +static umode_t lm63_attribute_mode(struct kobject *kobj, + 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); + + if (attr == &sensor_dev_attr_temp2_crit.dev_attr.attr + && (data->kind == lm64 || + (data->kind == lm96163 && (data->config & 0x02)))) + return attr->mode | S_IWUSR; + + return attr->mode; +} + static const struct attribute_group lm63_group = { + .is_visible = lm63_attribute_mode, .attrs = lm63_attributes, }; @@ -487,6 +855,8 @@ static int lm63_detect(struct i2c_client *new_client, strlcpy(info->type, "lm63", I2C_NAME_SIZE); else if (chip_id == 0x51 && (address == 0x18 || address == 0x4e)) strlcpy(info->type, "lm64", I2C_NAME_SIZE); + else if (chip_id == 0x49 && address == 0x4c) + strlcpy(info->type, "lm96163", I2C_NAME_SIZE); else return -ENODEV; @@ -518,12 +888,24 @@ static int lm63_probe(struct i2c_client *new_client, lm63_init_client(new_client); /* Register sysfs hooks */ - if ((err = sysfs_create_group(&new_client->dev.kobj, - &lm63_group))) + err = sysfs_create_group(&new_client->dev.kobj, &lm63_group); + if (err) goto exit_free; if (data->config & 0x04) { /* tachometer enabled */ - if ((err = sysfs_create_group(&new_client->dev.kobj, - &lm63_group_fan1))) + err = sysfs_create_group(&new_client->dev.kobj, + &lm63_group_fan1); + if (err) + goto exit_remove_files; + } + if (data->kind == lm96163) { + err = device_create_file(&new_client->dev, + &dev_attr_temp2_type); + if (err) + goto exit_remove_files; + + err = sysfs_create_group(&new_client->dev.kobj, + &lm63_group_extra_lut); + if (err) goto exit_remove_files; } @@ -538,17 +920,25 @@ static int lm63_probe(struct i2c_client *new_client, exit_remove_files: sysfs_remove_group(&new_client->dev.kobj, &lm63_group); sysfs_remove_group(&new_client->dev.kobj, &lm63_group_fan1); + if (data->kind == lm96163) { + device_remove_file(&new_client->dev, &dev_attr_temp2_type); + sysfs_remove_group(&new_client->dev.kobj, + &lm63_group_extra_lut); + } exit_free: kfree(data); exit: return err; } -/* Idealy we shouldn't have to initialize anything, since the BIOS - should have taken care of everything */ +/* + * 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) { struct lm63_data *data = i2c_get_clientdata(client); + u8 convrate; data->config = i2c_smbus_read_byte_data(client, LM63_REG_CONFIG1); data->config_fan = i2c_smbus_read_byte_data(client, @@ -561,16 +951,57 @@ static void lm63_init_client(struct i2c_client *client) i2c_smbus_write_byte_data(client, LM63_REG_CONFIG1, data->config); } + /* Tachometer is always enabled on LM64 */ + if (data->kind == lm64) + data->config |= 0x04; /* We may need pwm1_freq before ever updating the client data */ data->pwm1_freq = i2c_smbus_read_byte_data(client, LM63_REG_PWM_FREQ); if (data->pwm1_freq == 0) data->pwm1_freq = 1; + switch (data->kind) { + case lm63: + case lm64: + data->max_convrate_hz = LM63_MAX_CONVRATE_HZ; + data->lut_size = 8; + break; + case lm96163: + data->max_convrate_hz = LM96163_MAX_CONVRATE_HZ; + data->lut_size = 12; + data->trutherm + = i2c_smbus_read_byte_data(client, + LM96163_REG_TRUTHERM) & 0x02; + break; + } + convrate = i2c_smbus_read_byte_data(client, LM63_REG_CONVRATE); + if (unlikely(convrate > LM63_MAX_CONVRATE)) + convrate = LM63_MAX_CONVRATE; + data->update_interval = UPDATE_INTERVAL(data->max_convrate_hz, + convrate); + + /* + * For LM96163, check if high resolution PWM + * and unsigned temperature format is enabled. + */ + if (data->kind == lm96163) { + u8 config_enhanced + = i2c_smbus_read_byte_data(client, + LM96163_REG_CONFIG_ENHANCED); + if (config_enhanced & 0x20) + data->lut_temp_highres = true; + if ((config_enhanced & 0x10) + && !(data->config_fan & 0x08) && data->pwm1_freq == 8) + data->pwm_highres = true; + if (config_enhanced & 0x08) + data->remote_unsigned = true; + } + /* Show some debug info about the LM63 configuration */ - dev_dbg(&client->dev, "Alert/tach pin configured for %s\n", - (data->config & 0x04) ? "tachometer input" : - "alert output"); + if (data->kind == lm63) + dev_dbg(&client->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", (data->config_fan & 0x08) ? "1.4" : "360", ((data->config_fan & 0x08) ? 700 : 180000) / data->pwm1_freq); @@ -586,6 +1017,10 @@ static int lm63_remove(struct i2c_client *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); + } kfree(data); return 0; @@ -595,10 +1030,15 @@ 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); + unsigned long next_update; + int i; mutex_lock(&data->update_lock); - if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { + next_update = data->last_updated + + msecs_to_jiffies(data->update_interval) + 1; + + if (time_after(jiffies, next_update) || !data->valid) { if (data->config & 0x04) { /* tachometer enabled */ /* order matters for fan1_input */ data->fan[0] = i2c_smbus_read_byte_data(client, @@ -615,8 +1055,8 @@ static struct lm63_data *lm63_update_device(struct device *dev) LM63_REG_PWM_FREQ); if (data->pwm1_freq == 0) data->pwm1_freq = 1; - data->pwm1_value = i2c_smbus_read_byte_data(client, - LM63_REG_PWM_VALUE); + data->pwm1[0] = i2c_smbus_read_byte_data(client, + LM63_REG_PWM_VALUE); data->temp8[0] = i2c_smbus_read_byte_data(client, LM63_REG_LOCAL_TEMP); @@ -636,6 +1076,17 @@ static struct lm63_data *lm63_update_device(struct device *dev) LM63_REG_REMOTE_HIGH_MSB) << 8) | i2c_smbus_read_byte_data(client, LM63_REG_REMOTE_HIGH_LSB); + data->temp11[3] = (i2c_smbus_read_byte_data(client, + LM63_REG_REMOTE_OFFSET_MSB) << 8) + | i2c_smbus_read_byte_data(client, + LM63_REG_REMOTE_OFFSET_LSB); + + if (data->kind == lm96163) + data->temp11u = (i2c_smbus_read_byte_data(client, + LM96163_REG_REMOTE_TEMP_U_MSB) << 8) + | i2c_smbus_read_byte_data(client, + LM96163_REG_REMOTE_TEMP_U_LSB); + data->temp8[2] = i2c_smbus_read_byte_data(client, LM63_REG_REMOTE_TCRIT); data->temp2_crit_hyst = i2c_smbus_read_byte_data(client, @@ -648,6 +1099,21 @@ static struct lm63_data *lm63_update_device(struct device *dev) data->valid = 1; } + if (time_after(jiffies, data->lut_last_updated + 5 * HZ) || + !data->lut_valid) { + for (i = 0; i < data->lut_size; i++) { + data->pwm1[1 + i] = i2c_smbus_read_byte_data(client, + LM63_REG_LUT_PWM(i)); + data->temp8[3 + i] = i2c_smbus_read_byte_data(client, + LM63_REG_LUT_TEMP(i)); + } + data->lut_temp_hyst = i2c_smbus_read_byte_data(client, + LM63_REG_LUT_TEMP_HYST); + + data->lut_last_updated = jiffies; + data->lut_valid = 1; + } + mutex_unlock(&data->update_lock); return data; diff --git a/drivers/hwmon/lm73.c b/drivers/hwmon/lm73.c index 9e64d96620d..9c8093c4b30 100644 --- a/drivers/hwmon/lm73.c +++ b/drivers/hwmon/lm73.c @@ -50,7 +50,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da, long temp; short value; - int status = strict_strtol(buf, 10, &temp); + int status = kstrtol(buf, 10, &temp); if (status < 0) return status; diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index 1888dd0fc05..b3311b1d3d9 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c @@ -93,6 +93,10 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *da, { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct lm75_data *data = lm75_update_device(dev); + + if (IS_ERR(data)) + return PTR_ERR(data); + return sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(data->temp[attr->index])); } @@ -107,7 +111,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da, long temp; int error; - error = strict_strtol(buf, 10, &temp); + error = kstrtol(buf, 10, &temp); if (error) return error; @@ -402,6 +406,7 @@ static struct lm75_data *lm75_update_device(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct lm75_data *data = i2c_get_clientdata(client); + struct lm75_data *ret = data; mutex_lock(&data->update_lock); @@ -414,19 +419,23 @@ static struct lm75_data *lm75_update_device(struct device *dev) int status; status = lm75_read_value(client, LM75_REG_TEMP[i]); - if (status < 0) - dev_dbg(&client->dev, "reg %d, err %d\n", - LM75_REG_TEMP[i], status); - else - data->temp[i] = status; + if (unlikely(status < 0)) { + dev_dbg(dev, + "LM75: Failed to read value: reg %d, error %d\n", + LM75_REG_TEMP[i], status); + ret = ERR_PTR(status); + data->valid = 0; + goto abort; + } + data->temp[i] = status; } data->last_updated = jiffies; data->valid = 1; } +abort: mutex_unlock(&data->update_lock); - - return data; + return ret; } /*-----------------------------------------------------------------------*/ diff --git a/drivers/hwmon/lm75.h b/drivers/hwmon/lm75.h index e547a3eb4de..89aa9098ba5 100644 --- a/drivers/hwmon/lm75.h +++ b/drivers/hwmon/lm75.h @@ -1,6 +1,6 @@ /* lm75.h - Part of lm_sensors, Linux kernel modules for hardware - monitoring + monitoring Copyright (c) 2003 Mark M. Hoffman <mhoffman@lightlink.com> This program is free software; you can redistribute it and/or modify @@ -37,7 +37,7 @@ static inline u16 LM75_TEMP_TO_REG(long temp) { int ntemp = SENSORS_LIMIT(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); - ntemp += (ntemp<0 ? -250 : 250); + ntemp += (ntemp < 0 ? -250 : 250); return (u16)((ntemp / 500) << 7); } @@ -47,4 +47,3 @@ static inline int LM75_TEMP_FROM_REG(u16 reg) guarantee arithmetic shift and preserve the sign */ return ((s16)reg / 128) * 500; } - diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c index 18a0e6c5fe8..0891b38ffec 100644 --- a/drivers/hwmon/lm80.c +++ b/drivers/hwmon/lm80.c @@ -66,19 +66,19 @@ static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, these macros are called: arguments may be evaluated more than once. Fixing this is just not worth it. */ -#define IN_TO_REG(val) (SENSORS_LIMIT(((val)+5)/10,0,255)) -#define IN_FROM_REG(val) ((val)*10) +#define IN_TO_REG(val) (SENSORS_LIMIT(((val) + 5) / 10, 0, 255)) +#define IN_FROM_REG(val) ((val) * 10) static inline unsigned char FAN_TO_REG(unsigned rpm, unsigned div) { if (rpm == 0) return 255; rpm = SENSORS_LIMIT(rpm, 1, 1000000); - return SENSORS_LIMIT((1350000 + rpm*div / 2) / (rpm*div), 1, 254); + return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254); } -#define FAN_FROM_REG(val,div) ((val)==0?-1:\ - (val)==255?0:1350000/((div)*(val))) +#define FAN_FROM_REG(val, div) ((val) == 0 ? -1 : \ + (val) == 255 ? 0 : 1350000/((div) * (val))) static inline long TEMP_FROM_REG(u16 temp) { @@ -93,10 +93,11 @@ static inline long TEMP_FROM_REG(u16 temp) return res / 10; } -#define TEMP_LIMIT_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*1000) +#define TEMP_LIMIT_FROM_REG(val) (((val) > 0x80 ? \ + (val) - 0x100 : (val)) * 1000) -#define TEMP_LIMIT_TO_REG(val) SENSORS_LIMIT((val)<0?\ - ((val)-500)/1000:((val)+500)/1000,0,255) +#define TEMP_LIMIT_TO_REG(val) SENSORS_LIMIT((val) < 0 ? \ + ((val) - 500) / 1000 : ((val) + 500) / 1000, 0, 255) #define DIV_FROM_REG(val) (1 << (val)) @@ -164,7 +165,8 @@ static struct i2c_driver lm80_driver = { */ #define show_in(suffix, value) \ -static ssize_t show_in_##suffix(struct device *dev, struct device_attribute *attr, char *buf) \ +static ssize_t show_in_##suffix(struct device *dev, \ + struct device_attribute *attr, char *buf) \ { \ int nr = to_sensor_dev_attr(attr)->index; \ struct lm80_data *data = lm80_update_device(dev); \ @@ -175,14 +177,14 @@ show_in(max, in_max) show_in(input, in) #define set_in(suffix, value, reg) \ -static ssize_t set_in_##suffix(struct device *dev, struct device_attribute *attr, const char *buf, \ - size_t count) \ +static ssize_t set_in_##suffix(struct device *dev, \ + struct device_attribute *attr, const char *buf, size_t count) \ { \ int nr = to_sensor_dev_attr(attr)->index; \ struct i2c_client *client = to_i2c_client(dev); \ struct lm80_data *data = i2c_get_clientdata(client); \ long val = simple_strtol(buf, NULL, 10); \ - \ +\ mutex_lock(&data->update_lock);\ data->value[nr] = IN_TO_REG(val); \ lm80_write_value(client, reg(nr), data->value[nr]); \ @@ -193,7 +195,8 @@ set_in(min, in_min, LM80_REG_IN_MIN) set_in(max, in_max, LM80_REG_IN_MAX) #define show_fan(suffix, value) \ -static ssize_t show_fan_##suffix(struct device *dev, struct device_attribute *attr, char *buf) \ +static ssize_t show_fan_##suffix(struct device *dev, \ + struct device_attribute *attr, char *buf) \ { \ int nr = to_sensor_dev_attr(attr)->index; \ struct lm80_data *data = lm80_update_device(dev); \ @@ -245,10 +248,18 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, DIV_FROM_REG(data->fan_div[nr])); switch (val) { - case 1: data->fan_div[nr] = 0; break; - case 2: data->fan_div[nr] = 1; break; - case 4: data->fan_div[nr] = 2; break; - case 8: data->fan_div[nr] = 3; break; + case 1: + data->fan_div[nr] = 0; + break; + case 2: + data->fan_div[nr] = 1; + break; + case 4: + data->fan_div[nr] = 2; + break; + case 8: + data->fan_div[nr] = 3; + break; default: dev_err(&client->dev, "fan_div value %ld not " "supported. Choose one of 1, 2, 4 or 8!\n", val); @@ -268,14 +279,16 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, return count; } -static ssize_t show_temp_input1(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_temp_input1(struct device *dev, + struct device_attribute *attr, char *buf) { struct lm80_data *data = lm80_update_device(dev); return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp)); } #define show_temp(suffix, value) \ -static ssize_t show_temp_##suffix(struct device *dev, struct device_attribute *attr, char *buf) \ +static ssize_t show_temp_##suffix(struct device *dev, \ + struct device_attribute *attr, char *buf) \ { \ struct lm80_data *data = lm80_update_device(dev); \ return sprintf(buf, "%d\n", TEMP_LIMIT_FROM_REG(data->value)); \ @@ -286,13 +299,13 @@ show_temp(os_max, temp_os_max); show_temp(os_hyst, temp_os_hyst); #define set_temp(suffix, value, reg) \ -static ssize_t set_temp_##suffix(struct device *dev, struct device_attribute *attr, const char *buf, \ - size_t count) \ +static ssize_t set_temp_##suffix(struct device *dev, \ + struct device_attribute *attr, const char *buf, size_t count) \ { \ struct i2c_client *client = to_i2c_client(dev); \ struct lm80_data *data = i2c_get_clientdata(client); \ long val = simple_strtoul(buf, NULL, 10); \ - \ +\ mutex_lock(&data->update_lock); \ data->value = TEMP_LIMIT_TO_REG(val); \ lm80_write_value(client, reg, data->value); \ @@ -366,13 +379,13 @@ static SENSOR_DEVICE_ATTR(fan2_div, S_IWUSR | S_IRUGO, show_fan_div, set_fan_div, 1); static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input1, NULL); static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_hot_max, - set_temp_hot_max); + set_temp_hot_max); static DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, show_temp_hot_hyst, - set_temp_hot_hyst); + set_temp_hot_hyst); static DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp_os_max, - set_temp_os_max); + set_temp_os_max); static DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temp_os_hyst, - set_temp_os_hyst); + set_temp_os_hyst); static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); @@ -459,7 +472,7 @@ static int lm80_detect(struct i2c_client *client, struct i2c_board_info *info) if ((i2c_smbus_read_byte_data(client, i + 0x40) != cur) || (i2c_smbus_read_byte_data(client, i + 0x80) != cur) || (i2c_smbus_read_byte_data(client, i + 0xc0) != cur)) - return -ENODEV; + return -ENODEV; } strlcpy(info->type, "lm80", I2C_NAME_SIZE); @@ -490,7 +503,8 @@ static int lm80_probe(struct i2c_client *client, data->fan_min[1] = lm80_read_value(client, LM80_REG_FAN_MIN(2)); /* Register sysfs hooks */ - if ((err = sysfs_create_group(&client->dev.kobj, &lm80_group))) + err = sysfs_create_group(&client->dev.kobj, &lm80_group); + if (err) goto error_free; data->hwmon_dev = hwmon_device_register(&client->dev); diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index 615bc4f4e53..d2dd5f90496 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c @@ -730,7 +730,7 @@ static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr, long val; int err; - err = strict_strtol(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err < 0) return err; @@ -798,7 +798,7 @@ static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, long val; int err; - err = strict_strtol(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err < 0) return err; @@ -859,7 +859,7 @@ static ssize_t set_temphyst(struct device *dev, struct device_attribute *dummy, int err; int temp; - err = strict_strtol(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err < 0) return err; @@ -912,12 +912,12 @@ static ssize_t set_update_interval(struct device *dev, unsigned long val; int err; - err = strict_strtoul(buf, 10, &val); + err = kstrtoul(buf, 10, &val); if (err) return err; mutex_lock(&data->update_lock); - lm90_set_convrate(client, data, val); + lm90_set_convrate(client, data, SENSORS_LIMIT(val, 0, 100000)); mutex_unlock(&data->update_lock); return count; @@ -1080,7 +1080,7 @@ static ssize_t set_pec(struct device *dev, struct device_attribute *dummy, long val; int err; - err = strict_strtol(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err < 0) return err; diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c index 3b43df41861..8bd6c5c9e05 100644 --- a/drivers/hwmon/lm93.c +++ b/drivers/hwmon/lm93.c @@ -151,12 +151,12 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; /* Insmod parameters */ -static int disable_block; +static bool disable_block; module_param(disable_block, bool, 0); MODULE_PARM_DESC(disable_block, "Set to non-zero to disable SMBus block data transactions."); -static int init; +static bool init; module_param(init, bool, 0); MODULE_PARM_DESC(init, "Set to non-zero to force chip initialization."); diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c index 513901d592a..70bca671e08 100644 --- a/drivers/hwmon/lm95241.c +++ b/drivers/hwmon/lm95241.c @@ -169,7 +169,7 @@ static ssize_t set_type(struct device *dev, struct device_attribute *attr, int shift; u8 mask = to_sensor_dev_attr(attr)->index; - if (strict_strtoul(buf, 10, &val) < 0) + if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; if (val != 1 && val != 2) return -EINVAL; @@ -216,7 +216,7 @@ static ssize_t set_min(struct device *dev, struct device_attribute *attr, struct lm95241_data *data = i2c_get_clientdata(client); long val; - if (strict_strtol(buf, 10, &val) < 0) + if (kstrtol(buf, 10, &val) < 0) return -EINVAL; if (val < -128000) return -EINVAL; @@ -254,7 +254,7 @@ static ssize_t set_max(struct device *dev, struct device_attribute *attr, struct lm95241_data *data = i2c_get_clientdata(client); long val; - if (strict_strtol(buf, 10, &val) < 0) + if (kstrtol(buf, 10, &val) < 0) return -EINVAL; if (val >= 256000) return -EINVAL; @@ -290,7 +290,7 @@ static ssize_t set_interval(struct device *dev, struct device_attribute *attr, struct lm95241_data *data = i2c_get_clientdata(client); unsigned long val; - if (strict_strtoul(buf, 10, &val) < 0) + if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; data->interval = val * HZ / 1000; diff --git a/drivers/hwmon/lm95245.c b/drivers/hwmon/lm95245.c index dce9e68241e..5e5fc1b0ace 100644 --- a/drivers/hwmon/lm95245.c +++ b/drivers/hwmon/lm95245.c @@ -254,7 +254,7 @@ static ssize_t set_limit(struct device *dev, struct device_attribute *attr, int index = to_sensor_dev_attr(attr)->index; unsigned long val; - if (strict_strtoul(buf, 10, &val) < 0) + if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; val /= 1000; @@ -279,7 +279,7 @@ static ssize_t set_crit_hyst(struct device *dev, struct device_attribute *attr, struct lm95245_data *data = i2c_get_clientdata(client); unsigned long val; - if (strict_strtoul(buf, 10, &val) < 0) + if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; val /= 1000; @@ -316,7 +316,7 @@ static ssize_t set_type(struct device *dev, struct device_attribute *attr, struct lm95245_data *data = i2c_get_clientdata(client); unsigned long val; - if (strict_strtoul(buf, 10, &val) < 0) + if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; if (val != 1 && val != 2) return -EINVAL; @@ -363,7 +363,7 @@ static ssize_t set_interval(struct device *dev, struct device_attribute *attr, struct lm95245_data *data = i2c_get_clientdata(client); unsigned long val; - if (strict_strtoul(buf, 10, &val) < 0) + if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; mutex_lock(&data->update_lock); diff --git a/drivers/hwmon/ltc4261.c b/drivers/hwmon/ltc4261.c index 4b50601027d..ce5235560f0 100644 --- a/drivers/hwmon/ltc4261.c +++ b/drivers/hwmon/ltc4261.c @@ -85,6 +85,7 @@ static struct ltc4261_data *ltc4261_update_device(struct device *dev) "Failed to read ADC value: error %d\n", val); ret = ERR_PTR(val); + data->valid = 0; goto abort; } data->regs[i] = val; diff --git a/drivers/hwmon/max1111.c b/drivers/hwmon/max1111.c index c97b78ef911..482ca901db3 100644 --- a/drivers/hwmon/max1111.c +++ b/drivers/hwmon/max1111.c @@ -6,7 +6,7 @@ * Copyright (C) 2004-2005 Richard Purdie * * Copyright (C) 2008 Marvell International Ltd. - * Eric Miao <eric.miao@marvell.com> + * Eric Miao <eric.miao@marvell.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -106,11 +106,14 @@ static ssize_t show_adc(struct device *dev, if (ret < 0) return ret; - return sprintf(buf, "%d\n", ret); + /* assume the reference voltage to be 2.048V, with an 8-bit sample, + * the LSB weight is 8mV + */ + return sprintf(buf, "%d\n", ret * 8); } #define MAX1111_ADC_ATTR(_id) \ - SENSOR_DEVICE_ATTR(adc##_id##_in, S_IRUGO, show_adc, NULL, _id) + SENSOR_DEVICE_ATTR(in##_id##_input, S_IRUGO, show_adc, NULL, _id) static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); static MAX1111_ADC_ATTR(0); @@ -120,10 +123,10 @@ static MAX1111_ADC_ATTR(3); static struct attribute *max1111_attributes[] = { &dev_attr_name.attr, - &sensor_dev_attr_adc0_in.dev_attr.attr, - &sensor_dev_attr_adc1_in.dev_attr.attr, - &sensor_dev_attr_adc2_in.dev_attr.attr, - &sensor_dev_attr_adc3_in.dev_attr.attr, + &sensor_dev_attr_in0_input.dev_attr.attr, + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_in3_input.dev_attr.attr, NULL, }; diff --git a/drivers/hwmon/max16065.c b/drivers/hwmon/max16065.c index 385886a4f22..f8e323ac6cb 100644 --- a/drivers/hwmon/max16065.c +++ b/drivers/hwmon/max16065.c @@ -230,7 +230,7 @@ static ssize_t max16065_set_limit(struct device *dev, int err; int limit; - err = strict_strtoul(buf, 10, &val); + err = kstrtoul(buf, 10, &val); if (unlikely(err < 0)) return err; diff --git a/drivers/hwmon/max1668.c b/drivers/hwmon/max1668.c index 20d1b2ddffb..88953f99e91 100644 --- a/drivers/hwmon/max1668.c +++ b/drivers/hwmon/max1668.c @@ -59,7 +59,7 @@ static unsigned short max1668_addr_list[] = { #define DEV_ID_MAX1989 0xb /* read only mode module parameter */ -static int read_only; +static bool read_only; module_param(read_only, bool, 0); MODULE_PARM_DESC(read_only, "Don't set any values, read only mode"); @@ -335,10 +335,10 @@ static struct attribute *max1668_attribute_unique[] = { NULL }; -static mode_t max1668_attribute_mode(struct kobject *kobj, +static umode_t max1668_attribute_mode(struct kobject *kobj, struct attribute *attr, int index) { - int ret = S_IRUGO; + umode_t ret = S_IRUGO; if (read_only) return ret; if (attr == &sensor_dev_attr_temp1_max.dev_attr.attr || diff --git a/drivers/hwmon/max6639.c b/drivers/hwmon/max6639.c index f20d9978ee7..a6760bacd91 100644 --- a/drivers/hwmon/max6639.c +++ b/drivers/hwmon/max6639.c @@ -72,8 +72,8 @@ static unsigned short normal_i2c[] = { 0x2c, 0x2e, 0x2f, I2C_CLIENT_END }; static const int rpm_ranges[] = { 2000, 4000, 8000, 16000 }; -#define FAN_FROM_REG(val, div, rpm_range) ((val) == 0 ? -1 : \ - (val) == 255 ? 0 : (rpm_ranges[rpm_range] * 30) / ((div + 1) * (val))) +#define FAN_FROM_REG(val, rpm_range) ((val) == 0 || (val) == 255 ? \ + 0 : (rpm_ranges[rpm_range] * 30) / (val)) #define TEMP_LIMIT_TO_REG(val) SENSORS_LIMIT((val) / 1000, 0, 255) /* @@ -208,7 +208,7 @@ static ssize_t set_temp_max(struct device *dev, unsigned long val; int res; - res = strict_strtoul(buf, 10, &val); + res = kstrtoul(buf, 10, &val); if (res) return res; @@ -241,7 +241,7 @@ static ssize_t set_temp_crit(struct device *dev, unsigned long val; int res; - res = strict_strtoul(buf, 10, &val); + res = kstrtoul(buf, 10, &val); if (res) return res; @@ -275,7 +275,7 @@ static ssize_t set_temp_emergency(struct device *dev, unsigned long val; int res; - res = strict_strtoul(buf, 10, &val); + res = kstrtoul(buf, 10, &val); if (res) return res; @@ -308,7 +308,7 @@ static ssize_t set_pwm(struct device *dev, unsigned long val; int res; - res = strict_strtoul(buf, 10, &val); + res = kstrtoul(buf, 10, &val); if (res) return res; @@ -333,7 +333,7 @@ static ssize_t show_fan_input(struct device *dev, return PTR_ERR(data); return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[attr->index], - data->ppr, data->rpm_range)); + data->rpm_range)); } static ssize_t show_alarm(struct device *dev, @@ -429,9 +429,9 @@ static int max6639_init_client(struct i2c_client *client) struct max6639_data *data = i2c_get_clientdata(client); struct max6639_platform_data *max6639_info = client->dev.platform_data; - int i = 0; + int i; int rpm_range = 1; /* default: 4000 RPM */ - int err = 0; + int err; /* Reset chip to default values, see below for GCONFIG setup */ err = i2c_smbus_write_byte_data(client, MAX6639_REG_GCONFIG, @@ -446,11 +446,6 @@ static int max6639_init_client(struct i2c_client *client) else data->ppr = 2; data->ppr -= 1; - err = i2c_smbus_write_byte_data(client, - MAX6639_REG_FAN_PPR(i), - data->ppr << 5); - if (err) - goto exit; if (max6639_info) rpm_range = rpm_range_to_reg(max6639_info->rpm_range); @@ -458,6 +453,13 @@ static int max6639_init_client(struct i2c_client *client) for (i = 0; i < 2; i++) { + /* Set Fan pulse per revolution */ + err = i2c_smbus_write_byte_data(client, + MAX6639_REG_FAN_PPR(i), + data->ppr << 6); + if (err) + goto exit; + /* Fans config PWM, RPM */ err = i2c_smbus_write_byte_data(client, MAX6639_REG_FAN_CONFIG1(i), diff --git a/drivers/hwmon/max6642.c b/drivers/hwmon/max6642.c index e855d3b0bd1..209e8a526eb 100644 --- a/drivers/hwmon/max6642.c +++ b/drivers/hwmon/max6642.c @@ -234,7 +234,7 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, struct max6642_data *data = i2c_get_clientdata(client); struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(attr); - err = strict_strtoul(buf, 10, &val); + err = kstrtoul(buf, 10, &val); if (err < 0) return err; diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c index ece3aafa54b..2fc034aeca0 100644 --- a/drivers/hwmon/max6650.c +++ b/drivers/hwmon/max6650.c @@ -464,7 +464,7 @@ static SENSOR_DEVICE_ATTR(gpio1_alarm, S_IRUGO, get_alarm, NULL, static SENSOR_DEVICE_ATTR(gpio2_alarm, S_IRUGO, get_alarm, NULL, MAX6650_ALRM_GPIO2); -static mode_t max6650_attrs_visible(struct kobject *kobj, struct attribute *a, +static umode_t max6650_attrs_visible(struct kobject *kobj, struct attribute *a, int n) { struct device *dev = container_of(kobj, struct device, kobj); diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c index eab11615dce..9b382ec2c3b 100644 --- a/drivers/hwmon/ntc_thermistor.c +++ b/drivers/hwmon/ntc_thermistor.c @@ -432,19 +432,7 @@ static struct platform_driver ntc_thermistor_driver = { .id_table = ntc_thermistor_id, }; -static int __init ntc_thermistor_init(void) -{ - return platform_driver_register(&ntc_thermistor_driver); -} - -module_init(ntc_thermistor_init); - -static void __exit ntc_thermistor_cleanup(void) -{ - platform_driver_unregister(&ntc_thermistor_driver); -} - -module_exit(ntc_thermistor_cleanup); +module_platform_driver(ntc_thermistor_driver); MODULE_DESCRIPTION("NTC Thermistor Driver"); MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>"); diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c index 8da2181630b..cb35461d52d 100644 --- a/drivers/hwmon/pc87427.c +++ b/drivers/hwmon/pc87427.c @@ -418,7 +418,7 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute unsigned long val; int iobase = data->address[LD_FAN]; - if (strict_strtoul(buf, 10, &val) < 0) + if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; mutex_lock(&data->lock); @@ -572,7 +572,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute int nr = to_sensor_dev_attr(devattr)->index; unsigned long val; - if (strict_strtoul(buf, 10, &val) < 0 || val > 2) + if (kstrtoul(buf, 10, &val) < 0 || val > 2) return -EINVAL; /* Can't go to automatic mode if it isn't configured */ if (val == 2 && !(data->pwm_auto_ok & (1 << nr))) @@ -604,7 +604,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute int iobase = data->address[LD_FAN]; u8 mode; - if (strict_strtoul(buf, 10, &val) < 0 || val > 0xff) + if (kstrtoul(buf, 10, &val) < 0 || val > 0xff) return -EINVAL; mutex_lock(&data->lock); diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig index 4b26f51920b..cfec923f42b 100644 --- a/drivers/hwmon/pmbus/Kconfig +++ b/drivers/hwmon/pmbus/Kconfig @@ -19,8 +19,8 @@ config SENSORS_PMBUS default y help If you say yes here you get hardware monitoring support for generic - PMBus devices, including but not limited to ADP4000, BMR450, BMR451, - BMR453, BMR454, NCP4200, and NCP4208. + PMBus devices, including but not limited to ADP4000, BMR453, BMR454, + NCP4200, and NCP4208. This driver can also be built as a module. If so, the module will be called pmbus. @@ -113,8 +113,9 @@ config SENSORS_ZL6100 default n help If you say yes here you get hardware monitoring support for Intersil - ZL2004, ZL2006, ZL2008, ZL2105, ZL2106, ZL6100, and ZL6105 Digital - DC/DC Controllers. + ZL2004, ZL2005, ZL2006, ZL2008, ZL2105, ZL2106, ZL6100, and ZL6105 + Digital DC/DC Controllers, as well as for Ericsson BMR450, BMR451, + BMR462, BMR463, and BMR464. This driver can also be built as a module. If so, the module will be called zl6100. diff --git a/drivers/hwmon/pmbus/adm1275.c b/drivers/hwmon/pmbus/adm1275.c index 980a4d9d502..81c7c2ead6f 100644 --- a/drivers/hwmon/pmbus/adm1275.c +++ b/drivers/hwmon/pmbus/adm1275.c @@ -170,35 +170,71 @@ static int adm1275_read_byte_data(struct i2c_client *client, int page, int reg) return ret; } +static const struct i2c_device_id adm1275_id[] = { + { "adm1275", adm1275 }, + { "adm1276", adm1276 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, adm1275_id); + static int adm1275_probe(struct i2c_client *client, const struct i2c_device_id *id) { + u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1]; int config, device_config; int ret; struct pmbus_driver_info *info; struct adm1275_data *data; + const struct i2c_device_id *mid; if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_READ_BYTE_DATA)) + I2C_FUNC_SMBUS_READ_BYTE_DATA + | I2C_FUNC_SMBUS_BLOCK_DATA)) return -ENODEV; - data = kzalloc(sizeof(struct adm1275_data), GFP_KERNEL); - if (!data) - return -ENOMEM; + ret = i2c_smbus_read_block_data(client, PMBUS_MFR_ID, block_buffer); + if (ret < 0) { + dev_err(&client->dev, "Failed to read Manufacturer ID\n"); + return ret; + } + if (ret != 3 || strncmp(block_buffer, "ADI", 3)) { + dev_err(&client->dev, "Unsupported Manufacturer ID\n"); + return -ENODEV; + } - config = i2c_smbus_read_byte_data(client, ADM1275_PMON_CONFIG); - if (config < 0) { - ret = config; - goto err_mem; + ret = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, block_buffer); + if (ret < 0) { + dev_err(&client->dev, "Failed to read Manufacturer Model\n"); + return ret; + } + for (mid = adm1275_id; mid->name[0]; mid++) { + if (!strncasecmp(mid->name, block_buffer, strlen(mid->name))) + break; + } + if (!mid->name[0]) { + dev_err(&client->dev, "Unsupported device\n"); + return -ENODEV; } + if (id->driver_data != mid->driver_data) + dev_notice(&client->dev, + "Device mismatch: Configured %s, detected %s\n", + id->name, mid->name); + + config = i2c_smbus_read_byte_data(client, ADM1275_PMON_CONFIG); + if (config < 0) + return config; + device_config = i2c_smbus_read_byte_data(client, ADM1275_DEVICE_CONFIG); - if (device_config < 0) { - ret = device_config; - goto err_mem; - } + if (device_config < 0) + return device_config; + + data = kzalloc(sizeof(struct adm1275_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->id = mid->driver_data; - data->id = id->driver_data; info = &data->info; info->pages = 1; @@ -233,7 +269,7 @@ static int adm1275_probe(struct i2c_client *client, if (device_config & ADM1275_IOUT_WARN2_SELECT) data->have_oc_fault = true; - switch (id->driver_data) { + switch (data->id) { case adm1275: if (config & ADM1275_VIN_VOUT_SELECT) info->func[0] |= @@ -281,13 +317,6 @@ static int adm1275_remove(struct i2c_client *client) return 0; } -static const struct i2c_device_id adm1275_id[] = { - { "adm1275", adm1275 }, - { "adm1276", adm1276 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, adm1275_id); - static struct i2c_driver adm1275_driver = { .driver = { .name = "adm1275", diff --git a/drivers/hwmon/pmbus/max34440.c b/drivers/hwmon/pmbus/max34440.c index beaf5a8d9c4..9b97a5b3cf3 100644 --- a/drivers/hwmon/pmbus/max34440.c +++ b/drivers/hwmon/pmbus/max34440.c @@ -82,7 +82,7 @@ static int max34440_write_word_data(struct i2c_client *client, int page, case PMBUS_VIRT_RESET_TEMP_HISTORY: ret = pmbus_write_word_data(client, page, MAX34440_MFR_TEMPERATURE_PEAK, - 0xffff); + 0x8000); break; default: ret = -ENODATA; diff --git a/drivers/hwmon/pmbus/pmbus.c b/drivers/hwmon/pmbus/pmbus.c index 995e873197e..18a385e753d 100644 --- a/drivers/hwmon/pmbus/pmbus.c +++ b/drivers/hwmon/pmbus/pmbus.c @@ -200,8 +200,6 @@ static int pmbus_remove(struct i2c_client *client) */ static const struct i2c_device_id pmbus_id[] = { {"adp4000", 1}, - {"bmr450", 1}, - {"bmr451", 1}, {"bmr453", 1}, {"bmr454", 1}, {"ncp4200", 1}, diff --git a/drivers/hwmon/pmbus/zl6100.c b/drivers/hwmon/pmbus/zl6100.c index 2bc980006f8..48c7b4a716a 100644 --- a/drivers/hwmon/pmbus/zl6100.c +++ b/drivers/hwmon/pmbus/zl6100.c @@ -28,7 +28,7 @@ #include <linux/delay.h> #include "pmbus.h" -enum chips { zl2004, zl2006, zl2008, zl2105, zl2106, zl6100, zl6105 }; +enum chips { zl2004, zl2005, zl2006, zl2008, zl2105, zl2106, zl6100, zl6105 }; struct zl6100_data { int id; @@ -38,8 +38,11 @@ struct zl6100_data { #define to_zl6100_data(x) container_of(x, struct zl6100_data, info) +#define ZL6100_MFR_CONFIG 0xd0 #define ZL6100_DEVICE_ID 0xe4 +#define ZL6100_MFR_XTEMP_ENABLE (1 << 7) + #define ZL6100_WAIT_TIME 1000 /* uS */ static ushort delay = ZL6100_WAIT_TIME; @@ -65,6 +68,19 @@ static int zl6100_read_word_data(struct i2c_client *client, int page, int reg) if (page || reg >= PMBUS_VIRT_BASE) return -ENXIO; + if (data->id == zl2005) { + /* + * Limit register detection is not reliable on ZL2005. + * Make sure registers are not erroneously detected. + */ + switch (reg) { + case PMBUS_VOUT_OV_WARN_LIMIT: + case PMBUS_VOUT_UV_WARN_LIMIT: + case PMBUS_IOUT_OC_WARN_LIMIT: + return -ENXIO; + } + } + zl6100_wait(data); ret = pmbus_read_word_data(client, page, reg); data->access = ktime_get(); @@ -122,7 +138,13 @@ static int zl6100_write_byte(struct i2c_client *client, int page, u8 value) } static const struct i2c_device_id zl6100_id[] = { + {"bmr450", zl2005}, + {"bmr451", zl2005}, + {"bmr462", zl2008}, + {"bmr463", zl2008}, + {"bmr464", zl2008}, {"zl2004", zl2004}, + {"zl2005", zl2005}, {"zl2006", zl2006}, {"zl2008", zl2008}, {"zl2105", zl2105}, @@ -143,7 +165,7 @@ static int zl6100_probe(struct i2c_client *client, const struct i2c_device_id *mid; if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_READ_BYTE_DATA + I2C_FUNC_SMBUS_READ_WORD_DATA | I2C_FUNC_SMBUS_READ_BLOCK_DATA)) return -ENODEV; @@ -177,8 +199,9 @@ static int zl6100_probe(struct i2c_client *client, data->id = mid->driver_data; /* - * ZL2008, ZL2105, and ZL6100 are known to require a wait time + * ZL2005, ZL2008, ZL2105, and ZL6100 are known to require a wait time * between I2C accesses. ZL2004 and ZL6105 are known to be safe. + * Other chips have not yet been tested. * * Only clear the wait time for chips known to be safe. The wait time * can be cleared later for additional chips if tests show that it @@ -190,12 +213,9 @@ static int zl6100_probe(struct i2c_client *client, /* * Since there was a direct I2C device access above, wait before * accessing the chip again. - * Set the timestamp, wait, then set it again. This should provide - * enough buffer time to be safe. */ data->access = ktime_get(); zl6100_wait(data); - data->access = ktime_get(); info = &data->info; @@ -203,7 +223,16 @@ static int zl6100_probe(struct i2c_client *client, info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT - | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP; + | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; + + ret = i2c_smbus_read_word_data(client, ZL6100_MFR_CONFIG); + if (ret < 0) + goto err_mem; + if (ret & ZL6100_MFR_XTEMP_ENABLE) + info->func[0] |= PMBUS_HAVE_TEMP2; + + data->access = ktime_get(); + zl6100_wait(data); info->read_word_data = zl6100_read_word_data; info->read_byte_data = zl6100_read_byte_data; diff --git a/drivers/hwmon/s3c-hwmon.c b/drivers/hwmon/s3c-hwmon.c index b39f52e2752..f6c26d19f52 100644 --- a/drivers/hwmon/s3c-hwmon.c +++ b/drivers/hwmon/s3c-hwmon.c @@ -393,18 +393,7 @@ static struct platform_driver s3c_hwmon_driver = { .remove = __devexit_p(s3c_hwmon_remove), }; -static int __init s3c_hwmon_init(void) -{ - return platform_driver_register(&s3c_hwmon_driver); -} - -static void __exit s3c_hwmon_exit(void) -{ - platform_driver_unregister(&s3c_hwmon_driver); -} - -module_init(s3c_hwmon_init); -module_exit(s3c_hwmon_exit); +module_platform_driver(s3c_hwmon_driver); MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); MODULE_DESCRIPTION("S3C ADC HWMon driver"); diff --git a/drivers/hwmon/sch5627.c b/drivers/hwmon/sch5627.c index e3b5c6039c2..79b6dabe316 100644 --- a/drivers/hwmon/sch5627.c +++ b/drivers/hwmon/sch5627.c @@ -590,19 +590,8 @@ static struct platform_driver sch5627_driver = { .remove = sch5627_remove, }; -static int __init sch5627_init(void) -{ - return platform_driver_register(&sch5627_driver); -} - -static void __exit sch5627_exit(void) -{ - platform_driver_unregister(&sch5627_driver); -} +module_platform_driver(sch5627_driver); MODULE_DESCRIPTION("SMSC SCH5627 Hardware Monitoring Driver"); MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); MODULE_LICENSE("GPL"); - -module_init(sch5627_init); -module_exit(sch5627_exit); diff --git a/drivers/hwmon/sch5636.c b/drivers/hwmon/sch5636.c index 244407aa79f..9d5236fb09b 100644 --- a/drivers/hwmon/sch5636.c +++ b/drivers/hwmon/sch5636.c @@ -521,19 +521,8 @@ static struct platform_driver sch5636_driver = { .remove = sch5636_remove, }; -static int __init sch5636_init(void) -{ - return platform_driver_register(&sch5636_driver); -} - -static void __exit sch5636_exit(void) -{ - platform_driver_unregister(&sch5636_driver); -} +module_platform_driver(sch5636_driver); MODULE_DESCRIPTION("SMSC SCH5636 Hardware Monitoring Driver"); MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); MODULE_LICENSE("GPL"); - -module_init(sch5636_init); -module_exit(sch5636_exit); diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index fe4104c6b76..91fdd1fe18b 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c @@ -683,7 +683,7 @@ static ssize_t sht15_store_heater(struct device *dev, long value; u8 status; - if (strict_strtol(buf, 10, &value)) + if (kstrtol(buf, 10, &value)) return -EINVAL; mutex_lock(&data->read_lock); @@ -883,7 +883,7 @@ static int sht15_invalidate_voltage(struct notifier_block *nb, static int __devinit sht15_probe(struct platform_device *pdev) { - int ret = 0; + int ret; struct sht15_data *data = kzalloc(sizeof(*data), GFP_KERNEL); u8 status = 0; @@ -901,6 +901,7 @@ static int __devinit sht15_probe(struct platform_device *pdev) init_waitqueue_head(&data->wait_queue); if (pdev->dev.platform_data == NULL) { + ret = -EINVAL; dev_err(&pdev->dev, "no platform data supplied\n"); goto err_free_data; } diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c index 643aa8c9453..c08eee21d76 100644 --- a/drivers/hwmon/tmp102.c +++ b/drivers/hwmon/tmp102.c @@ -112,7 +112,7 @@ static ssize_t tmp102_set_temp(struct device *dev, long val; int status; - if (strict_strtol(buf, 10, &val) < 0) + if (kstrtol(buf, 10, &val) < 0) return -EINVAL; val = SENSORS_LIMIT(val, -256000, 255000); diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c index ad8d535235c..8b9a77486d5 100644 --- a/drivers/hwmon/tmp401.c +++ b/drivers/hwmon/tmp401.c @@ -334,7 +334,7 @@ static ssize_t store_temp_min(struct device *dev, struct device_attribute long val; u16 reg; - if (strict_strtol(buf, 10, &val)) + if (kstrtol(buf, 10, &val)) return -EINVAL; reg = tmp401_temp_to_register(val, data->config); @@ -361,7 +361,7 @@ static ssize_t store_temp_max(struct device *dev, struct device_attribute long val; u16 reg; - if (strict_strtol(buf, 10, &val)) + if (kstrtol(buf, 10, &val)) return -EINVAL; reg = tmp401_temp_to_register(val, data->config); @@ -388,7 +388,7 @@ static ssize_t store_temp_crit(struct device *dev, struct device_attribute long val; u8 reg; - if (strict_strtol(buf, 10, &val)) + if (kstrtol(buf, 10, &val)) return -EINVAL; reg = tmp401_crit_temp_to_register(val, data->config); @@ -413,7 +413,7 @@ static ssize_t store_temp_crit_hyst(struct device *dev, struct device_attribute long val; u8 reg; - if (strict_strtol(buf, 10, &val)) + if (kstrtol(buf, 10, &val)) return -EINVAL; if (data->config & TMP401_CONFIG_RANGE) @@ -447,7 +447,7 @@ static ssize_t reset_temp_history(struct device *dev, { long val; - if (strict_strtol(buf, 10, &val)) + if (kstrtol(buf, 10, &val)) return -EINVAL; if (val != 1) { diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c index 0517a8f09d3..c48381f2cd0 100644 --- a/drivers/hwmon/tmp421.c +++ b/drivers/hwmon/tmp421.c @@ -157,7 +157,7 @@ static ssize_t show_fault(struct device *dev, return sprintf(buf, "0\n"); } -static mode_t tmp421_is_visible(struct kobject *kobj, struct attribute *a, +static umode_t tmp421_is_visible(struct kobject *kobj, struct attribute *a, int n) { struct device *dev = container_of(kobj, struct device, kobj); diff --git a/drivers/hwmon/twl4030-madc-hwmon.c b/drivers/hwmon/twl4030-madc-hwmon.c index 57240740b16..0018c7dd009 100644 --- a/drivers/hwmon/twl4030-madc-hwmon.c +++ b/drivers/hwmon/twl4030-madc-hwmon.c @@ -136,19 +136,7 @@ static struct platform_driver twl4030_madc_hwmon_driver = { }, }; -static int __init twl4030_madc_hwmon_init(void) -{ - return platform_driver_register(&twl4030_madc_hwmon_driver); -} - -module_init(twl4030_madc_hwmon_init); - -static void __exit twl4030_madc_hwmon_exit(void) -{ - platform_driver_unregister(&twl4030_madc_hwmon_driver); -} - -module_exit(twl4030_madc_hwmon_exit); +module_platform_driver(twl4030_madc_hwmon_driver); MODULE_DESCRIPTION("TWL4030 ADC Hwmon driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/hwmon/ultra45_env.c b/drivers/hwmon/ultra45_env.c index 3cd07bf42dc..b9a87e89bab 100644 --- a/drivers/hwmon/ultra45_env.c +++ b/drivers/hwmon/ultra45_env.c @@ -309,15 +309,4 @@ static struct platform_driver env_driver = { .remove = __devexit_p(env_remove), }; -static int __init env_init(void) -{ - return platform_driver_register(&env_driver); -} - -static void __exit env_exit(void) -{ - platform_driver_unregister(&env_driver); -} - -module_init(env_init); -module_exit(env_exit); +module_platform_driver(env_driver); diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 93f5fc7d605..5276d1933db 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c @@ -937,7 +937,7 @@ store_in_##reg(struct device *dev, struct device_attribute *attr, \ int nr = sensor_attr->index; \ unsigned long val; \ int err; \ - err = strict_strtoul(buf, 10, &val); \ + err = kstrtoul(buf, 10, &val); \ if (err < 0) \ return err; \ mutex_lock(&data->update_lock); \ @@ -1054,7 +1054,7 @@ store_fan_min(struct device *dev, struct device_attribute *attr, unsigned int reg; u8 new_div; - err = strict_strtoul(buf, 10, &val); + err = kstrtoul(buf, 10, &val); if (err < 0) return err; @@ -1199,7 +1199,7 @@ store_##reg(struct device *dev, struct device_attribute *attr, \ int nr = sensor_attr->index; \ int err; \ long val; \ - err = strict_strtol(buf, 10, &val); \ + err = kstrtol(buf, 10, &val); \ if (err < 0) \ return err; \ mutex_lock(&data->update_lock); \ @@ -1319,17 +1319,23 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr, { struct w83627ehf_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + struct w83627ehf_sio_data *sio_data = dev->platform_data; int nr = sensor_attr->index; unsigned long val; int err; u16 reg; - err = strict_strtoul(buf, 10, &val); + err = kstrtoul(buf, 10, &val); if (err < 0) return err; if (val > 1) return -EINVAL; + + /* On NCT67766F, DC mode is only supported for pwm1 */ + if (sio_data->kind == nct6776 && nr && val != 1) + return -EINVAL; + mutex_lock(&data->update_lock); reg = w83627ehf_read_value(data, W83627EHF_REG_PWM_ENABLE[nr]); data->pwm_mode[nr] = val; @@ -1351,7 +1357,7 @@ store_pwm(struct device *dev, struct device_attribute *attr, unsigned long val; int err; - err = strict_strtoul(buf, 10, &val); + err = kstrtoul(buf, 10, &val); if (err < 0) return err; @@ -1376,7 +1382,7 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr, int err; u16 reg; - err = strict_strtoul(buf, 10, &val); + err = kstrtoul(buf, 10, &val); if (err < 0) return err; @@ -1430,7 +1436,7 @@ store_target_temp(struct device *dev, struct device_attribute *attr, long val; int err; - err = strict_strtol(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err < 0) return err; @@ -1455,7 +1461,7 @@ store_tolerance(struct device *dev, struct device_attribute *attr, long val; int err; - err = strict_strtol(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err < 0) return err; @@ -1556,7 +1562,7 @@ store_##reg(struct device *dev, struct device_attribute *attr, \ int nr = sensor_attr->index; \ unsigned long val; \ int err; \ - err = strict_strtoul(buf, 10, &val); \ + err = kstrtoul(buf, 10, &val); \ if (err < 0) \ return err; \ val = SENSORS_LIMIT(val, 1, 255); \ @@ -1595,7 +1601,7 @@ store_##reg(struct device *dev, struct device_attribute *attr, \ int nr = sensor_attr->index; \ unsigned long val; \ int err; \ - err = strict_strtoul(buf, 10, &val); \ + err = kstrtoul(buf, 10, &val); \ if (err < 0) \ return err; \ val = step_time_to_reg(val, data->pwm_mode[nr]); \ @@ -1702,7 +1708,7 @@ clear_caseopen(struct device *dev, struct device_attribute *attr, unsigned long val; u16 reg, mask; - if (strict_strtoul(buf, 10, &val) || val != 0) + if (kstrtoul(buf, 10, &val) || val != 0) return -EINVAL; mask = to_sensor_dev_attr_2(attr)->nr; @@ -1914,9 +1920,26 @@ w83627ehf_check_fan_inputs(const struct w83627ehf_sio_data *sio_data, fan4min = 0; fan5pin = 0; } else if (sio_data->kind == nct6776) { - fan3pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x40); - fan4pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x01); - fan5pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x02); + bool gpok = superio_inb(sio_data->sioreg, 0x27) & 0x80; + + superio_select(sio_data->sioreg, W83627EHF_LD_HWM); + regval = superio_inb(sio_data->sioreg, SIO_REG_ENABLE); + + if (regval & 0x80) + fan3pin = gpok; + else + fan3pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x40); + + if (regval & 0x40) + fan4pin = gpok; + else + fan4pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x01); + + if (regval & 0x20) + fan5pin = gpok; + else + fan5pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x02); + fan4min = fan4pin; } else if (sio_data->kind == w83667hg || sio_data->kind == w83667hg_b) { fan3pin = 1; @@ -2331,11 +2354,6 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) for (i = 0; i < data->pwm_num; i++) data->pwm_enable_orig[i] = data->pwm_enable[i]; - /* Read pwm data to save original values */ - w83627ehf_update_pwm_common(dev, data); - for (i = 0; i < data->pwm_num; i++) - data->pwm_enable_orig[i] = data->pwm_enable[i]; - /* Register sysfs hooks */ for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) { err = device_create_file(dev, &sda_sf3_arrays[i].dev_attr); diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index bde50e34d01..374118f2b9f 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c @@ -71,7 +71,7 @@ module_param(force_i2c, byte, 0); MODULE_PARM_DESC(force_i2c, "Initialize the i2c address of the sensors"); -static int init = 1; +static bool init = 1; module_param(init, bool, 0); MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index 65b685e2c7b..17a8fa2d9ae 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c @@ -67,11 +67,11 @@ module_param_array(force_subclients, short, NULL, 0); MODULE_PARM_DESC(force_subclients, "List of subclient addresses: " "{bus, clientaddr, subclientaddr1, subclientaddr2}"); -static int reset; +static bool reset; module_param(reset, bool, 0); MODULE_PARM_DESC(reset, "Set to one to reset chip on load"); -static int init = 1; +static bool init = 1; module_param(init, bool, 0); MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index 8c2844e5691..35aa5149307 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c @@ -58,11 +58,11 @@ module_param_array(force_subclients, short, NULL, 0); MODULE_PARM_DESC(force_subclients, "List of subclient addresses: " "{bus, clientaddr, subclientaddr1, subclientaddr2}"); -static int reset; +static bool reset; module_param(reset, bool, 0); MODULE_PARM_DESC(reset, "Set to one to force a hardware chip reset"); -static int init; +static bool init; module_param(init, bool, 0); MODULE_PARM_DESC(init, "Set to one to force extra software initialization"); @@ -711,7 +711,7 @@ static ssize_t store_pwm(struct device *dev, struct device_attribute *attr, int nr = sensor_attr->index; unsigned long val; - if (strict_strtoul(buf, 10, &val)) + if (kstrtoul(buf, 10, &val)) return -EINVAL; mutex_lock(&data->update_lock); @@ -756,7 +756,7 @@ static ssize_t store_pwmenable(struct device *dev, u8 val_shift = 0; u8 keep_mask = 0; - int ret = strict_strtoul(buf, 10, &val); + int ret = kstrtoul(buf, 10, &val); if (ret || val < 1 || val > 3) return -EINVAL; @@ -819,7 +819,7 @@ static ssize_t store_temp_target(struct device *dev, unsigned long val; u8 target_mask; - if (strict_strtoul(buf, 10, &val)) + if (kstrtoul(buf, 10, &val)) return -EINVAL; mutex_lock(&data->update_lock); @@ -863,7 +863,7 @@ static ssize_t store_temp_tolerance(struct device *dev, u8 val_shift = 0; u8 keep_mask = 0; - if (strict_strtoul(buf, 10, &val)) + if (kstrtoul(buf, 10, &val)) return -EINVAL; switch (nr) { diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index f3e7130c4cd..d3100eab6b2 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c @@ -56,7 +56,7 @@ module_param_array(force_subclients, short, NULL, 0); MODULE_PARM_DESC(force_subclients, "List of subclient addresses: " "{bus, clientaddr, subclientaddr1, subclientaddr2}"); -static int init; +static bool init; module_param(init, bool, 0); MODULE_PARM_DESC(init, "Set to one to force chip initialization"); @@ -749,7 +749,7 @@ store_chassis_clear(struct device *dev, struct device_attribute *attr, unsigned long val; u8 reg; - if (strict_strtoul(buf, 10, &val) || val != 0) + if (kstrtoul(buf, 10, &val) || val != 0) return -EINVAL; mutex_lock(&data->update_lock); diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index 854f9117f1a..45ec7e7c3c2 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c @@ -61,7 +61,7 @@ module_param_array(force_subclients, short, NULL, 0); MODULE_PARM_DESC(force_subclients, "List of subclient addresses: " "{bus, clientaddr, subclientaddr1, subclientaddr2}"); -static int reset; +static bool reset; module_param(reset, bool, 0); MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended"); @@ -450,7 +450,7 @@ store_chassis_clear(struct device *dev, unsigned long val; u8 reg; - if (strict_strtoul(buf, 10, &val) || val != 0) + if (kstrtoul(buf, 10, &val) || val != 0) return -EINVAL; mutex_lock(&data->update_lock); diff --git a/drivers/hwmon/w83795.c b/drivers/hwmon/w83795.c index 845232d7f61..aa58b25565b 100644 --- a/drivers/hwmon/w83795.c +++ b/drivers/hwmon/w83795.c @@ -42,7 +42,7 @@ static const unsigned short normal_i2c[] = { }; -static int reset; +static bool reset; module_param(reset, bool, 0); MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended"); @@ -730,7 +730,7 @@ store_beep(struct device *dev, struct device_attribute *attr, u8 beep_bit = 1 << shift; unsigned long val; - if (strict_strtoul(buf, 10, &val) < 0) + if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; if (val != 0 && val != 1) return -EINVAL; @@ -755,7 +755,7 @@ store_chassis_clear(struct device *dev, struct w83795_data *data = i2c_get_clientdata(client); unsigned long val; - if (strict_strtoul(buf, 10, &val) < 0 || val != 0) + if (kstrtoul(buf, 10, &val) < 0 || val != 0) return -EINVAL; mutex_lock(&data->update_lock); @@ -801,7 +801,7 @@ store_fan_min(struct device *dev, struct device_attribute *attr, struct w83795_data *data = i2c_get_clientdata(client); unsigned long val; - if (strict_strtoul(buf, 10, &val)) + if (kstrtoul(buf, 10, &val)) return -EINVAL; val = fan_to_reg(val); @@ -863,7 +863,7 @@ store_pwm(struct device *dev, struct device_attribute *attr, int index = sensor_attr->index; unsigned long val; - if (strict_strtoul(buf, 10, &val) < 0) + if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; mutex_lock(&data->update_lock); @@ -924,7 +924,7 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr, unsigned long val; int i; - if (strict_strtoul(buf, 10, &val) < 0) + if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; if (val < 1 || val > 2) return -EINVAL; @@ -1021,7 +1021,7 @@ store_temp_src(struct device *dev, struct device_attribute *attr, unsigned long channel; u8 val = index / 2; - if (strict_strtoul(buf, 10, &channel) < 0 || + if (kstrtoul(buf, 10, &channel) < 0 || channel < 1 || channel > 14) return -EINVAL; @@ -1088,7 +1088,7 @@ store_temp_pwm_enable(struct device *dev, struct device_attribute *attr, int index = sensor_attr->index; unsigned long tmp; - if (strict_strtoul(buf, 10, &tmp) < 0) + if (kstrtoul(buf, 10, &tmp) < 0) return -EINVAL; switch (nr) { @@ -1149,7 +1149,7 @@ store_fanin(struct device *dev, struct device_attribute *attr, int index = sensor_attr->index; unsigned long val; - if (strict_strtoul(buf, 10, &val) < 0) + if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; mutex_lock(&data->update_lock); @@ -1198,7 +1198,7 @@ store_temp_pwm(struct device *dev, struct device_attribute *attr, unsigned long val; u8 tmp; - if (strict_strtoul(buf, 10, &val) < 0) + if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; val /= 1000; @@ -1257,7 +1257,7 @@ store_sf4_pwm(struct device *dev, struct device_attribute *attr, int index = sensor_attr->index; unsigned long val; - if (strict_strtoul(buf, 10, &val) < 0) + if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; mutex_lock(&data->update_lock); @@ -1293,7 +1293,7 @@ store_sf4_temp(struct device *dev, struct device_attribute *attr, int index = sensor_attr->index; unsigned long val; - if (strict_strtoul(buf, 10, &val) < 0) + if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; val /= 1000; @@ -1333,7 +1333,7 @@ store_temp(struct device *dev, struct device_attribute *attr, struct w83795_data *data = i2c_get_clientdata(client); long tmp; - if (strict_strtol(buf, 10, &tmp) < 0) + if (kstrtol(buf, 10, &tmp) < 0) return -EINVAL; mutex_lock(&data->update_lock); @@ -1394,7 +1394,7 @@ store_dts_ext(struct device *dev, struct device_attribute *attr, struct w83795_data *data = i2c_get_clientdata(client); long tmp; - if (strict_strtol(buf, 10, &tmp) < 0) + if (kstrtol(buf, 10, &tmp) < 0) return -EINVAL; mutex_lock(&data->update_lock); @@ -1436,7 +1436,7 @@ store_temp_mode(struct device *dev, struct device_attribute *attr, unsigned long val; u8 tmp; - if (strict_strtoul(buf, 10, &val) < 0) + if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; if ((val != 4) && (val != 3)) return -EINVAL; @@ -1512,7 +1512,7 @@ store_in(struct device *dev, struct device_attribute *attr, u8 tmp; u8 lsb_idx; - if (strict_strtoul(buf, 10, &val) < 0) + if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; val = in_to_reg(index, val); @@ -1569,7 +1569,7 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, struct w83795_data *data = i2c_get_clientdata(client); unsigned long val; - if (strict_strtoul(buf, 10, &val) < 0) + if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; switch (nr) { diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c index 0254e181893..063bd9508d8 100644 --- a/drivers/hwmon/w83l786ng.c +++ b/drivers/hwmon/w83l786ng.c @@ -39,7 +39,7 @@ static const unsigned short normal_i2c[] = { 0x2e, 0x2f, I2C_CLIENT_END }; /* Insmod parameters */ -static int reset; +static bool reset; module_param(reset, bool, 0); MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended"); diff --git a/drivers/hwmon/wm831x-hwmon.c b/drivers/hwmon/wm831x-hwmon.c index 97b1f834a47..9b598ed2602 100644 --- a/drivers/hwmon/wm831x-hwmon.c +++ b/drivers/hwmon/wm831x-hwmon.c @@ -209,17 +209,7 @@ static struct platform_driver wm831x_hwmon_driver = { }, }; -static int __init wm831x_hwmon_init(void) -{ - return platform_driver_register(&wm831x_hwmon_driver); -} -module_init(wm831x_hwmon_init); - -static void __exit wm831x_hwmon_exit(void) -{ - platform_driver_unregister(&wm831x_hwmon_driver); -} -module_exit(wm831x_hwmon_exit); +module_platform_driver(wm831x_hwmon_driver); MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); MODULE_DESCRIPTION("WM831x Hardware Monitoring"); diff --git a/drivers/hwmon/wm8350-hwmon.c b/drivers/hwmon/wm8350-hwmon.c index 13290595ca8..3ff67edbdc4 100644 --- a/drivers/hwmon/wm8350-hwmon.c +++ b/drivers/hwmon/wm8350-hwmon.c @@ -133,17 +133,7 @@ static struct platform_driver wm8350_hwmon_driver = { }, }; -static int __init wm8350_hwmon_init(void) -{ - return platform_driver_register(&wm8350_hwmon_driver); -} -module_init(wm8350_hwmon_init); - -static void __exit wm8350_hwmon_exit(void) -{ - platform_driver_unregister(&wm8350_hwmon_driver); -} -module_exit(wm8350_hwmon_exit); +module_platform_driver(wm8350_hwmon_driver); MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); MODULE_DESCRIPTION("WM8350 Hardware Monitoring"); |