Skip to contentSkip to conversation

hwmon: (occ) Add various poll response data in sysfs

PATCH Applied Eddie James 3 participants 15 messages Feb 15, 2022 – Feb 22, 2022 Hardware monitoring

lore
Share & tools
lore
#0 lore raw

cover hwmon: (occ) Add various poll response data in sysfs

BMC control applications need to check various additional bits in the extended status in the poll response, as well as the OCC mode and IPS status bytes. Export all those through sysfs. In addition, add the "soft" minimum power cap attribute through hwmon.

Eddie James (4):
hwmon: (occ) Add sysfs entry for IPS (Idle Power Saver) status
hwmon: (occ) Add sysfs entry for OCC mode
hwmon: (occ) Add sysfs entries for additional extended status bits
hwmon: (occ) Add soft minimum power cap attribute

 drivers/hwmon/occ/common.c | 19 +++++++++++++---
 drivers/hwmon/occ/common.h |  2 ++
 drivers/hwmon/occ/sysfs.c  | 46 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 64 insertions(+), 3 deletions(-)
Signature · 1 line
2.27.0
#1 lore raw

PATCH 1/4 hwmon: (occ) Add sysfs entry for IPS (Idle Power Saver) status

BMC control applications need to check the Idle Power Saver status byte returned by the OCC poll response, so export it in sysfs with the other OCC-specific data.

---
 drivers/hwmon/occ/common.h |  1 +
 drivers/hwmon/occ/sysfs.c  | 11 +++++++++++
 2 files changed, 12 insertions(+)
drivers/hwmon/occ/common.h +1 -0
index 5020117be740..a88c66d36e38 100644
@@ -119,6 +119,7 @@ struct occ {
 	u8 prev_stat;
 	u8 prev_ext_stat;
 	u8 prev_occs_present;
+	u8 prev_ips_status;
 };
 
 int occ_setup(struct occ *occ, const char *name);
drivers/hwmon/occ/sysfs.c +11 -0
index 03b16abef67f..6dc69c9aa4c2 100644
@@ -63,6 +63,9 @@ static ssize_t occ_sysfs_show(struct device *dev,
 		else
 			val = 1;
 		break;
+	case 8:
+		val = header->ips_status;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -88,6 +91,7 @@ static SENSOR_DEVICE_ATTR(occ_mem_throttle, 0444, occ_sysfs_show, NULL, 4);
 static SENSOR_DEVICE_ATTR(occ_quick_pwr_drop, 0444, occ_sysfs_show, NULL, 5);
 static SENSOR_DEVICE_ATTR(occ_state, 0444, occ_sysfs_show, NULL, 6);
 static SENSOR_DEVICE_ATTR(occs_present, 0444, occ_sysfs_show, NULL, 7);
+static SENSOR_DEVICE_ATTR(occ_ips_status, 0444, occ_sysfs_show, NULL, 8);
 static DEVICE_ATTR_RO(occ_error);
 
 static struct attribute *occ_attributes[] = {
@@ -99,6 +103,7 @@ static struct attribute *occ_attributes[] = {
 	&sensor_dev_attr_occ_quick_pwr_drop.dev_attr.attr,
 	&sensor_dev_attr_occ_state.dev_attr.attr,
 	&sensor_dev_attr_occs_present.dev_attr.attr,
+	&sensor_dev_attr_occ_ips_status.dev_attr.attr,
 	&dev_attr_occ_error.attr,
 	NULL
 };
@@ -162,6 +167,11 @@ void occ_sysfs_poll_done(struct occ *occ)
 		sysfs_notify(&occ->bus_dev->kobj, NULL, name);
 	}
 
+	if (header->ips_status != occ->prev_ips_status) {
+		name = sensor_dev_attr_occ_ips_status.dev_attr.attr.name;
+		sysfs_notify(&occ->bus_dev->kobj, NULL, name);
+	}
+
 	if (occ->error && occ->error != occ->prev_error) {
 		name = dev_attr_occ_error.attr.name;
 		sysfs_notify(&occ->bus_dev->kobj, NULL, name);
@@ -174,6 +184,7 @@ void occ_sysfs_poll_done(struct occ *occ)
 	occ->prev_stat = header->status;
 	occ->prev_ext_stat = header->ext_status;
 	occ->prev_occs_present = header->occs_present;
+	occ->prev_ips_status = header->ips_status;
 }
 
 int occ_setup_sysfs(struct occ *occ)
Signature · 1 line
2.27.0
Reviewed-by on v1 1/4
#2 lore raw

Re: [PATCH 1/4] hwmon: (occ) Add sysfs entry for IPS (Idle Power Saver) status

Quoted 6 lines · Eddie James

BMC control applications need to check the Idle Power Saver status byte returned by the OCC poll response, so export it in sysfs with the other OCC-specific data.

Quoted 70 lines
---
 drivers/hwmon/occ/common.h |  1 +
 drivers/hwmon/occ/sysfs.c  | 11 +++++++++++
 2 files changed, 12 insertions(+)
drivers/hwmon/occ/common.h +1 -0
index 5020117be740..a88c66d36e38 100644
@@ -119,6 +119,7 @@ struct occ {
        u8 prev_stat;
        u8 prev_ext_stat;
        u8 prev_occs_present;
+       u8 prev_ips_status;
 };
 
 int occ_setup(struct occ *occ, const char *name);
drivers/hwmon/occ/sysfs.c +11 -1
index 03b16abef67f..6dc69c9aa4c2 100644
@@ -63,6 +63,9 @@ static ssize_t occ_sysfs_show(struct device *dev,
                else
                        val = 1;
                break;
+       case 8:
+               val = header->ips_status;
+               break;
        default:
                return -EINVAL;
        }
@@ -88,6 +91,7 @@ static SENSOR_DEVICE_ATTR(occ_mem_throttle, 0444, occ_sysfs_show, NULL, 4);
 static SENSOR_DEVICE_ATTR(occ_quick_pwr_drop, 0444, occ_sysfs_show, NULL, 5);
 static SENSOR_DEVICE_ATTR(occ_state, 0444, occ_sysfs_show, NULL, 6);
 static SENSOR_DEVICE_ATTR(occs_present, 0444, occ_sysfs_show, NULL, 7);
+static SENSOR_DEVICE_ATTR(occ_ips_status, 0444, occ_sysfs_show, NULL, 8);
 static DEVICE_ATTR_RO(occ_error);
 
 static struct attribute *occ_attributes[] = {
@@ -99,6 +103,7 @@ static struct attribute *occ_attributes[] = {
        &sensor_dev_attr_occ_quick_pwr_drop.dev_attr.attr,
        &sensor_dev_attr_occ_state.dev_attr.attr,
        &sensor_dev_attr_occs_present.dev_attr.attr,
+       &sensor_dev_attr_occ_ips_status.dev_attr.attr,
        &dev_attr_occ_error.attr,
        NULL
 };
@@ -162,6 +167,11 @@ void occ_sysfs_poll_done(struct occ *occ)
                sysfs_notify(&occ->bus_dev->kobj, NULL, name);
        }
 
+       if (header->ips_status != occ->prev_ips_status) {
+               name = sensor_dev_attr_occ_ips_status.dev_attr.attr.name;
+               sysfs_notify(&occ->bus_dev->kobj, NULL, name);
+       }
+
        if (occ->error && occ->error != occ->prev_error) {
                name = dev_attr_occ_error.attr.name;
                sysfs_notify(&occ->bus_dev->kobj, NULL, name);
@@ -174,6 +184,7 @@ void occ_sysfs_poll_done(struct occ *occ)
        occ->prev_stat = header->status;
        occ->prev_ext_stat = header->ext_status;
        occ->prev_occs_present = header->occs_present;
+       occ->prev_ips_status = header->ips_status;
 }
 
 int occ_setup_sysfs(struct occ *occ)
--

2.27.0

maintainer Applied
#3 lore raw

Re: [PATCH 1/4] hwmon: (occ) Add sysfs entry for IPS (Idle Power Saver) status

In reply to Eddie James
Quoted 6 lines · Eddie James

BMC control applications need to check the Idle Power Saver status byte returned by the OCC poll response, so export it in sysfs with the other OCC-specific data.

Applied to hwmon-next.

Thanks,
Guenter

Quoted 67 lines
---
 drivers/hwmon/occ/common.h |  1 +
 drivers/hwmon/occ/sysfs.c  | 11 +++++++++++
 2 files changed, 12 insertions(+)
drivers/hwmon/occ/common.h +1 -0
index 5020117be740..a88c66d36e38 100644
@@ -119,6 +119,7 @@ struct occ {
 	u8 prev_stat;
 	u8 prev_ext_stat;
 	u8 prev_occs_present;
+	u8 prev_ips_status;
 };
 
 int occ_setup(struct occ *occ, const char *name);
drivers/hwmon/occ/sysfs.c +11 -0
index 03b16abef67f..6dc69c9aa4c2 100644
@@ -63,6 +63,9 @@ static ssize_t occ_sysfs_show(struct device *dev,
 		else
 			val = 1;
 		break;
+	case 8:
+		val = header->ips_status;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -88,6 +91,7 @@ static SENSOR_DEVICE_ATTR(occ_mem_throttle, 0444, occ_sysfs_show, NULL, 4);
 static SENSOR_DEVICE_ATTR(occ_quick_pwr_drop, 0444, occ_sysfs_show, NULL, 5);
 static SENSOR_DEVICE_ATTR(occ_state, 0444, occ_sysfs_show, NULL, 6);
 static SENSOR_DEVICE_ATTR(occs_present, 0444, occ_sysfs_show, NULL, 7);
+static SENSOR_DEVICE_ATTR(occ_ips_status, 0444, occ_sysfs_show, NULL, 8);
 static DEVICE_ATTR_RO(occ_error);
 
 static struct attribute *occ_attributes[] = {
@@ -99,6 +103,7 @@ static struct attribute *occ_attributes[] = {
 	&sensor_dev_attr_occ_quick_pwr_drop.dev_attr.attr,
 	&sensor_dev_attr_occ_state.dev_attr.attr,
 	&sensor_dev_attr_occs_present.dev_attr.attr,
+	&sensor_dev_attr_occ_ips_status.dev_attr.attr,
 	&dev_attr_occ_error.attr,
 	NULL
 };
@@ -162,6 +167,11 @@ void occ_sysfs_poll_done(struct occ *occ)
 		sysfs_notify(&occ->bus_dev->kobj, NULL, name);
 	}
 
+	if (header->ips_status != occ->prev_ips_status) {
+		name = sensor_dev_attr_occ_ips_status.dev_attr.attr.name;
+		sysfs_notify(&occ->bus_dev->kobj, NULL, name);
+	}
+
 	if (occ->error && occ->error != occ->prev_error) {
 		name = dev_attr_occ_error.attr.name;
 		sysfs_notify(&occ->bus_dev->kobj, NULL, name);
@@ -174,6 +184,7 @@ void occ_sysfs_poll_done(struct occ *occ)
 	occ->prev_stat = header->status;
 	occ->prev_ext_stat = header->ext_status;
 	occ->prev_occs_present = header->occs_present;
+	occ->prev_ips_status = header->ips_status;
 }
 
 int occ_setup_sysfs(struct occ *occ)
#4 lore raw

PATCH 2/4 hwmon: (occ) Add sysfs entry for OCC mode

In reply to Eddie James

BMC control applications need to check the OCC mode returned by the OCC poll response, so export it in sysfs with the other OCC-specific data.

---
 drivers/hwmon/occ/common.h |  1 +
 drivers/hwmon/occ/sysfs.c  | 11 +++++++++++
 2 files changed, 12 insertions(+)
drivers/hwmon/occ/common.h +1 -0
index a88c66d36e38..2dd4a4d240c0 100644
@@ -120,6 +120,7 @@ struct occ {
 	u8 prev_ext_stat;
 	u8 prev_occs_present;
 	u8 prev_ips_status;
+	u8 prev_mode;
 };
 
 int occ_setup(struct occ *occ, const char *name);
drivers/hwmon/occ/sysfs.c +11 -0
index 6dc69c9aa4c2..88f655887c95 100644
@@ -66,6 +66,9 @@ static ssize_t occ_sysfs_show(struct device *dev,
 	case 8:
 		val = header->ips_status;
 		break;
+	case 9:
+		val = header->mode;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -92,6 +95,7 @@ static SENSOR_DEVICE_ATTR(occ_quick_pwr_drop, 0444, occ_sysfs_show, NULL, 5);
 static SENSOR_DEVICE_ATTR(occ_state, 0444, occ_sysfs_show, NULL, 6);
 static SENSOR_DEVICE_ATTR(occs_present, 0444, occ_sysfs_show, NULL, 7);
 static SENSOR_DEVICE_ATTR(occ_ips_status, 0444, occ_sysfs_show, NULL, 8);
+static SENSOR_DEVICE_ATTR(occ_mode, 0444, occ_sysfs_show, NULL, 9);
 static DEVICE_ATTR_RO(occ_error);
 
 static struct attribute *occ_attributes[] = {
@@ -104,6 +108,7 @@ static struct attribute *occ_attributes[] = {
 	&sensor_dev_attr_occ_state.dev_attr.attr,
 	&sensor_dev_attr_occs_present.dev_attr.attr,
 	&sensor_dev_attr_occ_ips_status.dev_attr.attr,
+	&sensor_dev_attr_occ_mode.dev_attr.attr,
 	&dev_attr_occ_error.attr,
 	NULL
 };
@@ -172,6 +177,11 @@ void occ_sysfs_poll_done(struct occ *occ)
 		sysfs_notify(&occ->bus_dev->kobj, NULL, name);
 	}
 
+	if (header->mode != occ->prev_mode) {
+		name = sensor_dev_attr_occ_mode.dev_attr.attr.name;
+		sysfs_notify(&occ->bus_dev->kobj, NULL, name);
+	}
+
 	if (occ->error && occ->error != occ->prev_error) {
 		name = dev_attr_occ_error.attr.name;
 		sysfs_notify(&occ->bus_dev->kobj, NULL, name);
@@ -185,6 +195,7 @@ void occ_sysfs_poll_done(struct occ *occ)
 	occ->prev_ext_stat = header->ext_status;
 	occ->prev_occs_present = header->occs_present;
 	occ->prev_ips_status = header->ips_status;
+	occ->prev_mode = header->mode;
 }
 
 int occ_setup_sysfs(struct occ *occ)
Signature · 1 line
2.27.0
Reviewed-by on v1 2/4
#5 lore raw

Re: [PATCH 2/4] hwmon: (occ) Add sysfs entry for OCC mode

Quoted 6 lines · Eddie James

BMC control applications need to check the OCC mode returned by the OCC poll response, so export it in sysfs with the other OCC-specific data.

Quoted 70 lines
---
 drivers/hwmon/occ/common.h |  1 +
 drivers/hwmon/occ/sysfs.c  | 11 +++++++++++
 2 files changed, 12 insertions(+)
drivers/hwmon/occ/common.h +1 -0
index a88c66d36e38..2dd4a4d240c0 100644
@@ -120,6 +120,7 @@ struct occ {
        u8 prev_ext_stat;
        u8 prev_occs_present;
        u8 prev_ips_status;
+       u8 prev_mode;
 };
 
 int occ_setup(struct occ *occ, const char *name);
drivers/hwmon/occ/sysfs.c +11 -1
index 6dc69c9aa4c2..88f655887c95 100644
@@ -66,6 +66,9 @@ static ssize_t occ_sysfs_show(struct device *dev,
        case 8:
                val = header->ips_status;
                break;
+       case 9:
+               val = header->mode;
+               break;
        default:
                return -EINVAL;
        }
@@ -92,6 +95,7 @@ static SENSOR_DEVICE_ATTR(occ_quick_pwr_drop, 0444, occ_sysfs_show, NULL, 5);
 static SENSOR_DEVICE_ATTR(occ_state, 0444, occ_sysfs_show, NULL, 6);
 static SENSOR_DEVICE_ATTR(occs_present, 0444, occ_sysfs_show, NULL, 7);
 static SENSOR_DEVICE_ATTR(occ_ips_status, 0444, occ_sysfs_show, NULL, 8);
+static SENSOR_DEVICE_ATTR(occ_mode, 0444, occ_sysfs_show, NULL, 9);
 static DEVICE_ATTR_RO(occ_error);
 
 static struct attribute *occ_attributes[] = {
@@ -104,6 +108,7 @@ static struct attribute *occ_attributes[] = {
        &sensor_dev_attr_occ_state.dev_attr.attr,
        &sensor_dev_attr_occs_present.dev_attr.attr,
        &sensor_dev_attr_occ_ips_status.dev_attr.attr,
+       &sensor_dev_attr_occ_mode.dev_attr.attr,
        &dev_attr_occ_error.attr,
        NULL
 };
@@ -172,6 +177,11 @@ void occ_sysfs_poll_done(struct occ *occ)
                sysfs_notify(&occ->bus_dev->kobj, NULL, name);
        }
 
+       if (header->mode != occ->prev_mode) {
+               name = sensor_dev_attr_occ_mode.dev_attr.attr.name;
+               sysfs_notify(&occ->bus_dev->kobj, NULL, name);
+       }
+
        if (occ->error && occ->error != occ->prev_error) {
                name = dev_attr_occ_error.attr.name;
                sysfs_notify(&occ->bus_dev->kobj, NULL, name);
@@ -185,6 +195,7 @@ void occ_sysfs_poll_done(struct occ *occ)
        occ->prev_ext_stat = header->ext_status;
        occ->prev_occs_present = header->occs_present;
        occ->prev_ips_status = header->ips_status;
+       occ->prev_mode = header->mode;
 }
 
 int occ_setup_sysfs(struct occ *occ)
--

2.27.0

maintainer Applied
#6 lore raw

Re: [PATCH 2/4] hwmon: (occ) Add sysfs entry for OCC mode

In reply to Eddie James
Quoted 6 lines · Eddie James

BMC control applications need to check the OCC mode returned by the OCC poll response, so export it in sysfs with the other OCC-specific data.

Applied to hwmon-next.

Thanks,
Guenter

Quoted 67 lines
---
 drivers/hwmon/occ/common.h |  1 +
 drivers/hwmon/occ/sysfs.c  | 11 +++++++++++
 2 files changed, 12 insertions(+)
drivers/hwmon/occ/common.h +1 -0
index a88c66d36e38..2dd4a4d240c0 100644
@@ -120,6 +120,7 @@ struct occ {
 	u8 prev_ext_stat;
 	u8 prev_occs_present;
 	u8 prev_ips_status;
+	u8 prev_mode;
 };
 
 int occ_setup(struct occ *occ, const char *name);
drivers/hwmon/occ/sysfs.c +11 -0
index 6dc69c9aa4c2..88f655887c95 100644
@@ -66,6 +66,9 @@ static ssize_t occ_sysfs_show(struct device *dev,
 	case 8:
 		val = header->ips_status;
 		break;
+	case 9:
+		val = header->mode;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -92,6 +95,7 @@ static SENSOR_DEVICE_ATTR(occ_quick_pwr_drop, 0444, occ_sysfs_show, NULL, 5);
 static SENSOR_DEVICE_ATTR(occ_state, 0444, occ_sysfs_show, NULL, 6);
 static SENSOR_DEVICE_ATTR(occs_present, 0444, occ_sysfs_show, NULL, 7);
 static SENSOR_DEVICE_ATTR(occ_ips_status, 0444, occ_sysfs_show, NULL, 8);
+static SENSOR_DEVICE_ATTR(occ_mode, 0444, occ_sysfs_show, NULL, 9);
 static DEVICE_ATTR_RO(occ_error);
 
 static struct attribute *occ_attributes[] = {
@@ -104,6 +108,7 @@ static struct attribute *occ_attributes[] = {
 	&sensor_dev_attr_occ_state.dev_attr.attr,
 	&sensor_dev_attr_occs_present.dev_attr.attr,
 	&sensor_dev_attr_occ_ips_status.dev_attr.attr,
+	&sensor_dev_attr_occ_mode.dev_attr.attr,
 	&dev_attr_occ_error.attr,
 	NULL
 };
@@ -172,6 +177,11 @@ void occ_sysfs_poll_done(struct occ *occ)
 		sysfs_notify(&occ->bus_dev->kobj, NULL, name);
 	}
 
+	if (header->mode != occ->prev_mode) {
+		name = sensor_dev_attr_occ_mode.dev_attr.attr.name;
+		sysfs_notify(&occ->bus_dev->kobj, NULL, name);
+	}
+
 	if (occ->error && occ->error != occ->prev_error) {
 		name = dev_attr_occ_error.attr.name;
 		sysfs_notify(&occ->bus_dev->kobj, NULL, name);
@@ -185,6 +195,7 @@ void occ_sysfs_poll_done(struct occ *occ)
 	occ->prev_ext_stat = header->ext_status;
 	occ->prev_occs_present = header->occs_present;
 	occ->prev_ips_status = header->ips_status;
+	occ->prev_mode = header->mode;
 }
 
 int occ_setup_sysfs(struct occ *occ)
#7 lore raw

PATCH 3/4 hwmon: (occ) Add sysfs entries for additional extended status bits

In reply to Eddie James

Add sysfs entries for DVFS due to a VRM Vdd over-temperature condition, and add the GPU throttling condition bits (such that if bit 1 is set, GPU1 is throttling).

---
 drivers/hwmon/occ/sysfs.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
drivers/hwmon/occ/sysfs.c +24 -0
index 88f655887c95..b2f788a77746 100644
@@ -19,6 +19,8 @@
 #define OCC_EXT_STAT_DVFS_POWER		BIT(6)
 #define OCC_EXT_STAT_MEM_THROTTLE	BIT(5)
 #define OCC_EXT_STAT_QUICK_DROP		BIT(4)
+#define OCC_EXT_STAT_DVFS_VDD		BIT(3)
+#define OCC_EXT_STAT_GPU_THROTTLE	GENMASK(2, 0)
 
 static ssize_t occ_sysfs_show(struct device *dev,
 			      struct device_attribute *attr, char *buf)
@@ -69,6 +71,12 @@ static ssize_t occ_sysfs_show(struct device *dev,
 	case 9:
 		val = header->mode;
 		break;
+	case 10:
+		val = !!(header->ext_status & OCC_EXT_STAT_DVFS_VDD);
+		break;
+	case 11:
+		val = header->ext_status & OCC_EXT_STAT_GPU_THROTTLE;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -96,6 +104,8 @@ static SENSOR_DEVICE_ATTR(occ_state, 0444, occ_sysfs_show, NULL, 6);
 static SENSOR_DEVICE_ATTR(occs_present, 0444, occ_sysfs_show, NULL, 7);
 static SENSOR_DEVICE_ATTR(occ_ips_status, 0444, occ_sysfs_show, NULL, 8);
 static SENSOR_DEVICE_ATTR(occ_mode, 0444, occ_sysfs_show, NULL, 9);
+static SENSOR_DEVICE_ATTR(occ_dvfs_vdd, 0444, occ_sysfs_show, NULL, 10);
+static SENSOR_DEVICE_ATTR(occ_gpu_throttle, 0444, occ_sysfs_show, NULL, 11);
 static DEVICE_ATTR_RO(occ_error);
 
 static struct attribute *occ_attributes[] = {
@@ -109,6 +119,8 @@ static struct attribute *occ_attributes[] = {
 	&sensor_dev_attr_occs_present.dev_attr.attr,
 	&sensor_dev_attr_occ_ips_status.dev_attr.attr,
 	&sensor_dev_attr_occ_mode.dev_attr.attr,
+	&sensor_dev_attr_occ_dvfs_vdd.dev_attr.attr,
+	&sensor_dev_attr_occ_gpu_throttle.dev_attr.attr,
 	&dev_attr_occ_error.attr,
 	NULL
 };
@@ -166,6 +178,18 @@ void occ_sysfs_poll_done(struct occ *occ)
 		sysfs_notify(&occ->bus_dev->kobj, NULL, name);
 	}
 
+	if ((header->ext_status & OCC_EXT_STAT_DVFS_VDD) !=
+	    (occ->prev_ext_stat & OCC_EXT_STAT_DVFS_VDD)) {
+		name = sensor_dev_attr_occ_dvfs_vdd.dev_attr.attr.name;
+		sysfs_notify(&occ->bus_dev->kobj, NULL, name);
+	}
+
+	if ((header->ext_status & OCC_EXT_STAT_GPU_THROTTLE) !=
+	    (occ->prev_ext_stat & OCC_EXT_STAT_GPU_THROTTLE)) {
+		name = sensor_dev_attr_occ_gpu_throttle.dev_attr.attr.name;
+		sysfs_notify(&occ->bus_dev->kobj, NULL, name);
+	}
+
 	if ((header->status & OCC_STAT_MASTER) &&
 	    header->occs_present != occ->prev_occs_present) {
 		name = sensor_dev_attr_occs_present.dev_attr.attr.name;
Signature · 1 line
2.27.0
Reviewed-by on v1 3/4
#8 lore raw

Re: [PATCH 3/4] hwmon: (occ) Add sysfs entries for additional extended status bits

Quoted 6 lines · Eddie James

Add sysfs entries for DVFS due to a VRM Vdd over-temperature condition, and add the GPU throttling condition bits (such that if bit 1 is set, GPU1 is throttling).

Quoted 70 lines
---
 drivers/hwmon/occ/sysfs.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
drivers/hwmon/occ/sysfs.c +24 -1
index 88f655887c95..b2f788a77746 100644
@@ -19,6 +19,8 @@
 #define OCC_EXT_STAT_DVFS_POWER                BIT(6)
 #define OCC_EXT_STAT_MEM_THROTTLE      BIT(5)
 #define OCC_EXT_STAT_QUICK_DROP                BIT(4)
+#define OCC_EXT_STAT_DVFS_VDD          BIT(3)
+#define OCC_EXT_STAT_GPU_THROTTLE      GENMASK(2, 0)
 
 static ssize_t occ_sysfs_show(struct device *dev,
                              struct device_attribute *attr, char *buf)
@@ -69,6 +71,12 @@ static ssize_t occ_sysfs_show(struct device *dev,
        case 9:
                val = header->mode;
                break;
+       case 10:
+               val = !!(header->ext_status & OCC_EXT_STAT_DVFS_VDD);
+               break;
+       case 11:
+               val = header->ext_status & OCC_EXT_STAT_GPU_THROTTLE;
+               break;
        default:
                return -EINVAL;
        }
@@ -96,6 +104,8 @@ static SENSOR_DEVICE_ATTR(occ_state, 0444, occ_sysfs_show, NULL, 6);
 static SENSOR_DEVICE_ATTR(occs_present, 0444, occ_sysfs_show, NULL, 7);
 static SENSOR_DEVICE_ATTR(occ_ips_status, 0444, occ_sysfs_show, NULL, 8);
 static SENSOR_DEVICE_ATTR(occ_mode, 0444, occ_sysfs_show, NULL, 9);
+static SENSOR_DEVICE_ATTR(occ_dvfs_vdd, 0444, occ_sysfs_show, NULL, 10);
+static SENSOR_DEVICE_ATTR(occ_gpu_throttle, 0444, occ_sysfs_show, NULL, 11);
 static DEVICE_ATTR_RO(occ_error);
 
 static struct attribute *occ_attributes[] = {
@@ -109,6 +119,8 @@ static struct attribute *occ_attributes[] = {
        &sensor_dev_attr_occs_present.dev_attr.attr,
        &sensor_dev_attr_occ_ips_status.dev_attr.attr,
        &sensor_dev_attr_occ_mode.dev_attr.attr,
+       &sensor_dev_attr_occ_dvfs_vdd.dev_attr.attr,
+       &sensor_dev_attr_occ_gpu_throttle.dev_attr.attr,
        &dev_attr_occ_error.attr,
        NULL
 };
@@ -166,6 +178,18 @@ void occ_sysfs_poll_done(struct occ *occ)
                sysfs_notify(&occ->bus_dev->kobj, NULL, name);
        }
 
+       if ((header->ext_status & OCC_EXT_STAT_DVFS_VDD) !=
+           (occ->prev_ext_stat & OCC_EXT_STAT_DVFS_VDD)) {
+               name = sensor_dev_attr_occ_dvfs_vdd.dev_attr.attr.name;
+               sysfs_notify(&occ->bus_dev->kobj, NULL, name);
+       }
+
+       if ((header->ext_status & OCC_EXT_STAT_GPU_THROTTLE) !=
+           (occ->prev_ext_stat & OCC_EXT_STAT_GPU_THROTTLE)) {
+               name = sensor_dev_attr_occ_gpu_throttle.dev_attr.attr.name;
+               sysfs_notify(&occ->bus_dev->kobj, NULL, name);
+       }
+
        if ((header->status & OCC_STAT_MASTER) &&
            header->occs_present != occ->prev_occs_present) {
                name = sensor_dev_attr_occs_present.dev_attr.attr.name;
--

2.27.0

maintainer Applied
#9 lore raw

Re: [PATCH 3/4] hwmon: (occ) Add sysfs entries for additional extended status bits

In reply to Eddie James
Quoted 6 lines · Eddie James

Add sysfs entries for DVFS due to a VRM Vdd over-temperature condition, and add the GPU throttling condition bits (such that if bit 1 is set, GPU1 is throttling).

Applied to hwmon-next.

Thanks,
Guenter

Quoted 67 lines
---
 drivers/hwmon/occ/sysfs.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
drivers/hwmon/occ/sysfs.c +24 -0
index 88f655887c95..b2f788a77746 100644
@@ -19,6 +19,8 @@
 #define OCC_EXT_STAT_DVFS_POWER		BIT(6)
 #define OCC_EXT_STAT_MEM_THROTTLE	BIT(5)
 #define OCC_EXT_STAT_QUICK_DROP		BIT(4)
+#define OCC_EXT_STAT_DVFS_VDD		BIT(3)
+#define OCC_EXT_STAT_GPU_THROTTLE	GENMASK(2, 0)
 
 static ssize_t occ_sysfs_show(struct device *dev,
 			      struct device_attribute *attr, char *buf)
@@ -69,6 +71,12 @@ static ssize_t occ_sysfs_show(struct device *dev,
 	case 9:
 		val = header->mode;
 		break;
+	case 10:
+		val = !!(header->ext_status & OCC_EXT_STAT_DVFS_VDD);
+		break;
+	case 11:
+		val = header->ext_status & OCC_EXT_STAT_GPU_THROTTLE;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -96,6 +104,8 @@ static SENSOR_DEVICE_ATTR(occ_state, 0444, occ_sysfs_show, NULL, 6);
 static SENSOR_DEVICE_ATTR(occs_present, 0444, occ_sysfs_show, NULL, 7);
 static SENSOR_DEVICE_ATTR(occ_ips_status, 0444, occ_sysfs_show, NULL, 8);
 static SENSOR_DEVICE_ATTR(occ_mode, 0444, occ_sysfs_show, NULL, 9);
+static SENSOR_DEVICE_ATTR(occ_dvfs_vdd, 0444, occ_sysfs_show, NULL, 10);
+static SENSOR_DEVICE_ATTR(occ_gpu_throttle, 0444, occ_sysfs_show, NULL, 11);
 static DEVICE_ATTR_RO(occ_error);
 
 static struct attribute *occ_attributes[] = {
@@ -109,6 +119,8 @@ static struct attribute *occ_attributes[] = {
 	&sensor_dev_attr_occs_present.dev_attr.attr,
 	&sensor_dev_attr_occ_ips_status.dev_attr.attr,
 	&sensor_dev_attr_occ_mode.dev_attr.attr,
+	&sensor_dev_attr_occ_dvfs_vdd.dev_attr.attr,
+	&sensor_dev_attr_occ_gpu_throttle.dev_attr.attr,
 	&dev_attr_occ_error.attr,
 	NULL
 };
@@ -166,6 +178,18 @@ void occ_sysfs_poll_done(struct occ *occ)
 		sysfs_notify(&occ->bus_dev->kobj, NULL, name);
 	}
 
+	if ((header->ext_status & OCC_EXT_STAT_DVFS_VDD) !=
+	    (occ->prev_ext_stat & OCC_EXT_STAT_DVFS_VDD)) {
+		name = sensor_dev_attr_occ_dvfs_vdd.dev_attr.attr.name;
+		sysfs_notify(&occ->bus_dev->kobj, NULL, name);
+	}
+
+	if ((header->ext_status & OCC_EXT_STAT_GPU_THROTTLE) !=
+	    (occ->prev_ext_stat & OCC_EXT_STAT_GPU_THROTTLE)) {
+		name = sensor_dev_attr_occ_gpu_throttle.dev_attr.attr.name;
+		sysfs_notify(&occ->bus_dev->kobj, NULL, name);
+	}
+
 	if ((header->status & OCC_STAT_MASTER) &&
 	    header->occs_present != occ->prev_occs_present) {
 		name = sensor_dev_attr_occs_present.dev_attr.attr.name;
#10 lore raw

PATCH 4/4 hwmon: (occ) Add soft minimum power cap attribute

In reply to Eddie James

Export the power caps data for the soft minimum power cap through hwmon.

---
 drivers/hwmon/occ/common.c | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)
drivers/hwmon/occ/common.c +16 -3
index 0cb4a0a6cbc1..f00cd59f1d19 100644
@@ -674,6 +674,9 @@ static ssize_t occ_show_caps_3(struct device *dev,
 	case 7:
 		val = caps->user_source;
 		break;
+	case 8:
+		val = get_unaligned_be16(&caps->soft_min) * 1000000ULL;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -835,12 +838,13 @@ static int occ_setup_sensor_attrs(struct occ *occ)
 	case 1:
 		num_attrs += (sensors->caps.num_sensors * 7);
 		break;
-	case 3:
-		show_caps = occ_show_caps_3;
-		fallthrough;
 	case 2:
 		num_attrs += (sensors->caps.num_sensors * 8);
 		break;
+	case 3:
+		show_caps = occ_show_caps_3;
+		num_attrs += (sensors->caps.num_sensors * 9);
+		break;
 	default:
 		sensors->caps.num_sensors = 0;
 	}
@@ -1047,6 +1051,15 @@ static int occ_setup_sensor_attrs(struct occ *occ)
 			attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
 						     show_caps, NULL, 7, 0);
 			attr++;
+
+			if (sensors->caps.version > 2) {
+				snprintf(attr->name, sizeof(attr->name),
+					 "power%d_cap_min_soft", s);
+				attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+							     show_caps, NULL,
+							     8, 0);
+				attr++;
+			}
 		}
 	}
 
Signature · 1 line
2.27.0
#11 lore raw

Re: [PATCH 4/4] hwmon: (occ) Add soft minimum power cap attribute

Quoted 25 lines · Eddie James

Export the power caps data for the soft minimum power cap through hwmon.

---
 drivers/hwmon/occ/common.c | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)
drivers/hwmon/occ/common.c +3 -0
index 0cb4a0a6cbc1..f00cd59f1d19 100644
@@ -674,6 +674,9 @@ static ssize_t occ_show_caps_3(struct device *dev,
        case 7:
                val = caps->user_source;
                break;
+       case 8:
+               val = get_unaligned_be16(&caps->soft_min) * 1000000ULL;
+               break;
        default:
                return -EINVAL;
        }
@@ -835,12 +838,13 @@ static int occ_setup_sensor_attrs(struct occ *occ)
        case 1:
                num_attrs += (sensors->caps.num_sensors * 7);

drivers/hwmon/occ/common.c static int occ_setup_sensor_attrs(struct occ *occ) · line 846

Quoted 10 lines
drivers/hwmon/occ/common.c +3 -3
                break;
-       case 3:
-               show_caps = occ_show_caps_3;
-               fallthrough;
        case 2:
                num_attrs += (sensors->caps.num_sensors * 8);
                break;
+       case 3:
+               show_caps = occ_show_caps_3;
+               num_attrs += (sensors->caps.num_sensors * 9);

How do we know this changed from 8 to 9?

We should start adding links to the occ source code, or a similar reference, when making these changes so they can be reviewed.

Quoted 23 lines
drivers/hwmon/occ/common.c +10 -1
+               break;
        default:
                sensors->caps.num_sensors = 0;
        }
@@ -1047,6 +1051,15 @@ static int occ_setup_sensor_attrs(struct occ *occ)
                        attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
                                                     show_caps, NULL, 7, 0);
                        attr++;
+
+                       if (sensors->caps.version > 2) {
+                               snprintf(attr->name, sizeof(attr->name),
+                                        "power%d_cap_min_soft", s);
+                               attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+                                                            show_caps, NULL,
+                                                            8, 0);
+                               attr++;
+                       }
                }
        }
 
