[PATCH linux dev-4.10 v2 2/5] drivers: hwmon: occ: Add new sensor versions and non-hwmon attributes
Eddie James
eajames at linux.vnet.ibm.com
Sat Jun 10 04:01:02 AEST 2017
From: "Edward A. James" <eajames at us.ibm.com>
Switch to versioned sensors which can be used for both p8 and p9. This
adds more common code and removes the need for the processor-specific
functions (other than the OCC access code).
Also add non-hwmon attributes for OCC status.
Signed-off-by: Edward A. James <eajames at us.ibm.com>
---
drivers/hwmon/occ/Makefile | 2 +-
drivers/hwmon/occ/common.c | 991 ++++++++++++++++++++++++++++++++++++++++++++-
drivers/hwmon/occ/common.h | 17 +
drivers/hwmon/occ/p9.c | 350 ----------------
drivers/hwmon/occ/p9.h | 17 -
drivers/hwmon/occ/p9_sbe.c | 30 +-
6 files changed, 1020 insertions(+), 387 deletions(-)
delete mode 100644 drivers/hwmon/occ/p9.c
delete mode 100644 drivers/hwmon/occ/p9.h
diff --git a/drivers/hwmon/occ/Makefile b/drivers/hwmon/occ/Makefile
index 3b0ddc6..6245c25 100644
--- a/drivers/hwmon/occ/Makefile
+++ b/drivers/hwmon/occ/Makefile
@@ -1 +1 @@
-obj-y += p9.o p9_sbe.o common.o
+obj-y += p9_sbe.o common.o
diff --git a/drivers/hwmon/occ/common.c b/drivers/hwmon/occ/common.c
index 1f17def..bee64cd 100644
--- a/drivers/hwmon/occ/common.c
+++ b/drivers/hwmon/occ/common.c
@@ -7,8 +7,114 @@
* (at your option) any later version.
*/
+#include <asm/unaligned.h>
#include "common.h"
+#define OCC_NUM_STATUS_ATTRS 6
+
+#define OCC_STAT_ACTIVE 0x01
+#define OCC_EXT_STAT_DVFS_OT 0x80
+#define OCC_EXT_STAT_DVFS_POWER 0x40
+#define OCC_EXT_STAT_MEM_THROTTLE 0x20
+#define OCC_EXT_STAT_QUICK_DROP 0x10
+
+struct temp_sensor_1 {
+ u16 sensor_id;
+ u16 value;
+} __packed;
+
+struct temp_sensor_2 {
+ u32 sensor_id;
+ u8 fru_type;
+ u8 value;
+} __packed;
+
+struct freq_sensor_1 {
+ u16 sensor_id;
+ u16 value;
+} __packed;
+
+struct freq_sensor_2 {
+ u32 sensor_id;
+ u16 value;
+} __packed;
+
+struct power_sensor_1 {
+ u16 sensor_id;
+ u32 update_tag;
+ u32 accumulator;
+ u16 value;
+} __packed;
+
+struct power_sensor_2 {
+ u32 sensor_id;
+ u8 function_id;
+ u8 apss_channel;
+ u16 reserved;
+ u32 update_tag;
+ u64 accumulator;
+ u16 value;
+} __packed;
+
+struct power_sensor_data {
+ u16 value;
+ u32 update_tag;
+ u64 accumulator;
+} __packed;
+
+struct power_sensor_data_and_time {
+ u16 update_time;
+ u16 value;
+ u32 update_tag;
+ u64 accumulator;
+} __packed;
+
+struct power_sensor_a0 {
+ u32 sensor_id;
+ struct power_sensor_data_and_time system;
+ u32 reserved;
+ struct power_sensor_data_and_time proc;
+ struct power_sensor_data vdd;
+ struct power_sensor_data vdn;
+} __packed;
+
+struct caps_sensor_1 {
+ u16 curr_powercap;
+ u16 curr_powerreading;
+ u16 norm_powercap;
+ u16 max_powercap;
+ u16 min_powercap;
+ u16 user_powerlimit;
+} __packed;
+
+struct caps_sensor_2 {
+ u16 curr_powercap;
+ u16 curr_powerreading;
+ u16 norm_powercap;
+ u16 max_powercap;
+ u16 min_powercap;
+ u16 user_powerlimit;
+ u8 user_powerlimit_source;
+} __packed;
+
+struct caps_sensor_3 {
+ u16 curr_powercap;
+ u16 curr_powerreading;
+ u16 norm_powercap;
+ u16 max_powercap;
+ u16 hard_min_powercap;
+ u16 soft_min_powercap;
+ u16 user_powerlimit;
+ u8 user_powerlimit_source;
+} __packed;
+
+struct extended_sensor {
+ u8 name[4];
+ u8 flags;
+ u8 reserved;
+ u8 data[6];
+} __packed;
+
void occ_parse_poll_response(struct occ *occ)
{
unsigned int i, offset = 0, size = 0;
@@ -40,6 +146,8 @@ void occ_parse_poll_response(struct occ *occ)
sensor = &sensors->power;
else if (strncmp(block->header.eye_catcher, "CAPS", 4) == 0)
sensor = &sensors->caps;
+ else if (strncmp(block->header.eye_catcher, "EXTN", 4) == 0)
+ sensor = &sensors->extended;
else {
dev_warn(occ->bus_dev, "sensor not supported %.4s\n",
block->header.eye_catcher);
@@ -47,6 +155,7 @@ void occ_parse_poll_response(struct occ *occ)
}
sensor->num_sensors = block->header.num_sensors;
+ sensor->version = block->header.sensor_format;
sensor->data = &block->data;
}
}
@@ -73,8 +182,9 @@ int occ_set_user_power_cap(struct occ *occ, u16 user_power_cap)
int rc;
u8 cmd[8];
u16 checksum = 0x24;
+ __be16 user_power_cap_be;
- user_power_cap = cpu_to_be16(user_power_cap);
+ user_power_cap_be = cpu_to_be16(user_power_cap);
cmd[0] = 0;
cmd[1] = 0x22;
@@ -108,3 +218,882 @@ int occ_update_response(struct occ *occ)
mutex_unlock(&occ->lock);
return rc;
}
+
+static ssize_t occ_show_status(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int rc;
+ int val;
+ struct occ *occ = dev_get_drvdata(dev);
+ struct occ_poll_response_header *header;
+ struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
+
+ rc = occ_update_response(occ);
+ if (rc)
+ return rc;
+
+ header = (struct occ_poll_response_header *)occ->resp.data;
+
+ switch (sattr->index) {
+ case 0:
+ val = header->status & OCC_STAT_ACTIVE;
+ break;
+ case 1:
+ val = header->ext_status & OCC_EXT_STAT_DVFS_OT;
+ break;
+ case 2:
+ val = header->ext_status & OCC_EXT_STAT_DVFS_POWER;
+ break;
+ case 3:
+ val = header->ext_status & OCC_EXT_STAT_MEM_THROTTLE;
+ break;
+ case 4:
+ val = header->ext_status & OCC_EXT_STAT_QUICK_DROP;
+ break;
+ case 5:
+ val = header->occ_state;
+ break;
+ }
+
+ return snprintf(buf, PAGE_SIZE - 1, "%d\n", val);
+}
+
+static ssize_t occ_show_temp_1(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int rc;
+ u16 val = 0;
+ struct temp_sensor_1 *temp;
+ struct occ *occ = dev_get_drvdata(dev);
+ struct occ_sensors *sensors = &occ->sensors;
+ struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+
+ rc = occ_update_response(occ);
+ if (rc)
+ return rc;
+
+ temp = ((struct temp_sensor_1 *)sensors->temp.data) + sattr->index;
+
+ switch (sattr->nr) {
+ case 0:
+ val = get_unaligned_be16(&temp->sensor_id);
+ break;
+ case 1:
+ val = get_unaligned_be16(&temp->value) * 1000;
+ break;
+ }
+
+ return snprintf(buf, PAGE_SIZE - 1, "%u\n", val);
+}
+
+static ssize_t occ_show_temp_2(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int rc;
+ u32 val = 0;
+ struct temp_sensor_2 *temp;
+ struct occ *occ = dev_get_drvdata(dev);
+ struct occ_sensors *sensors = &occ->sensors;
+ struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+
+ rc = occ_update_response(occ);
+ if (rc)
+ return rc;
+
+ temp = ((struct temp_sensor_2 *)sensors->temp.data) + sattr->index;
+
+ switch (sattr->nr) {
+ case 0:
+ val = get_unaligned_be32(&temp->sensor_id);
+ break;
+ case 1:
+ val = temp->value * 1000;
+ break;
+ case 2:
+ val = temp->fru_type;
+ break;
+ }
+
+ return snprintf(buf, PAGE_SIZE - 1, "%u\n", val);
+}
+
+static ssize_t occ_show_freq_1(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int rc;
+ u16 val = 0;
+ struct freq_sensor_1 *freq;
+ struct occ *occ = dev_get_drvdata(dev);
+ struct occ_sensors *sensors = &occ->sensors;
+ struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+
+ rc = occ_update_response(occ);
+ if (rc)
+ return rc;
+
+ freq = ((struct freq_sensor_1 *)sensors->freq.data) + sattr->index;
+
+ switch (sattr->nr) {
+ case 0:
+ val = get_unaligned_be16(&freq->sensor_id);
+ break;
+ case 1:
+ val = get_unaligned_be16(&freq->value);
+ break;
+ }
+
+ return snprintf(buf, PAGE_SIZE - 1, "%u\n", val);
+}
+
+static ssize_t occ_show_freq_2(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int rc;
+ u32 val = 0;
+ struct freq_sensor_2 *freq;
+ struct occ *occ = dev_get_drvdata(dev);
+ struct occ_sensors *sensors = &occ->sensors;
+ struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+
+ rc = occ_update_response(occ);
+ if (rc)
+ return rc;
+
+ freq = ((struct freq_sensor_2 *)sensors->freq.data) + sattr->index;
+
+ switch (sattr->nr) {
+ case 0:
+ val = get_unaligned_be32(&freq->sensor_id);
+ break;
+ case 1:
+ val = get_unaligned_be16(&freq->value);
+ break;
+ }
+
+ return snprintf(buf, PAGE_SIZE - 1, "%u\n", val);
+}
+
+static ssize_t occ_show_power_1(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int rc;
+ u32 val = 0;
+ struct power_sensor_1 *power;
+ struct occ *occ = dev_get_drvdata(dev);
+ struct occ_sensors *sensors = &occ->sensors;
+ struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+
+ rc = occ_update_response(occ);
+ if (rc)
+ return rc;
+
+ power = ((struct power_sensor_1 *)sensors->power.data) + sattr->index;
+
+ switch (sattr->nr) {
+ case 0:
+ val = get_unaligned_be16(&power->sensor_id);
+ break;
+ case 1:
+ val = get_unaligned_be32(&power->update_tag);
+ break;
+ case 2:
+ val = get_unaligned_be32(&power->accumulator);
+ break;
+ case 3:
+ val = get_unaligned_be16(&power->value);
+ break;
+ }
+
+ return snprintf(buf, PAGE_SIZE - 1, "%u\n", val);
+}
+
+static ssize_t occ_show_power_2(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int rc;
+ u64 val = 0;
+ struct power_sensor_2 *power;
+ struct occ *occ = dev_get_drvdata(dev);
+ struct occ_sensors *sensors = &occ->sensors;
+ struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+
+ rc = occ_update_response(occ);
+ if (rc)
+ return rc;
+
+ power = ((struct power_sensor_2 *)sensors->power.data) + sattr->index;
+
+ switch (sattr->nr) {
+ case 0:
+ val = get_unaligned_be32(&power->sensor_id);
+ break;
+ case 1:
+ val = get_unaligned_be32(&power->update_tag);
+ break;
+ case 2:
+ val = get_unaligned_be64(&power->accumulator);
+ break;
+ case 3:
+ val = get_unaligned_be16(&power->value);
+ break;
+ case 4:
+ val = power->function_id;
+ break;
+ case 5:
+ val = power->apss_channel;
+ break;
+ }
+
+ return snprintf(buf, PAGE_SIZE - 1, "%llu\n", val);
+}
+
+static ssize_t occ_show_power_a0(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int rc;
+ u64 val = 0;
+ struct power_sensor_a0 *power;
+ struct occ *occ = dev_get_drvdata(dev);
+ struct occ_sensors *sensors = &occ->sensors;
+ struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+
+ rc = occ_update_response(occ);
+ if (rc)
+ return rc;
+
+ power = ((struct power_sensor_a0 *)sensors->power.data) + sattr->index;
+
+ switch (sattr->nr) {
+ case 0:
+ val = get_unaligned_be32(&power->sensor_id);
+ break;
+ case 1:
+ val = get_unaligned_be16(&power->system.update_time);
+ break;
+ case 2:
+ val = get_unaligned_be16(&power->system.value);
+ break;
+ case 3:
+ val = get_unaligned_be32(&power->system.update_tag);
+ break;
+ case 4:
+ val = get_unaligned_be64(&power->system.accumulator);
+ break;
+ case 5:
+ val = get_unaligned_be16(&power->proc.update_time);
+ break;
+ case 6:
+ val = get_unaligned_be16(&power->proc.value);
+ break;
+ case 7:
+ val = get_unaligned_be32(&power->proc.update_tag);
+ break;
+ case 8:
+ val = get_unaligned_be64(&power->proc.accumulator);
+ break;
+ case 9:
+ val = get_unaligned_be16(&power->vdd.value);
+ break;
+ case 10:
+ val = get_unaligned_be32(&power->vdd.update_tag);
+ break;
+ case 11:
+ val = get_unaligned_be64(&power->vdd.accumulator);
+ break;
+ case 12:
+ val = get_unaligned_be16(&power->vdn.value);
+ break;
+ case 13:
+ val = get_unaligned_be32(&power->vdn.update_tag);
+ break;
+ case 14:
+ val = get_unaligned_be64(&power->vdn.accumulator);
+ break;
+ }
+
+ return snprintf(buf, PAGE_SIZE - 1, "%llu\n", val);
+}
+
+
+static ssize_t occ_show_caps_1(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int rc;
+ u16 val = 0;
+ struct caps_sensor_1 *caps;
+ struct occ *occ = dev_get_drvdata(dev);
+ struct occ_sensors *sensors = &occ->sensors;
+ struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+
+ rc = occ_update_response(occ);
+ if (rc)
+ return rc;
+
+ caps = ((struct caps_sensor_1 *)sensors->caps.data) + sattr->index;
+
+ switch (sattr->nr) {
+ case 0:
+ val = get_unaligned_be16(&caps->curr_powercap);
+ break;
+ case 1:
+ val = get_unaligned_be16(&caps->curr_powerreading);
+ break;
+ case 2:
+ val = get_unaligned_be16(&caps->norm_powercap);
+ break;
+ case 3:
+ val = get_unaligned_be16(&caps->max_powercap);
+ break;
+ case 4:
+ val = get_unaligned_be16(&caps->min_powercap);
+ break;
+ case 5:
+ val = get_unaligned_be16(&caps->user_powerlimit);
+ break;
+ }
+
+ return snprintf(buf, PAGE_SIZE - 1, "%u\n", val);
+}
+
+static ssize_t occ_show_caps_2(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int rc;
+ u16 val = 0;
+ struct caps_sensor_2 *caps;
+ struct occ *occ = dev_get_drvdata(dev);
+ struct occ_sensors *sensors = &occ->sensors;
+ struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+
+ rc = occ_update_response(occ);
+ if (rc)
+ return rc;
+
+ caps = ((struct caps_sensor_2 *)sensors->caps.data) + sattr->index;
+
+ switch (sattr->nr) {
+ case 0:
+ val = get_unaligned_be16(&caps->curr_powercap);
+ break;
+ case 1:
+ val = get_unaligned_be16(&caps->curr_powerreading);
+ break;
+ case 2:
+ val = get_unaligned_be16(&caps->norm_powercap);
+ break;
+ case 3:
+ val = get_unaligned_be16(&caps->max_powercap);
+ break;
+ case 4:
+ val = get_unaligned_be16(&caps->min_powercap);
+ break;
+ case 5:
+ val = get_unaligned_be16(&caps->user_powerlimit);
+ break;
+ case 6:
+ val = caps->user_powerlimit_source;
+ break;
+ }
+
+ return snprintf(buf, PAGE_SIZE - 1, "%u\n", val);
+}
+
+static ssize_t occ_show_caps_3(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int rc;
+ u16 val = 0;
+ struct caps_sensor_3 *caps;
+ struct occ *occ = dev_get_drvdata(dev);
+ struct occ_sensors *sensors = &occ->sensors;
+ struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+
+ rc = occ_update_response(occ);
+ if (rc)
+ return rc;
+
+ caps = ((struct caps_sensor_3 *)sensors->caps.data) + sattr->index;
+
+ switch (sattr->nr) {
+ case 0:
+ val = get_unaligned_be16(&caps->curr_powercap);
+ break;
+ case 1:
+ val = get_unaligned_be16(&caps->curr_powerreading);
+ break;
+ case 2:
+ val = get_unaligned_be16(&caps->norm_powercap);
+ break;
+ case 3:
+ val = get_unaligned_be16(&caps->max_powercap);
+ break;
+ case 4:
+ val = get_unaligned_be16(&caps->hard_min_powercap);
+ break;
+ case 5:
+ val = get_unaligned_be16(&caps->user_powerlimit);
+ break;
+ case 6:
+ val = caps->user_powerlimit_source;
+ break;
+ case 7:
+ val = get_unaligned_be16(&caps->soft_min_powercap);
+ break;
+ }
+
+ return snprintf(buf, PAGE_SIZE - 1, "%u\n", val);
+}
+
+
+static ssize_t occ_store_caps_user(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int rc;
+ u16 user_power_cap;
+ struct occ *occ = dev_get_drvdata(dev);
+
+ rc = kstrtou16(buf, 0, &user_power_cap);
+ if (rc)
+ return rc;
+
+ rc = occ_set_user_power_cap(occ, user_power_cap);
+ if (rc)
+ return rc;
+
+ return count;
+}
+
+static ssize_t occ_show_extended(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int rc;
+ struct extended_sensor *extn;
+ struct occ *occ = dev_get_drvdata(dev);
+ struct occ_sensors *sensors = &occ->sensors;
+ struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+
+ rc = occ_update_response(occ);
+ if (rc)
+ return rc;
+
+ extn = ((struct extended_sensor *)sensors->extended.data) +
+ sattr->index;
+
+ switch (sattr->nr) {
+ case 0:
+ rc = snprintf(buf, PAGE_SIZE - 1, "%02x%02x%02x%02x\n",
+ extn->name[0], extn->name[1], extn->name[2],
+ extn->name[3]);
+ break;
+ case 1:
+ rc = snprintf(buf, PAGE_SIZE - 1, "%02x\n", extn->flags);
+ break;
+ case 2:
+ rc = snprintf(buf, PAGE_SIZE - 1, "%02x%02x%02x%02x%02x%02x\n",
+ extn->data[0], extn->data[1], extn->data[2],
+ extn->data[3], extn->data[4], extn->data[5]);
+ break;
+ }
+
+ return rc;
+}
+
+int occ_setup_sensor_attrs(struct occ *occ)
+{
+ unsigned int i, s;
+ struct device *dev = occ->bus_dev;
+ struct occ_sensors *sensors = &occ->sensors;
+ struct occ_attribute *attr;
+ ssize_t (*show_temp)(struct device *, struct device_attribute *,
+ char *) = occ_show_temp_1;
+ ssize_t (*show_freq)(struct device *, struct device_attribute *,
+ char *) = occ_show_freq_1;
+ ssize_t (*show_power)(struct device *, struct device_attribute *,
+ char *) = occ_show_power_1;
+ ssize_t (*show_caps)(struct device *, struct device_attribute *,
+ char *) = occ_show_caps_1;
+
+ occ->num_attrs = 0;
+
+ switch (sensors->temp.version) {
+ case 1:
+ occ->num_attrs += (sensors->temp.num_sensors * 2);
+ break;
+ case 2:
+ occ->num_attrs += (sensors->temp.num_sensors * 3);
+ show_temp = occ_show_temp_2;
+ break;
+ default:
+ sensors->temp.num_sensors = 0;
+ }
+
+ switch (sensors->freq.version) {
+ case 2:
+ show_freq = occ_show_freq_2;
+ /* fall through */
+ case 1:
+ occ->num_attrs += (sensors->freq.num_sensors * 2);
+ break;
+ default:
+ sensors->freq.num_sensors = 0;
+ }
+
+ switch (sensors->power.version) {
+ case 1:
+ occ->num_attrs += (sensors->power.num_sensors * 4);
+ break;
+ case 2:
+ occ->num_attrs += (sensors->power.num_sensors * 6);
+ show_power = occ_show_power_2;
+ break;
+ case 0xA0:
+ occ->num_attrs += (sensors->power.num_sensors * 15);
+ show_power = occ_show_power_a0;
+ break;
+ default:
+ sensors->power.num_sensors = 0;
+ }
+
+ switch (sensors->caps.version) {
+ case 1:
+ occ->num_attrs += (sensors->caps.num_sensors * 6);
+ break;
+ case 2:
+ occ->num_attrs += (sensors->caps.num_sensors * 7);
+ show_caps = occ_show_caps_2;
+ break;
+ case 3:
+ occ->num_attrs += (sensors->caps.num_sensors * 8);
+ show_caps = occ_show_caps_3;
+ break;
+ default:
+ sensors->caps.num_sensors = 0;
+ }
+
+ switch (sensors->extended.version) {
+ case 1:
+ occ->num_attrs += sensors->extended.num_sensors;
+ break;
+ default:
+ sensors->extended.num_sensors = 0;
+ }
+
+ occ->attrs = devm_kzalloc(dev, sizeof(*occ->attrs) * occ->num_attrs,
+ GFP_KERNEL);
+ if (!occ->attrs)
+ return -ENOMEM;
+
+ occ->group.attrs = devm_kzalloc(dev, sizeof(*occ->group.attrs) *
+ occ->num_attrs + 1, GFP_KERNEL);
+ if (!occ->group.attrs)
+ return -ENOMEM;
+
+ attr = occ->attrs;
+
+ for (i = 0; i < sensors->temp.num_sensors; ++i) {
+ s = i + 1;
+
+ snprintf(attr->name, sizeof(attr->name), "temp%d_label", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_temp, NULL,
+ 0, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name), "temp%d_input", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_temp, NULL,
+ 1, i);
+ attr++;
+
+ if (sensors->temp.version > 1) {
+ snprintf(attr->name, sizeof(attr->name),
+ "temp%d_fru_type", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_temp, NULL, 2, i);
+ attr++;
+ }
+ }
+
+ for (i = 0; i < sensors->freq.num_sensors; ++i) {
+ s = i + 1;
+
+ snprintf(attr->name, sizeof(attr->name), "freq%d_label", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_freq, NULL,
+ 0, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name), "freq%d_input", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_freq, NULL,
+ 1, i);
+ attr++;
+ }
+
+ if (sensors->power.version == 0xA0) {
+ for (i = 0; i < sensors->power.num_sensors; ++i) {
+ s = i + 1;
+
+ snprintf(attr->name, sizeof(attr->name),
+ "power%d_label", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_power, NULL, 0, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name),
+ "power%d_system_update_time", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_power, NULL, 1, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name),
+ "power%d_system_value", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_power, NULL, 2, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name),
+ "power%d_system_update_tag", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_power, NULL, 3, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name),
+ "power%d_system_accumulator", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_power, NULL, 4, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name),
+ "power%d_proc_update_time", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_power, NULL, 5, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name),
+ "power%d_proc_value", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_power, NULL, 6, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name),
+ "power%d_proc_update_tag", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_power, NULL, 7, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name),
+ "power%d_proc_accumulator", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_power, NULL, 8, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name),
+ "power%d_vdd_value", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_power, NULL, 9, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name),
+ "power%d_vdd_update_tag", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_power, NULL, 10, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name),
+ "power%d_vdd_accumulator", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_power, NULL, 11, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name),
+ "power%d_vdn_value", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_power, NULL, 12, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name),
+ "power%d_vdn_update_tag", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_power, NULL, 13, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name),
+ "power%d_vdn_accumulator", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_power, NULL, 14, i);
+ attr++;
+ }
+ } else {
+ for (i = 0; i < sensors->power.num_sensors; ++i) {
+ s = i + 1;
+
+ snprintf(attr->name, sizeof(attr->name),
+ "power%d_label", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_power, NULL, 0, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name),
+ "power%d_update_tag", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_power, NULL, 1, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name),
+ "power%d_accumulator", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_power, NULL, 2, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name),
+ "power%d_input", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_power, NULL, 3, i);
+ attr++;
+
+ if (sensors->power.version > 1) {
+ snprintf(attr->name, sizeof(attr->name),
+ "power%d_function_id", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_power, NULL,
+ 4, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name),
+ "power%d_apss_channel", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_power, NULL,
+ 5, i);
+ attr++;
+ }
+ }
+ }
+
+ for (i = 0; i < sensors->caps.num_sensors; ++i) {
+ s = i + 1;
+
+ snprintf(attr->name, sizeof(attr->name), "caps%d_current", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_caps, NULL,
+ 0, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name), "caps%d_reading", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_caps, NULL,
+ 1, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name), "caps%d_norm", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_caps, NULL,
+ 2, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name), "caps%d_max", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444, show_caps, NULL,
+ 3, i);
+ attr++;
+
+ if (sensors->caps.version > 2) {
+ snprintf(attr->name, sizeof(attr->name),
+ "caps%d_min_hard", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_caps, NULL, 4, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name),
+ "caps%d_min_soft", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_caps, NULL, 7, i);
+ attr++;
+ } else {
+ snprintf(attr->name, sizeof(attr->name), "caps%d_min",
+ s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_caps, NULL, 4, i);
+ attr++;
+ }
+
+ snprintf(attr->name, sizeof(attr->name), "caps%d_user", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0644, show_caps,
+ occ_store_caps_user, 5, i);
+ attr++;
+
+ if (sensors->caps.version > 1) {
+ snprintf(attr->name, sizeof(attr->name),
+ "caps%d_user_source", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ show_caps, NULL, 6, i);
+ attr++;
+ }
+ }
+
+ for (i = 0; i < sensors->extended.num_sensors; ++i) {
+ s = i + 1;
+
+ snprintf(attr->name, sizeof(attr->name), "extn%d_label", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ occ_show_extended, NULL, 0, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name), "extn%d_flags", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ occ_show_extended, NULL, 1, i);
+ attr++;
+
+ snprintf(attr->name, sizeof(attr->name), "extn%d_value", s);
+ attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+ occ_show_extended, NULL, 2, i);
+ attr++;
+ }
+
+ /* put the sensors in the group */
+ for (i = 0; i < occ->num_attrs; ++i)
+ occ->group.attrs[i] = &occ->attrs[i].sensor.dev_attr.attr;
+
+ return 0;
+}
+
+int occ_create_status_attrs(struct occ *occ)
+{
+ int rc, i;
+ struct device *dev = occ->bus_dev;
+
+ occ->status_attrs = devm_kzalloc(dev, sizeof(*occ->status_attrs) *
+ OCC_NUM_STATUS_ATTRS, GFP_KERNEL);
+ if (!occ->status_attrs)
+ return -ENOMEM;
+
+ occ->status_attrs[0] =
+ (struct sensor_device_attribute)SENSOR_ATTR(occ_active, 0444,
+ occ_show_status,
+ NULL, 0);
+ occ->status_attrs[1] =
+ (struct sensor_device_attribute)SENSOR_ATTR(occ_dvfs_ot, 0444,
+ occ_show_status,
+ NULL, 1);
+ occ->status_attrs[2] =
+ (struct sensor_device_attribute)SENSOR_ATTR(occ_dvfs_power,
+ 0444,
+ occ_show_status,
+ NULL, 2);
+ occ->status_attrs[3] =
+ (struct sensor_device_attribute)SENSOR_ATTR(occ_mem_throttle,
+ 0444,
+ occ_show_status,
+ NULL, 3);
+ occ->status_attrs[4] =
+ (struct sensor_device_attribute)SENSOR_ATTR(occ_quick_drop,
+ 0444,
+ occ_show_status,
+ NULL, 4);
+ occ->status_attrs[5] =
+ (struct sensor_device_attribute)SENSOR_ATTR(occ_status, 0444,
+ occ_show_status,
+ NULL, 5);
+
+ for (i = 0; i < OCC_NUM_STATUS_ATTRS; ++i) {
+ rc = device_create_file(dev, &occ->status_attrs[i].dev_attr);
+ if (rc)
+ dev_warn(dev, "error %d creating status attr %d\n", rc,
+ i);
+ }
+
+ return 0;
+}
diff --git a/drivers/hwmon/occ/common.h b/drivers/hwmon/occ/common.h
index a3d733a..ad21538 100644
--- a/drivers/hwmon/occ/common.h
+++ b/drivers/hwmon/occ/common.h
@@ -16,6 +16,18 @@
#define OCC_UPDATE_FREQUENCY msecs_to_jiffies(1000)
#define OCC_RESP_DATA_BYTES 4089
+#define OCC_TIMEOUT_MS 5000
+#define OCC_CMD_IN_PRG_MS 100
+
+#define RESP_RETURN_CMD_IN_PRG 0xFF
+#define RESP_RETURN_SUCCESS 0
+#define RESP_RETURN_CMD_INVAL 0x11
+#define RESP_RETURN_CMD_LEN 0x12
+#define RESP_RETURN_DATA_INVAL 0x13
+#define RESP_RETURN_CHKSUM 0x14
+#define RESP_RETURN_OCC_ERR 0x15
+#define RESP_RETURN_STATE 0x16
+
struct occ_response {
u8 seq_no;
u8 cmd_type;
@@ -63,6 +75,7 @@ struct occ_poll_response {
struct occ_sensor {
u8 num_sensors;
+ u8 version;
void *data;
};
@@ -71,6 +84,7 @@ struct occ_sensors {
struct occ_sensor freq;
struct occ_sensor power;
struct occ_sensor caps;
+ struct occ_sensor extended;
};
struct occ_attribute {
@@ -92,6 +106,7 @@ struct occ {
struct occ_attribute *attrs;
struct attribute_group group;
const struct attribute_group *groups[2];
+ struct sensor_device_attribute *status_attrs;
u8 poll_cmd_data;
int (*send_cmd)(struct occ *occ, u8 *cmd);
@@ -120,5 +135,7 @@ struct occ {
int occ_poll(struct occ *occ);
int occ_set_user_power_cap(struct occ *occ, u16 user_power_cap);
int occ_update_response(struct occ *occ);
+int occ_setup_sensor_attrs(struct occ *occ);
+int occ_create_status_attrs(struct occ *occ);
#endif /* __OCC_COMMON_H__ */
diff --git a/drivers/hwmon/occ/p9.c b/drivers/hwmon/occ/p9.c
deleted file mode 100644
index 832d6ff..0000000
--- a/drivers/hwmon/occ/p9.c
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * Copyright 2017 IBM Corp.
- *
- * 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
- * (at your option) any later version.
- */
-
-#include <asm/unaligned.h>
-#include "common.h"
-
-struct p9_temp_sensor {
- u32 sensor_id;
- u8 fru_type;
- u8 value;
-} __packed;
-
-struct p9_freq_sensor {
- u32 sensor_id;
- u16 value;
-} __packed;
-
-struct p9_power_sensor {
- u32 sensor_id;
- u8 function_id;
- u8 apss_channel;
- u16 reserved;
- u32 update_tag;
- u64 accumulator;
- u16 value;
-} __packed;
-
-struct p9_caps_sensor {
- u16 curr_powercap;
- u16 curr_powerreading;
- u16 norm_powercap;
- u16 max_powercap;
- u16 min_powercap;
- u16 user_powerlimit;
- u8 user_powerlimit_source;
-} __packed;
-
-static ssize_t p9_occ_show_temp(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- int rc;
- u32 val = 0;
- struct p9_temp_sensor *temp;
- struct occ *occ = dev_get_drvdata(dev);
- struct occ_sensors *sensors = &occ->sensors;
- struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
-
- rc = occ_update_response(occ);
- if (rc)
- return rc;
-
- temp = ((struct p9_temp_sensor *)sensors->temp.data) + sattr->index;
-
- switch (sattr->nr) {
- case 0:
- val = be32_to_cpu(get_unaligned(&temp->sensor_id));
- break;
- case 1:
- val = temp->fru_type;
- break;
- case 2:
- /* millidegree */
- val = temp->value * 1000;
- break;
- }
-
- return snprintf(buf, PAGE_SIZE - 1, "%u\n", val);
-}
-
-static ssize_t p9_occ_show_freq(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- int rc;
- u32 val = 0;
- struct p9_freq_sensor *freq;
- struct occ *occ = dev_get_drvdata(dev);
- struct occ_sensors *sensors = &occ->sensors;
- struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
-
- rc = occ_update_response(occ);
- if (rc)
- return rc;
-
- freq = ((struct p9_freq_sensor *)sensors->freq.data) + sattr->index;
-
- switch (sattr->nr) {
- case 0:
- val = be32_to_cpu(get_unaligned(&freq->sensor_id));
- break;
- case 1:
- val = be16_to_cpu(get_unaligned(&freq->value));
- break;
- }
-
- return snprintf(buf, PAGE_SIZE - 1, "%u\n", val);
-}
-
-static ssize_t p9_occ_show_power(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- int rc;
- u64 val = 0;
- struct p9_power_sensor *power;
- struct occ *occ = dev_get_drvdata(dev);
- struct occ_sensors *sensors = &occ->sensors;
- struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
-
- rc = occ_update_response(occ);
- if (rc)
- return rc;
-
- power = ((struct p9_power_sensor *)sensors->power.data) + sattr->index;
-
- switch (sattr->nr) {
- case 0:
- val = be32_to_cpu(get_unaligned(&power->sensor_id));
- break;
- case 1:
- val = power->function_id;
- break;
- case 2:
- val = power->apss_channel;
- break;
- case 3:
- val = be32_to_cpu(get_unaligned(&power->update_tag));
- break;
- case 4:
- val = be64_to_cpu(get_unaligned(&power->accumulator));
- break;
- case 5:
- val = be16_to_cpu(get_unaligned(&power->value));
- break;
- }
-
- return snprintf(buf, PAGE_SIZE - 1, "%llu\n", val);
-}
-
-static ssize_t p9_occ_show_caps(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- int rc;
- u16 val = 0;
- struct p9_caps_sensor *caps;
- struct occ *occ = dev_get_drvdata(dev);
- struct occ_sensors *sensors = &occ->sensors;
- struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
-
- rc = occ_update_response(occ);
- if (rc)
- return rc;
-
- caps = ((struct p9_caps_sensor *)sensors->caps.data) + sattr->index;
-
- switch (sattr->nr) {
- case 0:
- val = be16_to_cpu(get_unaligned(&caps->curr_powercap));
- break;
- case 1:
- val = be16_to_cpu(get_unaligned(&caps->curr_powerreading));
- break;
- case 2:
- val = be16_to_cpu(get_unaligned(&caps->norm_powercap));
- break;
- case 3:
- val = be16_to_cpu(get_unaligned(&caps->max_powercap));
- break;
- case 4:
- val = be16_to_cpu(get_unaligned(&caps->min_powercap));
- break;
- case 5:
- val = be16_to_cpu(get_unaligned(&caps->user_powerlimit));
- break;
- case 6:
- val = caps->user_powerlimit_source;
- break;
- }
-
- return snprintf(buf, PAGE_SIZE - 1, "%u\n", val);
-}
-
-static ssize_t p9_occ_store_caps_user(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- int rc;
- u16 user_power_cap;
- struct occ *occ = dev_get_drvdata(dev);
-
- rc = kstrtou16(buf, 0, &user_power_cap);
- if (rc)
- return rc;
-
- rc = occ_set_user_power_cap(occ, user_power_cap);
- if (rc)
- return rc;
-
- return count;
-}
-
-int p9_occ_setup_sensor_attrs(struct occ *occ)
-{
- unsigned int i, s;
- struct device *dev = occ->bus_dev;
- struct occ_sensors *sensors = &occ->sensors;
- struct occ_attribute *attr;
-
- occ->num_attrs = (sensors->temp.num_sensors * 3);
- occ->num_attrs += (sensors->freq.num_sensors * 2);
- occ->num_attrs += (sensors->power.num_sensors * 6);
- occ->num_attrs += (sensors->caps.num_sensors * 7);
-
- occ->attrs = devm_kzalloc(dev, sizeof(*occ->attrs) * occ->num_attrs,
- GFP_KERNEL);
- if (!occ->attrs)
- return -ENOMEM;
-
- occ->group.attrs = devm_kzalloc(dev, sizeof(*occ->group.attrs) *
- occ->num_attrs + 1, GFP_KERNEL);
- if (!occ->group.attrs)
- return -ENOMEM;
-
- attr = occ->attrs;
- for (i = 0; i < sensors->temp.num_sensors; ++i) {
- s = i + 1;
-
- snprintf(attr->name, sizeof(attr->name), "temp%d_label", s);
- attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
- p9_occ_show_temp, NULL, 0, i);
- attr++;
-
- snprintf(attr->name, sizeof(attr->name), "temp%d_fru_type", s);
- attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
- p9_occ_show_temp, NULL, 1, i);
- attr++;
-
- snprintf(attr->name, sizeof(attr->name), "temp%d_input", s);
- attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
- p9_occ_show_temp, NULL, 2, i);
- attr++;
- }
-
- for (i = 0; i < sensors->freq.num_sensors; ++i) {
- s = i + 1;
-
- snprintf(attr->name, sizeof(attr->name), "freq%d_label", s);
- attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
- p9_occ_show_freq, NULL, 0, i);
- attr++;
-
- snprintf(attr->name, sizeof(attr->name), "freq%d_input", s);
- attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
- p9_occ_show_freq, NULL, 1, i);
- attr++;
- }
-
- for (i = 0; i < sensors->power.num_sensors; ++i) {
- s = i + 1;
-
- snprintf(attr->name, sizeof(attr->name), "power%d_label", s);
- attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
- p9_occ_show_power, NULL, 0, i);
- attr++;
-
- snprintf(attr->name, sizeof(attr->name), "power%d_function_id",
- s);
- attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
- p9_occ_show_power, NULL, 1, i);
- attr++;
-
- snprintf(attr->name, sizeof(attr->name),
- "power%d_apss_channel", s);
- attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
- p9_occ_show_power, NULL, 2, i);
- attr++;
-
- snprintf(attr->name, sizeof(attr->name), "power%d_update_tag",
- s);
- attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
- p9_occ_show_power, NULL, 3, i);
- attr++;
-
- snprintf(attr->name, sizeof(attr->name), "power%d_accumulator",
- s);
- attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
- p9_occ_show_power, NULL, 4, i);
- attr++;
-
- snprintf(attr->name, sizeof(attr->name), "power%d_input", s);
- attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
- p9_occ_show_power, NULL, 5, i);
- attr++;
- }
-
- for (i = 0; i < sensors->caps.num_sensors; ++i) {
- s = i + 1;
-
- snprintf(attr->name, sizeof(attr->name), "caps%d_curr", s);
- attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
- p9_occ_show_caps, NULL, 0, i);
- attr++;
-
- snprintf(attr->name, sizeof(attr->name), "caps%d_reading", s);
- attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
- p9_occ_show_caps, NULL, 1, i);
- attr++;
-
- snprintf(attr->name, sizeof(attr->name), "caps%d_norm", s);
- attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
- p9_occ_show_caps, NULL, 2, i);
- attr++;
-
- snprintf(attr->name, sizeof(attr->name), "caps%d_max", s);
- attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
- p9_occ_show_caps, NULL, 3, i);
- attr++;
-
- snprintf(attr->name, sizeof(attr->name), "caps%d_min", s);
- attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
- p9_occ_show_caps, NULL, 4, i);
- attr++;
-
- snprintf(attr->name, sizeof(attr->name), "caps%d_user", s);
- attr->sensor = OCC_INIT_ATTR(attr->name, 0644,
- p9_occ_show_caps,
- p9_occ_store_caps_user, 5, i);
- attr++;
-
- snprintf(attr->name, sizeof(attr->name), "caps%d_user_source",
- s);
- attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
- p9_occ_show_caps, NULL, 6, i);
- attr++;
- }
-
- /* put the sensors in the group */
- for (i = 0; i < occ->num_attrs; ++i)
- occ->group.attrs[i] = &occ->attrs[i].sensor.dev_attr.attr;
-
- return 0;
-}
diff --git a/drivers/hwmon/occ/p9.h b/drivers/hwmon/occ/p9.h
deleted file mode 100644
index 12d1bc5..0000000
--- a/drivers/hwmon/occ/p9.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright 2017 IBM Corp.
- *
- * 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
- * (at your option) any later version.
- */
-
-#ifndef __OCC_P9_H__
-#define __OCC_P9_H__
-
-struct occ;
-
-int p9_occ_setup_sensor_attrs(struct occ *occ);
-
-#endif /* __OCC_P9_H__ */
diff --git a/drivers/hwmon/occ/p9_sbe.c b/drivers/hwmon/occ/p9_sbe.c
index 88f71b1..fe435ef 100644
--- a/drivers/hwmon/occ/p9_sbe.c
+++ b/drivers/hwmon/occ/p9_sbe.c
@@ -15,21 +15,8 @@
#include <linux/occ.h>
#include <linux/sched.h>
#include <linux/workqueue.h>
-#include "p9.h"
-#define P9_SBE_OCC_SETUP_DELAY 2500
-
-#define OCC_TIMEOUT_MS 5000
-#define OCC_CMD_IN_PRG_MS 100
-
-#define RESP_RETURN_CMD_IN_PRG 0xFF
-#define RESP_RETURN_SUCCESS 0
-#define RESP_RETURN_CMD_INVAL 0x11
-#define RESP_RETURN_CMD_LEN 0x12
-#define RESP_RETURN_DATA_INVAL 0x13
-#define RESP_RETURN_CHKSUM 0x14
-#define RESP_RETURN_OCC_ERR 0x15
-#define RESP_RETURN_STATE 0x16
+#define P9_SBE_OCC_SETUP_DELAY 5000
struct p9_sbe_occ {
struct occ occ;
@@ -66,7 +53,8 @@ static int p9_sbe_occ_send_cmd(struct occ *occ, u8 *cmd)
switch (resp->return_status) {
case RESP_RETURN_CMD_IN_PRG:
- if (time_after(jiffies, start + msecs_to_jiffies(OCC_TIMEOUT_MS)))
+ if (time_after(jiffies,
+ start + msecs_to_jiffies(OCC_TIMEOUT_MS)))
rc = -EALREADY;
else {
set_current_state(TASK_INTERRUPTIBLE);
@@ -123,7 +111,7 @@ static void p9_sbe_occ_setup(struct work_struct *work)
occ_parse_poll_response(occ);
- rc = p9_occ_setup_sensor_attrs(occ);
+ rc = occ_setup_sensor_attrs(occ);
if (rc) {
dev_err(occ->bus_dev, "failed to setup p9 attrs: %d\n", rc);
return;
@@ -137,6 +125,10 @@ static void p9_sbe_occ_setup(struct work_struct *work)
PTR_ERR(occ->hwmon));
return;
}
+
+ rc = occ_create_status_attrs(occ);
+ if (rc)
+ dev_err(occ->bus_dev, "failed to setup p9 status attrs: %d\n", rc);
}
static int p9_sbe_occ_probe(struct platform_device *pdev)
@@ -157,7 +149,8 @@ static int p9_sbe_occ_probe(struct platform_device *pdev)
occ->send_cmd = p9_sbe_occ_send_cmd;
mutex_init(&occ->lock);
INIT_DELAYED_WORK(&p9_sbe_occ->setup, p9_sbe_occ_setup);
- platform_set_drvdata(pdev, p9_sbe_occ);
+
+ platform_set_drvdata(pdev, occ);
schedule_delayed_work(&p9_sbe_occ->setup,
msecs_to_jiffies(P9_SBE_OCC_SETUP_DELAY));
@@ -167,7 +160,8 @@ static int p9_sbe_occ_probe(struct platform_device *pdev)
static int p9_sbe_occ_remove(struct platform_device *pdev)
{
- struct p9_sbe_occ *p9_sbe_occ = platform_get_drvdata(pdev);
+ struct occ *occ = platform_get_drvdata(pdev);
+ struct p9_sbe_occ *p9_sbe_occ = to_p9_sbe_occ(occ);
cancel_delayed_work_sync(&p9_sbe_occ->setup);
--
1.8.3.1
More information about the openbmc
mailing list