aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeelesh Gupta <neelegup@linux.vnet.ibm.com>2014-03-03 14:39:45 +1100
committerEli Qiao <taget@linux.vnet.ibm.com>2014-03-04 11:53:58 +0800
commit524bdfd2ddb5fea50ae97386baa505b52d36b80e (patch)
tree82545e824600225a06287312c9dc725b5a05655f
parent81896beeb0f634303ddf403741a7811c98f5b000 (diff)
downloadpowerkvm-524bdfd2ddb5fea50ae97386baa505b52d36b80e.tar.gz
hwsensors/ibmpowernv: Cleanup and fix up sysfs file duplication
Cleaning up the code, removing not necessary enumeration, clubbing the fragmented data structure and some conditional checks in node traversal in __init code. This also fixes a bug of sysfs file duplication. Signed-off-by: Neelesh Gupta <neelegup@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--drivers/hwmon/ibmpowernv.c163
1 files changed, 76 insertions, 87 deletions
diff --git a/drivers/hwmon/ibmpowernv.c b/drivers/hwmon/ibmpowernv.c
index 6a08c4717f6a5f..b7b1297a9b02c5 100644
--- a/drivers/hwmon/ibmpowernv.c
+++ b/drivers/hwmon/ibmpowernv.c
@@ -33,13 +33,7 @@
MODULE_DESCRIPTION("IBM PowerNV Platform power/temp/fan sensor hwmon module");
MODULE_LICENSE("GPL");
-#define SENSOR_NAME_LENGTH 50
-
-/* Creating different platform devices for different device types. So, using
- * different device ids.
- */
-
-#define MAX_STRING_LENGTH 100
+#define MAX_ATTR_LENGTH 32
/* Device tree sensor name prefixes. The device tree has the names in the
* format "cooling-fan#2-faulted" where the "cooling-fan" is the sensor type,
@@ -50,28 +44,11 @@ MODULE_LICENSE("GPL");
#define DT_THRESHOLD_ATTR_SUFFIX "thrs"
enum sensors {
- UNKNOWN = -1,
FAN,
TEMPERATURE,
POWERSUPPLY,
POWER,
- MAX_SENSOR_TYPES
-};
-
-static const char * const sensor_name_table[] = {
- "fan-sensor",
- "amb-temp-sensor",
- "power-sensor",
- "power",
- NULL
-};
-
-static const char * const dt_sensor_comp_types[] = {
- "ibm,opal-sensor-cooling-fan",
- "ibm,opal-sensor-amb-temp",
- "ibm,opal-sensor-power-supply",
- "ibm,opal-sensor-power",
- NULL
+ MAX_SENSOR_TYPE,
};
enum attributes {
@@ -82,6 +59,16 @@ enum attributes {
MAX_ATTR_TYPES
};
+static struct sensor_name {
+ char *name;
+ char *compaible;
+} sensor_names[] = {
+ {"fan-sensor", "ibm,opal-sensor-cooling-fan"},
+ {"amb-temp-sensor", "ibm,opal-sensor-amb-temp"},
+ {"power-sensor", "ibm,opal-sensor-power-supply"},
+ {"power", "ibm,opal-sensor-power"}
+};
+
static const char * const attribute_type_table[] = {
"input",
"min",
@@ -112,10 +99,10 @@ static LIST_HEAD(pdev_list);
*/
struct sensor_specific_data {
u32 sensor_id; /* The hex value as in the device tree */
- int sensor_index; /* The sensor instance index */
+ u32 sensor_index; /* The sensor instance index */
struct sensor_device_attribute sd_attr;
enum attributes attr_type;
- char attr_name[SENSOR_NAME_LENGTH];
+ char attr_name[64];
};
struct sensor_data {
@@ -166,11 +153,11 @@ static ssize_t show_name(struct device *dev,
static ssize_t show_sensor(struct device *dev,
struct device_attribute *devattr, char *buf)
{
- struct platform_device *pdev = to_platform_device(dev);
- enum sensors sensor_type = pdev->id;
struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(devattr);
+ struct platform_device *pdev = to_platform_device(dev);
struct sensor_data *pdata = platform_get_drvdata(pdev);
struct sensor_specific_data *tdata = NULL;
+ enum sensors sensor_type = pdev->id;
u32 x = -1;
int ret;
@@ -181,7 +168,7 @@ static ssize_t show_sensor(struct device *dev,
for (i = 0; i < MAX_ATTR_TYPES; i++) {
if (strcmp(pos+1, attribute_type_table[i]) == 0) {
tdata = powernv_sensor_get_sensor_data(pdata,
- sd_attr->index, i);
+ sd_attr->index, i);
break;
}
}
@@ -206,17 +193,18 @@ static ssize_t show_sensor(struct device *dev,
return sprintf(buf, "%d\n", x);
}
-static int get_sensor_index_from_name(const char *name)
+static u32 get_sensor_index_from_name(const char *name)
{
- int index = 0;
- int copy_length;
- char newbuf[MAX_STRING_LENGTH];
char *hash_position = strchr(name, '#');
+ u32 index = 0, copy_length;
+ char newbuf[8];
if (hash_position) {
- copy_length = strchr(hash_position, '-')-hash_position-1;
- strncpy(newbuf, hash_position+1, copy_length);
- sscanf(newbuf, "%d", &index);
+ copy_length = strchr(hash_position, '-') - hash_position - 1;
+ if (copy_length < sizeof(newbuf)) {
+ strncpy(newbuf, hash_position + 1, copy_length);
+ sscanf(newbuf, "%d", &index);
+ }
}
return index;
@@ -226,26 +214,25 @@ static inline void get_sensor_suffix_from_name(const char *name, char *suffix)
{
char *dash_position = strrchr(name, '-');
if (dash_position)
- strncpy(suffix, dash_position+1, MAX_STRING_LENGTH);
+ strncpy(suffix, dash_position+1, MAX_ATTR_LENGTH);
else
strcpy(suffix,"");
}
-static void get_sensor_attr_properties(const char *sensor_name,
- int sensor_type, enum attributes *attr_type,
- int *sensor_index, int *valid_sensor)
+static int get_sensor_attr_properties(const char *sensor_name,
+ enum sensors sensor_type, enum attributes *attr_type,
+ u32 *sensor_index)
{
- char suffix[MAX_STRING_LENGTH];
-
- *valid_sensor = 0;
+ char suffix[MAX_ATTR_LENGTH];
+ *attr_type = MAX_ATTR_TYPES;
*sensor_index = get_sensor_index_from_name(sensor_name);
if (*sensor_index == 0)
- return;
+ return -EINVAL;
get_sensor_suffix_from_name(sensor_name, suffix);
- if (strcmp(suffix,"") == 0)
- return;
+ if (strcmp(suffix, "") == 0)
+ return -EINVAL;
if (strcmp(suffix, DT_FAULT_ATTR_SUFFIX) == 0)
*attr_type = FAULT;
@@ -257,20 +244,22 @@ static void get_sensor_attr_properties(const char *sensor_name,
else if ((sensor_type == FAN) &&
(strcmp(suffix, DT_THRESHOLD_ATTR_SUFFIX) == 0))
*attr_type = MINIMUM;
+ else
+ return -ENOENT;
if (((sensor_type == FAN) && ((*attr_type == INPUT) ||
(*attr_type == MINIMUM)))
|| ((sensor_type == TEMPERATURE) && ((*attr_type == INPUT) ||
(*attr_type == MAXIMUM)))
|| ((sensor_type == POWER) && ((*attr_type == INPUT))))
- *valid_sensor = 1;
+ return 0;
- return;
+ return -ENOENT;
}
static int create_sensor_attr(struct sensor_specific_data *tdata,
- struct device *dev, enum sensors sensor_type,
- enum sensors attr_type)
+ struct device *dev, enum sensors sensor_type,
+ enum attributes attr_type)
{
int err = 0;
char temp_file_prefix[50];
@@ -287,7 +276,7 @@ static int create_sensor_attr(struct sensor_specific_data *tdata,
else if (sensor_type == POWER)
strcpy(temp_file_prefix, "power");
- snprintf(tdata->attr_name, SENSOR_NAME_LENGTH, file_name_format,
+ snprintf(tdata->attr_name, sizeof(tdata->attr_name), file_name_format,
temp_file_prefix, tdata->sensor_index,
attribute_type_table[tdata->attr_type]);
@@ -318,8 +307,8 @@ static int create_platform_device(enum sensors sensor_type,
struct pdev_entry *pdev_entry = NULL;
int err;
- *pdev = platform_device_alloc(sensor_name_table[sensor_type],
- sensor_type);
+ *pdev = platform_device_alloc(sensor_names[sensor_type].name,
+ sensor_type);
if (!*pdev) {
pr_err("Device allocation failed\n");
err = -ENOMEM;
@@ -402,14 +391,13 @@ static void delete_sensor_attr(struct sensor_data *pdata)
}
static int powernv_sensor_init(u32 sensor_id, const struct device_node *np,
- enum sensors sensor_type,
- enum attributes attr_type,
- int sensor_index)
+ enum sensors sensor_type, enum attributes attr_type,
+ u32 sensor_index)
{
- struct sensor_data *pdata;
struct platform_device *pdev = powernv_sensor_get_pdev(sensor_type);
- struct sensor_entry *sensor_entry;
struct sensor_specific_data *tdata;
+ struct sensor_entry *sensor_entry;
+ struct sensor_data *pdata;
int err = 0;
if (!pdev) {
@@ -466,7 +454,7 @@ static void delete_unregister_sensors(void)
list_for_each_entry_safe(p, n, &pdev_list, list) {
struct sensor_data *pdata = platform_get_drvdata(p->pdev);
- if (pdata != NULL) {
+ if (pdata) {
delete_sensor_attr(pdata);
hwmon_device_unregister(pdata->hwmon_dev);
@@ -480,46 +468,47 @@ static void delete_unregister_sensors(void)
static int __init powernv_hwmon_init(void)
{
- int err = 0;
- const u32 *sensor_id;
struct device_node *opal, *np = NULL;
- enum sensors type;
enum attributes attr_type;
- int i;
- int valid = 0;
- int sensor_index = 0;
+ enum sensors type;
+ const u32 *sensor_id;
+ u32 sensor_index;
+ int err;
opal = of_find_node_by_path("/ibm,opal/sensors");
- if (!opal)
+ if (!opal) {
+ pr_err("%s: Opal 'sensors' node not found\n", __func__);
return -ENXIO;
+ }
for_each_child_of_node(opal, np) {
- type = UNKNOWN;
- valid = 0;
- sensor_index = 0;
- attr_type = UNKNOWN;
-
if (np->name == NULL)
continue;
- for (i = 0; i < MAX_SENSOR_TYPES; i++)
- if (of_get_property(np, "compatible", NULL) &&
- of_device_is_compatible(np,
- dt_sensor_comp_types[i]))
- type = i;
+ for (type = 0; type < MAX_SENSOR_TYPE; type++)
+ if (of_device_is_compatible(np,
+ sensor_names[type].compaible))
+ break;
- get_sensor_attr_properties(np->name, type,
- &attr_type, &sensor_index,
- &valid);
+ if (type == MAX_SENSOR_TYPE)
+ continue;
+
+ if (get_sensor_attr_properties(np->name, type, &attr_type,
+ &sensor_index))
+ continue;
sensor_id = of_get_property(np, "sensor-id", NULL);
- if (sensor_id && valid) {
- err = powernv_sensor_init(*sensor_id, np, type,
- attr_type, sensor_index);
- if (err != 0) {
- of_node_put(opal);
- goto exit;
- }
+ if (!sensor_id) {
+ pr_info("%s: %s doesn't have sensor-id\n", __func__,
+ np->name);
+ continue;
+ }
+
+ err = powernv_sensor_init(*sensor_id, np, type, attr_type,
+ sensor_index);
+ if (err) {
+ of_node_put(opal);
+ goto exit;
}
}
of_node_put(opal);