--

2.27.0

#12 lore raw

Re: [PATCH 4/4] hwmon: (occ) Add soft minimum power cap attribute

Quoted 28 lines · Joel Stanley
Quoted 27 lines · Eddie James

Export the power caps data for the soft minimum power cap through hwmon.

---
  drivers/hwmon/occ/common.c | 19 ++++++++++++++++---
  1 file changed, 16 insertions(+), 3 deletions(-)
drivers/hwmon/occ/common.c +3 -2
index 0cb4a0a6cbc1..f00cd59f1d19 100644
@@ -674,6 +674,9 @@ static ssize_t occ_show_caps_3(struct device *dev,
         case 7:
                 val = caps->user_source;
                 break;
+       case 8:
+               val = get_unaligned_be16(&caps->soft_min) * 1000000ULL;
+               break;
         default:
                 return -EINVAL;
         }
@@ -835,12 +838,13 @@ static int occ_setup_sensor_attrs(struct occ *occ)
         case 1:
                 num_attrs += (sensors->caps.num_sensors * 7);
                 break;
-       case 3:
-               show_caps = occ_show_caps_3;
Quoted 8 lines

drivers/hwmon/occ/common.c static int occ_setup_sensor_attrs(struct occ *occ) · line 846

Quoted 7 lines
drivers/hwmon/occ/common.c +3 -1
-               fallthrough;
         case 2:
                 num_attrs += (sensors->caps.num_sensors * 8);
                 break;
