[PATCH] w83627ehf: Refactor the sysfs interface
Use dynamic sysfs callbacks and array of attributes to reduce the w83627ehf driver size. Signed-off-by: Jean Delvare <khali@linux-fr.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Родитель
4c537fb287
Коммит
412fec8216
|
@ -42,6 +42,7 @@
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/i2c-isa.h>
|
#include <linux/i2c-isa.h>
|
||||||
#include <linux/hwmon.h>
|
#include <linux/hwmon.h>
|
||||||
|
#include <linux/hwmon-sysfs.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
@ -408,9 +409,12 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
|
||||||
|
|
||||||
#define show_fan_reg(reg) \
|
#define show_fan_reg(reg) \
|
||||||
static ssize_t \
|
static ssize_t \
|
||||||
show_##reg(struct device *dev, char *buf, int nr) \
|
show_##reg(struct device *dev, struct device_attribute *attr, \
|
||||||
|
char *buf) \
|
||||||
{ \
|
{ \
|
||||||
struct w83627ehf_data *data = w83627ehf_update_device(dev); \
|
struct w83627ehf_data *data = w83627ehf_update_device(dev); \
|
||||||
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
|
||||||
|
int nr = sensor_attr->index; \
|
||||||
return sprintf(buf, "%d\n", \
|
return sprintf(buf, "%d\n", \
|
||||||
fan_from_reg(data->reg[nr], \
|
fan_from_reg(data->reg[nr], \
|
||||||
div_from_reg(data->fan_div[nr]))); \
|
div_from_reg(data->fan_div[nr]))); \
|
||||||
|
@ -419,18 +423,23 @@ show_fan_reg(fan);
|
||||||
show_fan_reg(fan_min);
|
show_fan_reg(fan_min);
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
show_fan_div(struct device *dev, char *buf, int nr)
|
show_fan_div(struct device *dev, struct device_attribute *attr,
|
||||||
|
char *buf)
|
||||||
{
|
{
|
||||||
struct w83627ehf_data *data = w83627ehf_update_device(dev);
|
struct w83627ehf_data *data = w83627ehf_update_device(dev);
|
||||||
return sprintf(buf, "%u\n",
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
||||||
div_from_reg(data->fan_div[nr]));
|
int nr = sensor_attr->index;
|
||||||
|
return sprintf(buf, "%u\n", div_from_reg(data->fan_div[nr]));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
store_fan_min(struct device *dev, const char *buf, size_t count, int nr)
|
store_fan_min(struct device *dev, struct device_attribute *attr,
|
||||||
|
const char *buf, size_t count)
|
||||||
{
|
{
|
||||||
struct i2c_client *client = to_i2c_client(dev);
|
struct i2c_client *client = to_i2c_client(dev);
|
||||||
struct w83627ehf_data *data = i2c_get_clientdata(client);
|
struct w83627ehf_data *data = i2c_get_clientdata(client);
|
||||||
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
||||||
|
int nr = sensor_attr->index;
|
||||||
unsigned int val = simple_strtoul(buf, NULL, 10);
|
unsigned int val = simple_strtoul(buf, NULL, 10);
|
||||||
unsigned int reg;
|
unsigned int reg;
|
||||||
u8 new_div;
|
u8 new_div;
|
||||||
|
@ -488,58 +497,41 @@ store_fan_min(struct device *dev, const char *buf, size_t count, int nr)
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define sysfs_fan_offset(offset) \
|
static struct sensor_device_attribute sda_fan_input[] = {
|
||||||
static ssize_t \
|
SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0),
|
||||||
show_reg_fan_##offset(struct device *dev, struct device_attribute *attr, \
|
SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1),
|
||||||
char *buf) \
|
SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2),
|
||||||
{ \
|
SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3),
|
||||||
return show_fan(dev, buf, offset-1); \
|
SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4),
|
||||||
} \
|
};
|
||||||
static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
|
|
||||||
show_reg_fan_##offset, NULL);
|
|
||||||
|
|
||||||
#define sysfs_fan_min_offset(offset) \
|
static struct sensor_device_attribute sda_fan_min[] = {
|
||||||
static ssize_t \
|
SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min,
|
||||||
show_reg_fan##offset##_min(struct device *dev, struct device_attribute *attr, \
|
store_fan_min, 0),
|
||||||
char *buf) \
|
SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min,
|
||||||
{ \
|
store_fan_min, 1),
|
||||||
return show_fan_min(dev, buf, offset-1); \
|
SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min,
|
||||||
} \
|
store_fan_min, 2),
|
||||||
static ssize_t \
|
SENSOR_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min,
|
||||||
store_reg_fan##offset##_min(struct device *dev, struct device_attribute *attr, \
|
store_fan_min, 3),
|
||||||
const char *buf, size_t count) \
|
SENSOR_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min,
|
||||||
{ \
|
store_fan_min, 4),
|
||||||
return store_fan_min(dev, buf, count, offset-1); \
|
};
|
||||||
} \
|
|
||||||
static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
|
|
||||||
show_reg_fan##offset##_min, \
|
|
||||||
store_reg_fan##offset##_min);
|
|
||||||
|
|
||||||
#define sysfs_fan_div_offset(offset) \
|
static struct sensor_device_attribute sda_fan_div[] = {
|
||||||
static ssize_t \
|
SENSOR_ATTR(fan1_div, S_IRUGO, show_fan_div, NULL, 0),
|
||||||
show_reg_fan##offset##_div(struct device *dev, struct device_attribute *attr, \
|
SENSOR_ATTR(fan2_div, S_IRUGO, show_fan_div, NULL, 1),
|
||||||
char *buf) \
|
SENSOR_ATTR(fan3_div, S_IRUGO, show_fan_div, NULL, 2),
|
||||||
{ \
|
SENSOR_ATTR(fan4_div, S_IRUGO, show_fan_div, NULL, 3),
|
||||||
return show_fan_div(dev, buf, offset - 1); \
|
SENSOR_ATTR(fan5_div, S_IRUGO, show_fan_div, NULL, 4),
|
||||||
} \
|
};
|
||||||
static DEVICE_ATTR(fan##offset##_div, S_IRUGO, \
|
|
||||||
show_reg_fan##offset##_div, NULL);
|
|
||||||
|
|
||||||
sysfs_fan_offset(1);
|
static void device_create_file_fan(struct device *dev, int i)
|
||||||
sysfs_fan_min_offset(1);
|
{
|
||||||
sysfs_fan_div_offset(1);
|
device_create_file(dev, &sda_fan_input[i].dev_attr);
|
||||||
sysfs_fan_offset(2);
|
device_create_file(dev, &sda_fan_div[i].dev_attr);
|
||||||
sysfs_fan_min_offset(2);
|
device_create_file(dev, &sda_fan_min[i].dev_attr);
|
||||||
sysfs_fan_div_offset(2);
|
}
|
||||||
sysfs_fan_offset(3);
|
|
||||||
sysfs_fan_min_offset(3);
|
|
||||||
sysfs_fan_div_offset(3);
|
|
||||||
sysfs_fan_offset(4);
|
|
||||||
sysfs_fan_min_offset(4);
|
|
||||||
sysfs_fan_div_offset(4);
|
|
||||||
sysfs_fan_offset(5);
|
|
||||||
sysfs_fan_min_offset(5);
|
|
||||||
sysfs_fan_div_offset(5);
|
|
||||||
|
|
||||||
#define show_temp1_reg(reg) \
|
#define show_temp1_reg(reg) \
|
||||||
static ssize_t \
|
static ssize_t \
|
||||||
|
@ -572,17 +564,14 @@ store_temp1_##reg(struct device *dev, struct device_attribute *attr, \
|
||||||
store_temp1_reg(OVER, max);
|
store_temp1_reg(OVER, max);
|
||||||
store_temp1_reg(HYST, max_hyst);
|
store_temp1_reg(HYST, max_hyst);
|
||||||
|
|
||||||
static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1, NULL);
|
|
||||||
static DEVICE_ATTR(temp1_max, S_IRUGO| S_IWUSR,
|
|
||||||
show_temp1_max, store_temp1_max);
|
|
||||||
static DEVICE_ATTR(temp1_max_hyst, S_IRUGO| S_IWUSR,
|
|
||||||
show_temp1_max_hyst, store_temp1_max_hyst);
|
|
||||||
|
|
||||||
#define show_temp_reg(reg) \
|
#define show_temp_reg(reg) \
|
||||||
static ssize_t \
|
static ssize_t \
|
||||||
show_##reg (struct device *dev, char *buf, int nr) \
|
show_##reg(struct device *dev, struct device_attribute *attr, \
|
||||||
|
char *buf) \
|
||||||
{ \
|
{ \
|
||||||
struct w83627ehf_data *data = w83627ehf_update_device(dev); \
|
struct w83627ehf_data *data = w83627ehf_update_device(dev); \
|
||||||
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
|
||||||
|
int nr = sensor_attr->index; \
|
||||||
return sprintf(buf, "%d\n", \
|
return sprintf(buf, "%d\n", \
|
||||||
LM75_TEMP_FROM_REG(data->reg[nr])); \
|
LM75_TEMP_FROM_REG(data->reg[nr])); \
|
||||||
}
|
}
|
||||||
|
@ -592,10 +581,13 @@ show_temp_reg(temp_max_hyst);
|
||||||
|
|
||||||
#define store_temp_reg(REG, reg) \
|
#define store_temp_reg(REG, reg) \
|
||||||
static ssize_t \
|
static ssize_t \
|
||||||
store_##reg (struct device *dev, const char *buf, size_t count, int nr) \
|
store_##reg(struct device *dev, struct device_attribute *attr, \
|
||||||
|
const char *buf, size_t count) \
|
||||||
{ \
|
{ \
|
||||||
struct i2c_client *client = to_i2c_client(dev); \
|
struct i2c_client *client = to_i2c_client(dev); \
|
||||||
struct w83627ehf_data *data = i2c_get_clientdata(client); \
|
struct w83627ehf_data *data = i2c_get_clientdata(client); \
|
||||||
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
|
||||||
|
int nr = sensor_attr->index; \
|
||||||
u32 val = simple_strtoul(buf, NULL, 10); \
|
u32 val = simple_strtoul(buf, NULL, 10); \
|
||||||
\
|
\
|
||||||
mutex_lock(&data->update_lock); \
|
mutex_lock(&data->update_lock); \
|
||||||
|
@ -608,39 +600,23 @@ store_##reg (struct device *dev, const char *buf, size_t count, int nr) \
|
||||||
store_temp_reg(OVER, temp_max);
|
store_temp_reg(OVER, temp_max);
|
||||||
store_temp_reg(HYST, temp_max_hyst);
|
store_temp_reg(HYST, temp_max_hyst);
|
||||||
|
|
||||||
#define sysfs_temp_offset(offset) \
|
static struct sensor_device_attribute sda_temp[] = {
|
||||||
static ssize_t \
|
SENSOR_ATTR(temp1_input, S_IRUGO, show_temp1, NULL, 0),
|
||||||
show_reg_temp##offset (struct device *dev, struct device_attribute *attr, \
|
SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 0),
|
||||||
char *buf) \
|
SENSOR_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 1),
|
||||||
{ \
|
SENSOR_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp1_max,
|
||||||
return show_temp(dev, buf, offset - 2); \
|
store_temp1_max, 0),
|
||||||
} \
|
SENSOR_ATTR(temp2_max, S_IRUGO | S_IWUSR, show_temp_max,
|
||||||
static DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
|
store_temp_max, 0),
|
||||||
show_reg_temp##offset, NULL);
|
SENSOR_ATTR(temp3_max, S_IRUGO | S_IWUSR, show_temp_max,
|
||||||
|
store_temp_max, 1),
|
||||||
#define sysfs_temp_reg_offset(reg, offset) \
|
SENSOR_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp1_max_hyst,
|
||||||
static ssize_t \
|
store_temp1_max_hyst, 0),
|
||||||
show_reg_temp##offset##_##reg(struct device *dev, struct device_attribute *attr, \
|
SENSOR_ATTR(temp2_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
|
||||||
char *buf) \
|
store_temp_max_hyst, 0),
|
||||||
{ \
|
SENSOR_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
|
||||||
return show_temp_##reg(dev, buf, offset - 2); \
|
store_temp_max_hyst, 1),
|
||||||
} \
|
};
|
||||||
static ssize_t \
|
|
||||||
store_reg_temp##offset##_##reg(struct device *dev, struct device_attribute *attr, \
|
|
||||||
const char *buf, size_t count) \
|
|
||||||
{ \
|
|
||||||
return store_temp_##reg(dev, buf, count, offset - 2); \
|
|
||||||
} \
|
|
||||||
static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, \
|
|
||||||
show_reg_temp##offset##_##reg, \
|
|
||||||
store_reg_temp##offset##_##reg);
|
|
||||||
|
|
||||||
sysfs_temp_offset(2);
|
|
||||||
sysfs_temp_reg_offset(max, 2);
|
|
||||||
sysfs_temp_reg_offset(max_hyst, 2);
|
|
||||||
sysfs_temp_offset(3);
|
|
||||||
sysfs_temp_reg_offset(max, 3);
|
|
||||||
sysfs_temp_reg_offset(max_hyst, 3);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Driver and client management
|
* Driver and client management
|
||||||
|
@ -674,6 +650,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter)
|
||||||
{
|
{
|
||||||
struct i2c_client *client;
|
struct i2c_client *client;
|
||||||
struct w83627ehf_data *data;
|
struct w83627ehf_data *data;
|
||||||
|
struct device *dev;
|
||||||
int i, err = 0;
|
int i, err = 0;
|
||||||
|
|
||||||
if (!request_region(address + REGION_OFFSET, REGION_LENGTH,
|
if (!request_region(address + REGION_OFFSET, REGION_LENGTH,
|
||||||
|
@ -694,6 +671,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter)
|
||||||
client->adapter = adapter;
|
client->adapter = adapter;
|
||||||
client->driver = &w83627ehf_driver;
|
client->driver = &w83627ehf_driver;
|
||||||
client->flags = 0;
|
client->flags = 0;
|
||||||
|
dev = &client->dev;
|
||||||
|
|
||||||
strlcpy(client->name, "w83627ehf", I2C_NAME_SIZE);
|
strlcpy(client->name, "w83627ehf", I2C_NAME_SIZE);
|
||||||
data->valid = 0;
|
data->valid = 0;
|
||||||
|
@ -721,42 +699,18 @@ static int w83627ehf_detect(struct i2c_adapter *adapter)
|
||||||
data->has_fan |= (1 << 4);
|
data->has_fan |= (1 << 4);
|
||||||
|
|
||||||
/* Register sysfs hooks */
|
/* Register sysfs hooks */
|
||||||
data->class_dev = hwmon_device_register(&client->dev);
|
data->class_dev = hwmon_device_register(dev);
|
||||||
if (IS_ERR(data->class_dev)) {
|
if (IS_ERR(data->class_dev)) {
|
||||||
err = PTR_ERR(data->class_dev);
|
err = PTR_ERR(data->class_dev);
|
||||||
goto exit_detach;
|
goto exit_detach;
|
||||||
}
|
}
|
||||||
|
|
||||||
device_create_file(&client->dev, &dev_attr_fan1_input);
|
for (i = 0; i < 5; i++) {
|
||||||
device_create_file(&client->dev, &dev_attr_fan1_min);
|
if (data->has_fan & (1 << i))
|
||||||
device_create_file(&client->dev, &dev_attr_fan1_div);
|
device_create_file_fan(dev, i);
|
||||||
device_create_file(&client->dev, &dev_attr_fan2_input);
|
|
||||||
device_create_file(&client->dev, &dev_attr_fan2_min);
|
|
||||||
device_create_file(&client->dev, &dev_attr_fan2_div);
|
|
||||||
device_create_file(&client->dev, &dev_attr_fan3_input);
|
|
||||||
device_create_file(&client->dev, &dev_attr_fan3_min);
|
|
||||||
device_create_file(&client->dev, &dev_attr_fan3_div);
|
|
||||||
|
|
||||||
if (data->has_fan & (1 << 3)) {
|
|
||||||
device_create_file(&client->dev, &dev_attr_fan4_input);
|
|
||||||
device_create_file(&client->dev, &dev_attr_fan4_min);
|
|
||||||
device_create_file(&client->dev, &dev_attr_fan4_div);
|
|
||||||
}
|
}
|
||||||
if (data->has_fan & (1 << 4)) {
|
for (i = 0; i < ARRAY_SIZE(sda_temp); i++)
|
||||||
device_create_file(&client->dev, &dev_attr_fan5_input);
|
device_create_file(dev, &sda_temp[i].dev_attr);
|
||||||
device_create_file(&client->dev, &dev_attr_fan5_min);
|
|
||||||
device_create_file(&client->dev, &dev_attr_fan5_div);
|
|
||||||
}
|
|
||||||
|
|
||||||
device_create_file(&client->dev, &dev_attr_temp1_input);
|
|
||||||
device_create_file(&client->dev, &dev_attr_temp1_max);
|
|
||||||
device_create_file(&client->dev, &dev_attr_temp1_max_hyst);
|
|
||||||
device_create_file(&client->dev, &dev_attr_temp2_input);
|
|
||||||
device_create_file(&client->dev, &dev_attr_temp2_max);
|
|
||||||
device_create_file(&client->dev, &dev_attr_temp2_max_hyst);
|
|
||||||
device_create_file(&client->dev, &dev_attr_temp3_input);
|
|
||||||
device_create_file(&client->dev, &dev_attr_temp3_max);
|
|
||||||
device_create_file(&client->dev, &dev_attr_temp3_max_hyst);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче