This commit is contained in:
Mark Brown
2026-07-31 13:59:16 +01:00
10 changed files with 164 additions and 90 deletions
+93 -38
View File
@@ -70,8 +70,8 @@ static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END };
#define ADT7470_PWM1_AUTO_MASK 0x80
#define ADT7470_PWM_AUTO_MASK 0xC0
#define ADT7470_REG_PWM34_CFG 0x69
#define ADT7470_PWM3_AUTO_MASK 0x40
#define ADT7470_PWM4_AUTO_MASK 0x80
#define ADT7470_PWM4_AUTO_MASK 0x40
#define ADT7470_PWM3_AUTO_MASK 0x80
#define ADT7470_REG_PWM_MIN_BASE_ADDR 0x6A
#define ADT7470_REG_PWM_MIN_MAX_ADDR 0x6D
#define ADT7470_REG_PWM_TEMP_MIN_BASE_ADDR 0x6E
@@ -110,6 +110,21 @@ static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END };
#define ALARM2(x) ((x) << 8)
/* TEMP1..TEMP7 (ch 0..6) are, respectively BIT(0)..BIT(6) of reg 0x41 and
* 0x72, or BIT(0)..BIT(6) of data->alarm.
* TEMP8..TEMP9 (ch 7..9) are, respectively BIT(0)..BIT(2) of reg 0x42 and
* 0x73, or BIT(8)..BIT(10) of data->alarm.
*/
#define TEMP_ALARM_BIT(ch) ({ \
typeof(ch) _ch = (ch); \
(1 << (_ch < 7 ? _ch : _ch + 1)); \
})
/* FAN1..FAN4 (ch 0..3) are respectively BIT(4)..BIT(7) in
* reg 0x42 and 0x73 or BIT(12)..BIT(15) in data->alarm.
*/
#define FAN_ALARM_BIT(ch) (1 << (12 + (ch)))
#define ADT7470_VENDOR 0x41
#define ADT7470_DEVICE 0x70
/* datasheet only mentions a revision 2 */
@@ -167,6 +182,7 @@ struct adt7470_data {
u8 pwm_min[ADT7470_PWM_COUNT];
s8 pwm_tmin[ADT7470_PWM_COUNT];
u8 pwm_auto_temp[ADT7470_PWM_COUNT];
u32 pwm_freq;
struct task_struct *auto_update;
unsigned int auto_update_interval;
@@ -205,11 +221,12 @@ static inline int adt7470_write_word_data(struct adt7470_data *data, unsigned in
/* Probe for temperature sensors. Assumes lock is held */
static int adt7470_read_temperatures(struct adt7470_data *data)
{
unsigned long res;
unsigned int pwm_cfg[2];
int err;
int i;
struct device *dev = regmap_get_device(data->regmap);
u8 pwm[ADT7470_FAN_COUNT];
unsigned int pwm_cfg[2];
unsigned long res;
int err, err2;
int i;
/* save pwm[1-4] config register */
err = regmap_read(data->regmap, ADT7470_REG_PWM_CFG(0), &pwm_cfg[0]);
@@ -233,19 +250,19 @@ static int adt7470_read_temperatures(struct adt7470_data *data)
err = regmap_update_bits(data->regmap, ADT7470_REG_PWM_CFG(2),
ADT7470_PWM_AUTO_MASK, 0);
if (err < 0)
return err;
goto out_restore;
/* write pwm control to whatever it was */
err = regmap_bulk_write(data->regmap, ADT7470_REG_PWM(0), &pwm[0],
ADT7470_PWM_COUNT);
if (err < 0)
return err;
goto out_restore;
/* start reading temperature sensors */
err = regmap_update_bits(data->regmap, ADT7470_REG_CFG,
ADT7470_T05_STB_MASK, ADT7470_T05_STB_MASK);
if (err < 0)
return err;
goto out_restore;
/* Delay is 200ms * number of temp sensors. */
res = msleep_interruptible((data->num_temp_sensors >= 0 ?
@@ -256,13 +273,30 @@ static int adt7470_read_temperatures(struct adt7470_data *data)
err = regmap_update_bits(data->regmap, ADT7470_REG_CFG,
ADT7470_T05_STB_MASK, 0);
if (err < 0)
return err;
goto out_restore;
out_restore:
/* restore pwm[1-4] config registers */
err = regmap_write(data->regmap, ADT7470_REG_PWM_CFG(0), pwm_cfg[0]);
if (err < 0)
return err;
err = regmap_write(data->regmap, ADT7470_REG_PWM_CFG(2), pwm_cfg[1]);
err2 = regmap_write(data->regmap, ADT7470_REG_PWM_CFG(0), pwm_cfg[0]);
if (err2 < 0) {
dev_warn_ratelimited(dev,
"failed to restore PWM{1,2} config (%d)\n",
err2);
if (!err)
err = err2;
}
err2 = regmap_write(data->regmap, ADT7470_REG_PWM_CFG(2), pwm_cfg[1]);
if (err2 < 0) {
dev_warn_ratelimited(dev,
"failed to restore PWM{3,4} config (%d)\n",
err2);
if (!err)
err = err2;
}
if (err < 0)
return err;
@@ -491,7 +525,7 @@ static ssize_t auto_update_interval_store(struct device *dev,
if (kstrtol(buf, 10, &temp))
return -EINVAL;
temp = clamp_val(temp, 0, 60000);
temp = clamp_val(temp, 500, 60000);
mutex_lock(&data->lock);
data->auto_update_interval = temp;
@@ -551,7 +585,7 @@ static int adt7470_temp_read(struct device *dev, u32 attr, int channel, long *va
*val = 1000 * data->temp_max[channel];
break;
case hwmon_temp_alarm:
*val = !!(data->alarm & channel);
*val = !!(data->alarm & TEMP_ALARM_BIT(channel));
break;
default:
return -EOPNOTSUPP;
@@ -571,14 +605,16 @@ static int adt7470_temp_write(struct device *dev, u32 attr, int channel, long va
switch (attr) {
case hwmon_temp_min:
mutex_lock(&data->lock);
data->temp_min[channel] = val;
err = regmap_write(data->regmap, ADT7470_TEMP_MIN_REG(channel), val);
if (!err)
data->temp_min[channel] = val;
mutex_unlock(&data->lock);
break;
case hwmon_temp_max:
mutex_lock(&data->lock);
data->temp_max[channel] = val;
err = regmap_write(data->regmap, ADT7470_TEMP_MAX_REG(channel), val);
if (!err)
data->temp_max[channel] = val;
mutex_unlock(&data->lock);
break;
default:
@@ -624,36 +660,33 @@ static ssize_t alarm_mask_store(struct device *dev,
static int adt7470_fan_read(struct device *dev, u32 attr, int channel, long *val)
{
struct adt7470_data *data = adt7470_update_device(dev);
u16 fan_data;
if (IS_ERR(data))
return PTR_ERR(data);
switch (attr) {
case hwmon_fan_input:
if (FAN_DATA_VALID(data->fan[channel]))
*val = FAN_PERIOD_TO_RPM(data->fan[channel]);
else
*val = 0;
fan_data = READ_ONCE(data->fan[channel]);
break;
case hwmon_fan_min:
if (FAN_DATA_VALID(data->fan_min[channel]))
*val = FAN_PERIOD_TO_RPM(data->fan_min[channel]);
else
*val = 0;
fan_data = READ_ONCE(data->fan_min[channel]);
break;
case hwmon_fan_max:
if (FAN_DATA_VALID(data->fan_max[channel]))
*val = FAN_PERIOD_TO_RPM(data->fan_max[channel]);
else
*val = 0;
fan_data = READ_ONCE(data->fan_max[channel]);
break;
case hwmon_fan_alarm:
*val = !!(data->alarm & (1 << (12 + channel)));
break;
*val = !!(data->alarm & FAN_ALARM_BIT(channel));
return 0;
default:
return -EOPNOTSUPP;
}
if (FAN_DATA_VALID(fan_data))
*val = FAN_PERIOD_TO_RPM(fan_data);
else
*val = 0;
return 0;
}
@@ -721,7 +754,7 @@ static ssize_t force_pwm_max_store(struct device *dev,
}
/* These are the valid PWM frequencies to the nearest Hz */
static const int adt7470_freq_map[] = {
static const u32 adt7470_freq_map[] = {
11, 15, 22, 29, 35, 44, 59, 88, 1400, 22500
};
@@ -761,7 +794,7 @@ static int adt7470_pwm_read(struct device *dev, u32 attr, int channel, long *val
*val = 1 + data->pwm_automatic[channel];
break;
case hwmon_pwm_freq:
*val = pwm1_freq_get(dev);
*val = data->pwm_freq;
break;
default:
return -EOPNOTSUPP;
@@ -774,12 +807,14 @@ static int pwm1_freq_set(struct device *dev, long freq)
{
struct adt7470_data *data = dev_get_drvdata(dev);
unsigned int low_freq = ADT7470_CFG_LF;
u32 closest_freq;
int index;
int err;
/* Round the user value given to the closest available frequency */
index = find_closest(freq, adt7470_freq_map,
ARRAY_SIZE(adt7470_freq_map));
closest_freq = adt7470_freq_map[index];
if (index >= 8) {
index -= 8;
@@ -797,6 +832,10 @@ static int pwm1_freq_set(struct device *dev, long freq)
err = regmap_update_bits(data->regmap, ADT7470_REG_CFG_2,
ADT7470_FREQ_MASK,
index << ADT7470_FREQ_SHIFT);
if (err < 0)
goto out;
data->pwm_freq = closest_freq;
out:
mutex_unlock(&data->lock);
@@ -813,9 +852,10 @@ static int adt7470_pwm_write(struct device *dev, u32 attr, int channel, long val
case hwmon_pwm_input:
val = clamp_val(val, 0, 255);
mutex_lock(&data->lock);
data->pwm[channel] = val;
err = regmap_write(data->regmap, ADT7470_REG_PWM(channel),
data->pwm[channel]);
val);
if (!err)
data->pwm[channel] = val;
mutex_unlock(&data->lock);
break;
case hwmon_pwm_enable:
@@ -829,10 +869,11 @@ static int adt7470_pwm_write(struct device *dev, u32 attr, int channel, long val
val--;
mutex_lock(&data->lock);
data->pwm_automatic[channel] = val;
err = regmap_update_bits(data->regmap, ADT7470_REG_PWM_CFG(channel),
pwm_auto_reg_mask,
val ? pwm_auto_reg_mask : 0);
if (!err)
data->pwm_automatic[channel] = val;
mutex_unlock(&data->lock);
break;
case hwmon_pwm_freq:
@@ -1008,8 +1049,10 @@ static ssize_t pwm_auto_temp_store(struct device *dev,
if (temp < 0)
return temp;
if (temp > 0xF)
return -EINVAL;
mutex_lock(&data->lock);
data->pwm_automatic[attr->index] = temp;
if (!(attr->index % 2)) {
mask = 0xF0;
@@ -1020,6 +1063,9 @@ static ssize_t pwm_auto_temp_store(struct device *dev,
}
err = regmap_update_bits(data->regmap, pwm_auto_reg, mask, val);
if (!err)
data->pwm_auto_temp[attr->index] = temp;
mutex_unlock(&data->lock);
return err < 0 ? err : count;
@@ -1248,6 +1294,7 @@ static int adt7470_probe(struct i2c_client *client)
struct device *dev = &client->dev;
struct adt7470_data *data;
struct device *hwmon_dev;
int freq_val;
int err;
data = devm_kzalloc(dev, sizeof(struct adt7470_data), GFP_KERNEL);
@@ -1272,6 +1319,14 @@ static int adt7470_probe(struct i2c_client *client)
if (err < 0)
return err;
freq_val = pwm1_freq_get(dev);
if (freq_val <= 0) {
err = freq_val < 0 ? freq_val : -EINVAL;
return err;
}
data->pwm_freq = (u32)freq_val;
/* Register sysfs hooks */
hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, data,
&adt7470_chip_info,
+35 -26
View File
@@ -16,6 +16,7 @@
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/limits.h>
#include <linux/module.h>
#include <linux/property.h>
#include <linux/regmap.h>
@@ -266,30 +267,34 @@ static u16 ina226_interval_to_reg(long interval)
return FIELD_PREP(INA226_AVG_RD_MASK, avg_bits);
}
static int ina2xx_get_value(struct ina2xx_data *data, u8 reg,
unsigned int regval)
static long ina2xx_get_value(struct ina2xx_data *data, u8 reg,
unsigned int regval)
{
int val;
s64 val64;
long val;
switch (reg) {
case INA2XX_SHUNT_VOLTAGE:
/* signed register */
val = (s16)regval >> data->config->shunt_voltage_shift;
val = DIV_ROUND_CLOSEST(val, data->config->shunt_div);
val = DIV_ROUND_CLOSEST((s16)regval >> data->config->shunt_voltage_shift,
data->config->shunt_div);
break;
case INA2XX_BUS_VOLTAGE:
val = (regval >> data->config->bus_voltage_shift) *
data->config->bus_voltage_lsb;
val = DIV_ROUND_CLOSEST(val, 1000);
val = DIV_ROUND_CLOSEST((regval >> data->config->bus_voltage_shift) *
data->config->bus_voltage_lsb, 1000);
break;
case INA2XX_POWER:
val = regval * data->power_lsb_uW;
val = min_t(u64, (u64)regval * data->power_lsb_uW, LONG_MAX);
break;
case INA2XX_CURRENT:
/* signed register, result in mA */
val = ((s16)regval >> data->config->current_shift) *
val64 = (s64)((s16)regval >> data->config->current_shift) *
data->current_lsb_uA;
val = DIV_ROUND_CLOSEST(val, 1000);
if (val64 < 0)
val64 = -DIV_ROUND_CLOSEST_ULL(-val64, 1000);
else
val64 = DIV_ROUND_CLOSEST_ULL(val64, 1000);
val = clamp_val(val64, LONG_MIN, LONG_MAX);
break;
case INA2XX_CALIBRATION:
val = regval;
@@ -378,27 +383,29 @@ static int ina2xx_read_init(struct device *dev, int reg, long *val)
*/
static u16 ina226_alert_to_reg(struct ina2xx_data *data, int reg, long val)
{
long limit;
switch (reg) {
case INA2XX_SHUNT_VOLTAGE:
val = clamp_val(val, 0, SHRT_MAX * data->config->shunt_div);
val *= data->config->shunt_div;
val <<= data->config->shunt_voltage_shift;
return clamp_val(val, 0, SHRT_MAX);
val = min_t(long, val, DIV_ROUND_CLOSEST(SHRT_MAX, data->config->shunt_div));
return min_t(long, (val * data->config->shunt_div) << data->config->shunt_voltage_shift,
SHRT_MAX);
case INA2XX_BUS_VOLTAGE:
val = clamp_val(val, 0, 200000);
val = (val * 1000) << data->config->bus_voltage_shift;
val = DIV_ROUND_CLOSEST(val, data->config->bus_voltage_lsb);
return clamp_val(val, 0, USHRT_MAX);
val = min_t(long, val, 130000);
return min_t(long,
DIV_ROUND_CLOSEST((val * 1000) << data->config->bus_voltage_shift,
data->config->bus_voltage_lsb),
USHRT_MAX);
case INA2XX_POWER:
val = clamp_val(val, 0, UINT_MAX - data->power_lsb_uW);
val = DIV_ROUND_CLOSEST(val, data->power_lsb_uW);
return clamp_val(val, 0, USHRT_MAX);
val = min_t(long, val, LONG_MAX - data->power_lsb_uW);
return min_t(long, DIV_ROUND_CLOSEST(val, data->power_lsb_uW), USHRT_MAX);
case INA2XX_CURRENT:
val = clamp_val(val, INT_MIN / 1000, INT_MAX / 1000);
limit = (LONG_MAX - (data->current_lsb_uA / 2)) / 1000;
val = min_t(long, val, limit);
/* signed register, result in mA */
val = DIV_ROUND_CLOSEST(val * 1000, data->current_lsb_uA);
val <<= data->config->current_shift;
return clamp_val(val, SHRT_MIN, SHRT_MAX);
limit = SHRT_MAX >> data->config->current_shift;
return (u16)(min_t(long, val, limit) << data->config->current_shift);
default:
/* programmer goofed */
WARN_ON_ONCE(1);
@@ -537,6 +544,7 @@ static int sy24655_average_power_read(struct ina2xx_data *data, u8 reg, long *va
u8 template[6];
int ret;
long accumulator_24, sample_count;
u64 val64;
/* 48-bit register read */
ret = i2c_smbus_read_i2c_block_data(data->client, reg, 6, template);
@@ -555,7 +563,8 @@ static int sy24655_average_power_read(struct ina2xx_data *data, u8 reg, long *va
return 0;
}
*val = DIV_ROUND_CLOSEST(accumulator_24, sample_count) * data->power_lsb_uW;
val64 = (u64)DIV_ROUND_CLOSEST(accumulator_24, sample_count) * data->power_lsb_uW;
*val = min_t(u64, val64, LONG_MAX);
return 0;
}
+2 -3
View File
@@ -247,8 +247,7 @@ static struct lm63_data *lm63_update_device(struct device *dev)
LM63_REG_TACH_LIMIT_MSB) << 8);
}
data->pwm1_freq = i2c_smbus_read_byte_data(client,
LM63_REG_PWM_FREQ);
data->pwm1_freq = i2c_smbus_read_byte_data(client, LM63_REG_PWM_FREQ) & 0x1f;
if (data->pwm1_freq == 0)
data->pwm1_freq = 1;
data->pwm1[0] = i2c_smbus_read_byte_data(client,
@@ -1187,7 +1186,7 @@ static void lm63_init_client(struct lm63_data *data)
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);
data->pwm1_freq = i2c_smbus_read_byte_data(client, LM63_REG_PWM_FREQ) & 0x1f;
if (data->pwm1_freq == 0)
data->pwm1_freq = 1;
+2 -2
View File
@@ -1194,7 +1194,7 @@ static int lm90_update_alarms_locked(struct lm90_data *data, bool force)
check_enable = (client->irq || !(data->config_orig & 0x80)) &&
(data->config & 0x80);
if (force || check_enable)
if (data->hwmon_dev && (force || check_enable))
schedule_work(&data->report_work);
/*
@@ -1202,7 +1202,7 @@ static int lm90_update_alarms_locked(struct lm90_data *data, bool force)
* alarms are all clear, and alerts are currently disabled.
* Otherwise (re)schedule worker if needed.
*/
if (check_enable) {
if (check_enable && data->hwmon_dev) {
if (!(data->current_alarms & data->alert_alarms)) {
dev_dbg(&client->dev, "Re-enabling ALERT#\n");
lm90_update_confreg(data, data->config & ~0x80);
+2 -2
View File
@@ -374,8 +374,8 @@ static int ltc4282_read_in(struct ltc4282_state *st, u32 attr, long *val,
channel, val);
case hwmon_in_min_alarm:
if (channel == LTC4282_CHAN_VGPIO)
ltc4282_read_alarm(st, LTC4282_ADC_ALERT_LOG,
LTC4282_GPIO_ALARM_L_MASK, val);
return ltc4282_read_alarm(st, LTC4282_ADC_ALERT_LOG,
LTC4282_GPIO_ALARM_L_MASK, val);
return ltc4282_vdd_source_read_alm(st,
LTC4282_VSOURCE_ALARM_L_MASK,
+9 -11
View File
@@ -791,12 +791,12 @@ static const u16 NCT6106_REG_TOLERANCE_H[] = { 0x112, 0x122, 0x132 };
static const u16 NCT6106_REG_TARGET[] = { 0x111, 0x121, 0x131 };
static const u16 NCT6106_REG_WEIGHT_TEMP_SEL[] = { 0x168, 0x178, 0x188 };
static const u16 NCT6106_REG_WEIGHT_TEMP_STEP[] = { 0x169, 0x179, 0x189 };
static const u16 NCT6106_REG_WEIGHT_TEMP_STEP_TOL[] = { 0x16a, 0x17a, 0x18a };
static const u16 NCT6106_REG_WEIGHT_DUTY_STEP[] = { 0x16b, 0x17b, 0x18b };
static const u16 NCT6106_REG_WEIGHT_TEMP_BASE[] = { 0x16c, 0x17c, 0x18c };
static const u16 NCT6106_REG_WEIGHT_DUTY_BASE[] = { 0x16d, 0x17d, 0x18d };
static const u16 NCT6106_REG_WEIGHT_TEMP_SEL[] = { 0x168, 0x178, 0x188, 0, 0 };
static const u16 NCT6106_REG_WEIGHT_TEMP_STEP[] = { 0x169, 0x179, 0x189, 0, 0 };
static const u16 NCT6106_REG_WEIGHT_TEMP_STEP_TOL[] = { 0x16a, 0x17a, 0x18a, 0, 0 };
static const u16 NCT6106_REG_WEIGHT_DUTY_STEP[] = { 0x16b, 0x17b, 0x18b, 0, 0 };
static const u16 NCT6106_REG_WEIGHT_TEMP_BASE[] = { 0x16c, 0x17c, 0x18c, 0, 0 };
static const u16 NCT6106_REG_WEIGHT_DUTY_BASE[] = { 0x16d, 0x17d, 0x18d, 0, 0 };
static const u16 NCT6106_REG_AUTO_TEMP[] = { 0x160, 0x170, 0x180 };
static const u16 NCT6106_REG_AUTO_PWM[] = { 0x164, 0x174, 0x184 };
@@ -846,8 +846,6 @@ static const u16 NCT6116_FAN_PULSE_SHIFT[] = { 0, 2, 4, 6, 6 };
static const u16 NCT6116_REG_PWM[] = { 0x119, 0x129, 0x139, 0x199, 0x1a9 };
static const u16 NCT6116_REG_FAN_MODE[] = { 0x113, 0x123, 0x133, 0x193, 0x1a3 };
static const u16 NCT6116_REG_TEMP_SEL[] = { 0x110, 0x120, 0x130, 0x190, 0x1a0 };
static const u16 NCT6116_REG_TEMP_SOURCE[] = {
0xb0, 0xb1, 0xb2 };
static const u16 NCT6116_REG_CRITICAL_TEMP[] = {
0x11a, 0x12a, 0x13a, 0x19a, 0x1aa };
@@ -3652,7 +3650,7 @@ int nct6775_probe(struct device *dev, struct nct6775_data *data,
= NCT6106_CRITICAL_PWM_ENABLE_MASK;
data->REG_CRITICAL_PWM = NCT6116_REG_CRITICAL_PWM;
data->REG_TEMP_OFFSET = NCT6106_REG_TEMP_OFFSET;
data->REG_TEMP_SOURCE = NCT6116_REG_TEMP_SOURCE;
data->REG_TEMP_SOURCE = NCT6106_REG_TEMP_SOURCE;
data->REG_TEMP_SEL = NCT6116_REG_TEMP_SEL;
data->REG_WEIGHT_TEMP_SEL = NCT6106_REG_WEIGHT_TEMP_SEL;
data->REG_WEIGHT_TEMP[0] = NCT6106_REG_WEIGHT_TEMP_STEP;
@@ -3666,13 +3664,13 @@ int nct6775_probe(struct device *dev, struct nct6775_data *data,
reg_temp = NCT6106_REG_TEMP;
reg_temp_mon = NCT6106_REG_TEMP_MON;
num_reg_temp = ARRAY_SIZE(NCT6106_REG_TEMP);
num_reg_temp = 3;
num_reg_temp_mon = ARRAY_SIZE(NCT6106_REG_TEMP_MON);
num_reg_tsi_temp = ARRAY_SIZE(NCT6116_REG_TSI_TEMP);
reg_temp_over = NCT6106_REG_TEMP_OVER;
reg_temp_hyst = NCT6106_REG_TEMP_HYST;
reg_temp_config = NCT6106_REG_TEMP_CONFIG;
num_reg_temp_config = ARRAY_SIZE(NCT6106_REG_TEMP_CONFIG);
num_reg_temp_config = 3;
reg_temp_alternate = NCT6106_REG_TEMP_ALTERNATE;
reg_temp_crit = NCT6106_REG_TEMP_CRIT;
reg_temp_crit_l = NCT6106_REG_TEMP_CRIT_L;
+11
View File
@@ -358,6 +358,11 @@ static void npcm7xx_fan_polling(struct timer_list *t)
add_timer(&data->fan_timer);
}
static void npcm7xx_fan_cleanup(void *timer)
{
timer_shutdown_sync(timer);
}
static inline void npcm7xx_fan_compute(struct npcm7xx_pwm_fan_data *data,
u8 fan, u8 cmp, u8 fan_id, u8 flag_int,
u8 flag_mode, u8 flag_clear)
@@ -1020,6 +1025,12 @@ static int npcm7xx_pwm_fan_probe(struct platform_device *pdev)
msecs_to_jiffies(NPCM7XX_FAN_POLL_TIMER_200MS);
timer_setup(&data->fan_timer,
npcm7xx_fan_polling, 0);
ret = devm_add_action_or_reset(dev,
npcm7xx_fan_cleanup,
&data->fan_timer);
if (ret)
return ret;
add_timer(&data->fan_timer);
break;
}
+1 -1
View File
@@ -203,7 +203,7 @@ struct drvdata {
*/
struct mutex mutex;
long update_interval;
u8 output_buffer[OUTPUT_REPORT_SIZE];
u8 output_buffer[OUTPUT_REPORT_SIZE] __aligned(ARCH_DMA_MINALIGN);
};
static long scale_pwm_value(long val, long orig_max, long new_max)
+4 -3
View File
@@ -513,7 +513,7 @@ int pmbus_update_byte_data(struct i2c_client *client, int page, u8 reg,
if (tmp != rv)
rv = _pmbus_write_byte_data(client, page, reg, tmp);
return rv;
return rv < 0 ? rv : 0;
}
EXPORT_SYMBOL_NS_GPL(pmbus_update_byte_data, "PMBUS");
@@ -2985,8 +2985,9 @@ static void pmbus_notify(struct pmbus_data *data, int page, int reg, int flags)
if (reg == sreg && page == spage && (smask & flags)) {
dev_dbg(data->dev, "sysfs notify: %s", da->attr.name);
sysfs_notify(&data->dev->kobj, NULL, da->attr.name);
kobject_uevent(&data->dev->kobj, KOBJ_CHANGE);
sysfs_notify(&data->hwmon_dev->kobj, NULL,
da->attr.name);
kobject_uevent(&data->hwmon_dev->kobj, KOBJ_CHANGE);
flags &= ~smask;
}
+5 -4
View File
@@ -21,6 +21,7 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/unaligned.h>
/* commands (high repeatability mode) */
static const unsigned char sht3x_cmd_measure_single_hpm[] = { 0x24, 0x00 };
@@ -276,9 +277,9 @@ static struct sht3x_data *sht3x_update_client(struct device *dev)
if (ret)
goto out;
val = be16_to_cpup((__be16 *)buf);
val = get_unaligned_be16(buf);
data->temperature = sht3x_extract_temperature(val);
val = be16_to_cpup((__be16 *)(buf + 3));
val = get_unaligned_be16(buf + 3);
data->humidity = sht3x_extract_humidity(val);
data->last_update = jiffies;
}
@@ -336,7 +337,7 @@ static int limits_update(struct sht3x_data *data)
if (ret)
return ret;
raw = be16_to_cpup((__be16 *)buffer);
raw = get_unaligned_be16(buffer);
temperature = sht3x_extract_temperature((raw & 0x01ff) << 7);
humidity = sht3x_extract_humidity(raw & 0xfe00);
data->temperature_limits[index] = temperature;
@@ -389,7 +390,7 @@ static size_t limit_write(struct device *dev,
raw = ((u32)(temperature + 45000) * 24543) >> (16 + 7);
raw |= ((humidity * 42950) >> 16) & 0xfe00;
*((__be16 *)position) = cpu_to_be16(raw);
put_unaligned_be16(raw, position);
position += SHT3X_WORD_LEN;
*position = crc8(sht3x_crc8_table,
position - SHT3X_WORD_LEN,