+       case 3:
+               show_caps = occ_show_caps_3;
+               num_attrs += (sensors->caps.num_sensors * 9);

How do we know this changed from 8 to 9?

Well we made the structure change a while back when adding P10 support, but didn't bother to export the "soft min" field. Now it's needed.

Quoted 3 lines

We should start adding links to the occ source code, or a similar reference, when making these changes so they can be reviewed.

I would but it doesn't appear to be public for P10 yet... at least, no one has updated the P9 OCC spec hosted in the open-power repo: https://github.com/open-power/docs

Thanks,

Eddie

Quoted 24 lines
Quoted 24 lines
drivers/hwmon/occ/common.c +10 -1
+               break;
         default:
                 sensors->caps.num_sensors = 0;
         }
@@ -1047,6 +1051,15 @@ static int occ_setup_sensor_attrs(struct occ *occ)
                         attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
                                                      show_caps, NULL, 7, 0);
                         attr++;
+
+                       if (sensors->caps.version > 2) {
+                               snprintf(attr->name, sizeof(attr->name),
+                                        "power%d_cap_min_soft", s);
+                               attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+                                                            show_caps, NULL,
+                                                            8, 0);
+                               attr++;
+                       }
                 }
         }
 
--

2.27.0

Reviewed-by
#13 lore raw

