summaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/w83795.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/w83795.c')
-rw-r--r--drivers/hwmon/w83795.c51
1 files changed, 29 insertions, 22 deletions
diff --git a/drivers/hwmon/w83795.c b/drivers/hwmon/w83795.c
index 6464a52b134b..78a876f35fa3 100644
--- a/drivers/hwmon/w83795.c
+++ b/drivers/hwmon/w83795.c
@@ -372,6 +372,7 @@ struct w83795_data {
char valid;
char valid_limits;
+ char valid_pwm_config;
};
/*
@@ -503,11 +504,17 @@ static void w83795_update_limits(struct i2c_client *client)
data->valid_limits = 1;
}
-static void w83795_update_pwm_config(struct i2c_client *client)
+static struct w83795_data *w83795_update_pwm_config(struct device *dev)
{
+ struct i2c_client *client = to_i2c_client(dev);
struct w83795_data *data = i2c_get_clientdata(client);
int i, tmp;
+ mutex_lock(&data->update_lock);
+
+ if (data->valid_pwm_config)
+ goto END;
+
/* Read temperature source selection */
for (i = 0; i < ARRAY_SIZE(data->temp_src); i++)
data->temp_src[i] = w83795_read(client, W83795_REG_TSS(i));
@@ -556,6 +563,12 @@ static void w83795_update_pwm_config(struct i2c_client *client)
for (i = 0; i < ARRAY_SIZE(data->setup_pwm); i++)
data->setup_pwm[i] =
w83795_read(client, W83795_REG_SETUP_PWM(i));
+
+ data->valid_pwm_config = 1;
+
+END:
+ mutex_unlock(&data->update_lock);
+ return data;
}
static struct w83795_data *w83795_update_device(struct device *dev)
@@ -775,13 +788,16 @@ store_fan_min(struct device *dev, struct device_attribute *attr,
static ssize_t
show_pwm(struct device *dev, struct device_attribute *attr, char *buf)
{
- struct w83795_data *data = w83795_update_device(dev);
+ struct w83795_data *data;
struct sensor_device_attribute_2 *sensor_attr =
to_sensor_dev_attr_2(attr);
int nr = sensor_attr->nr;
int index = sensor_attr->index;
unsigned int val;
+ data = nr == PWM_OUTPUT ? w83795_update_device(dev)
+ : w83795_update_pwm_config(dev);
+
switch (nr) {
case PWM_STOP_TIME:
val = time_from_reg(data->pwm[index][nr]);
@@ -835,8 +851,7 @@ show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf)
{
struct sensor_device_attribute_2 *sensor_attr =
to_sensor_dev_attr_2(attr);
- struct i2c_client *client = to_i2c_client(dev);
- struct w83795_data *data = i2c_get_clientdata(client);
+ struct w83795_data *data = w83795_update_pwm_config(dev);
int index = sensor_attr->index;
u8 tmp;
@@ -864,7 +879,7 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
- struct w83795_data *data = i2c_get_clientdata(client);
+ struct w83795_data *data = w83795_update_pwm_config(dev);
struct sensor_device_attribute_2 *sensor_attr =
to_sensor_dev_attr_2(attr);
int index = sensor_attr->index;
@@ -905,8 +920,7 @@ show_temp_src(struct device *dev, struct device_attribute *attr, char *buf)
{
struct sensor_device_attribute_2 *sensor_attr =
to_sensor_dev_attr_2(attr);
- struct i2c_client *client = to_i2c_client(dev);
- struct w83795_data *data = i2c_get_clientdata(client);
+ struct w83795_data *data = w83795_update_pwm_config(dev);
int index = sensor_attr->index;
u8 val = index / 2;
u8 tmp = data->temp_src[val];
@@ -926,7 +940,7 @@ store_temp_src(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
- struct w83795_data *data = i2c_get_clientdata(client);
+ struct w83795_data *data = w83795_update_pwm_config(dev);
struct sensor_device_attribute_2 *sensor_attr =
to_sensor_dev_attr_2(attr);
int index = sensor_attr->index;
@@ -957,8 +971,7 @@ static ssize_t
show_temp_pwm_enable(struct device *dev, struct device_attribute *attr,
char *buf)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct w83795_data *data = i2c_get_clientdata(client);
+ struct w83795_data *data = w83795_update_pwm_config(dev);
struct sensor_device_attribute_2 *sensor_attr =
to_sensor_dev_attr_2(attr);
int nr = sensor_attr->nr;
@@ -986,7 +999,7 @@ store_temp_pwm_enable(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
- struct w83795_data *data = i2c_get_clientdata(client);
+ struct w83795_data *data = w83795_update_pwm_config(dev);
struct sensor_device_attribute_2 *sensor_attr =
to_sensor_dev_attr_2(attr);
int nr = sensor_attr->nr;
@@ -1023,8 +1036,7 @@ store_temp_pwm_enable(struct device *dev, struct device_attribute *attr,
static ssize_t
show_fanin(struct device *dev, struct device_attribute *attr, char *buf)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct w83795_data *data = i2c_get_clientdata(client);
+ struct w83795_data *data = w83795_update_pwm_config(dev);
struct sensor_device_attribute_2 *sensor_attr =
to_sensor_dev_attr_2(attr);
int nr = sensor_attr->nr;
@@ -1081,8 +1093,7 @@ store_fanin(struct device *dev, struct device_attribute *attr,
static ssize_t
show_temp_pwm(struct device *dev, struct device_attribute *attr, char *buf)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct w83795_data *data = i2c_get_clientdata(client);
+ struct w83795_data *data = w83795_update_pwm_config(dev);
struct sensor_device_attribute_2 *sensor_attr =
to_sensor_dev_attr_2(attr);
int nr = sensor_attr->nr;
@@ -1143,8 +1154,7 @@ store_temp_pwm(struct device *dev, struct device_attribute *attr,
static ssize_t
show_sf4_pwm(struct device *dev, struct device_attribute *attr, char *buf)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct w83795_data *data = i2c_get_clientdata(client);
+ struct w83795_data *data = w83795_update_pwm_config(dev);
struct sensor_device_attribute_2 *sensor_attr =
to_sensor_dev_attr_2(attr);
int nr = sensor_attr->nr;
@@ -1179,8 +1189,7 @@ store_sf4_pwm(struct device *dev, struct device_attribute *attr,
static ssize_t
show_sf4_temp(struct device *dev, struct device_attribute *attr, char *buf)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct w83795_data *data = i2c_get_clientdata(client);
+ struct w83795_data *data = w83795_update_pwm_config(dev);
struct sensor_device_attribute_2 *sensor_attr =
to_sensor_dev_attr_2(attr);
int nr = sensor_attr->nr;
@@ -1456,8 +1465,7 @@ show_sf_setup(struct device *dev, struct device_attribute *attr, char *buf)
struct sensor_device_attribute_2 *sensor_attr =
to_sensor_dev_attr_2(attr);
int nr = sensor_attr->nr;
- struct i2c_client *client = to_i2c_client(dev);
- struct w83795_data *data = i2c_get_clientdata(client);
+ struct w83795_data *data = w83795_update_pwm_config(dev);
u16 val = data->setup_pwm[nr];
switch (nr) {
@@ -2029,7 +2037,6 @@ static int w83795_probe(struct i2c_client *client,
data->has_pwm = 8;
else
data->has_pwm = 2;
- w83795_update_pwm_config(client);
err = w83795_handle_files(dev, device_create_file);
if (err)
OpenPOWER on IntegriCloud