Re: [PATCH 4/4] hwmon: (occ) Add soft minimum power cap attribute

Quoted 46 lines · Eddie James
Quoted 28 lines · Joel Stanley
Quoted 27 lines · Eddie James

Export the power caps data for the soft minimum power cap through hwmon.

---
  drivers/hwmon/occ/common.c | 19 ++++++++++++++++---
  1 file changed, 16 insertions(+), 3 deletions(-)
drivers/hwmon/occ/common.c +3 -2
index 0cb4a0a6cbc1..f00cd59f1d19 100644
@@ -674,6 +674,9 @@ static ssize_t occ_show_caps_3(struct device *dev,
         case 7:
                 val = caps->user_source;
                 break;
+       case 8:
+               val = get_unaligned_be16(&caps->soft_min) * 1000000ULL;
+               break;
         default:
                 return -EINVAL;
         }
@@ -835,12 +838,13 @@ static int occ_setup_sensor_attrs(struct occ *occ)
         case 1:
                 num_attrs += (sensors->caps.num_sensors * 7);
                 break;
-       case 3:
-               show_caps = occ_show_caps_3;
Quoted 8 lines

drivers/hwmon/occ/common.c static int occ_setup_sensor_attrs(struct occ *occ) · line 846

Quoted 7 lines
drivers/hwmon/occ/common.c +3 -1
-               fallthrough;
         case 2:
                 num_attrs += (sensors->caps.num_sensors * 8);
                 break;
+       case 3:
+               show_caps = occ_show_caps_3;
+               num_attrs += (sensors->caps.num_sensors * 9);

How do we know this changed from 8 to 9?

Well we made the structure change a while back when adding P10 support, but didn't bother to export the "soft min" field. Now it's needed.

Quoted 1 line
Quoted 7 lines
Quoted 2 lines

We should start adding links to the occ source code, or a similar reference, when making these changes so they can be reviewed.

I would but it doesn't appear to be public for P10 yet... at least, no one has updated the P9 OCC spec hosted in the open-power repo:
https://github.com/open-power/docs

Ok. Lets follow that up internally. For this patch:

Cheers,

Joel

maintainer Applied
#14 lore raw

Re: [PATCH 4/4] hwmon: (occ) Add soft minimum power cap attribute

In reply to Eddie James
Quoted 4 lines · Eddie James

Export the power caps data for the soft minimum power cap through hwmon.

Applied to hwmon-next.

Thanks,
Guenter

Quoted 51 lines
---
 drivers/hwmon/occ/common.c | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)
drivers/hwmon/occ/common.c +16 -3
index 0cb4a0a6cbc1..f00cd59f1d19 100644
@@ -674,6 +674,9 @@ static ssize_t occ_show_caps_3(struct device *dev,
 	case 7:
 		val = caps->user_source;
 		break;
+	case 8:
+		val = get_unaligned_be16(&caps->soft_min) * 1000000ULL;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -835,12 +838,13 @@ static int occ_setup_sensor_attrs(struct occ *occ)
 	case 1:
 		num_attrs += (sensors->caps.num_sensors * 7);
 		break;
-	case 3:
-		show_caps = occ_show_caps_3;
-		fallthrough;
 	case 2:
 		num_attrs += (sensors->caps.num_sensors * 8);
 		break;
+	case 3:
+		show_caps = occ_show_caps_3;
+		num_attrs += (sensors->caps.num_sensors * 9);
+		break;
 	default:
 		sensors->caps.num_sensors = 0;
 	}
@@ -1047,6 +1051,15 @@ static int occ_setup_sensor_attrs(struct occ *occ)
 			attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
 						     show_caps, NULL, 7, 0);
 			attr++;
+
+			if (sensors->caps.version > 2) {
+				snprintf(attr->name, sizeof(attr->name),
+					 "power%d_cap_min_soft", s);
+				attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
+							     show_caps, NULL,
+							     8, 0);
+				attr++;
+			}
 		}
 	}