[Skiboot] [PATCH V8 8/8] sensors: occ: Add support to clear sensor groups

Shilpasri G Bhat shilpa.bhat at linux.vnet.ibm.com
Fri Jul 21 21:14:40 AEST 2017


Adds a generic API to clear sensor groups. OCC inband sensor groups
such as CSM, Profiler and Job Scheduler can be cleared using this API.
It will clear the min/max of all sensors belonging to OCC sensor
groups.

Signed-off-by: Shilpasri G Bhat <shilpa.bhat at linux.vnet.ibm.com>
---
 core/sensor.c                                 | 13 +++++
 doc/device-tree/ibm,opal/sensor-groups.rst    | 33 +++++++++++
 doc/opal-api/opal-sensor-groups-clear-156.rst | 42 ++++++++++++++
 hw/occ-sensor.c                               |  1 +
 hw/occ.c                                      | 81 +++++++++++++++++++++++++++
 include/opal-api.h                            |  3 +-
 include/skiboot.h                             |  2 +
 7 files changed, 174 insertions(+), 1 deletion(-)
 create mode 100644 doc/device-tree/ibm,opal/sensor-groups.rst
 create mode 100644 doc/opal-api/opal-sensor-groups-clear-156.rst

diff --git a/core/sensor.c b/core/sensor.c
index b0d3c5e..c2c8165 100644
--- a/core/sensor.c
+++ b/core/sensor.c
@@ -41,6 +41,18 @@ static int64_t opal_sensor_read(uint32_t sensor_hndl, int token,
 	return OPAL_UNSUPPORTED;
 }
 
+static int opal_sensor_groups_clear(u32 group_hndl, int token)
+{
+	switch (sensor_get_family(group_hndl)) {
+	case SENSOR_OCC:
+		return occ_sensor_groups_clear(group_hndl, token);
+	default:
+		break;
+	}
+
+	return OPAL_UNSUPPORTED;
+}
+
 void sensor_init(void)
 {
 	sensor_node = dt_new(opal_node, "sensors");
@@ -50,4 +62,5 @@ void sensor_init(void)
 
 	/* Register OPAL interface */
 	opal_register(OPAL_SENSOR_READ, opal_sensor_read, 3);
+	opal_register(OPAL_SENSOR_GROUPS_CLEAR, opal_sensor_groups_clear, 2);
 }
diff --git a/doc/device-tree/ibm,opal/sensor-groups.rst b/doc/device-tree/ibm,opal/sensor-groups.rst
new file mode 100644
index 0000000..21fe4c4
--- /dev/null
+++ b/doc/device-tree/ibm,opal/sensor-groups.rst
@@ -0,0 +1,33 @@
+ibm,opal/sensor-groups
+----------------------
+
+This node contains all sensor groups defined in the system.
+Each child node here represents a sensor group.
+
+For example : ::
+        occ-csm at 1c00020/
+
+Each child node has below properties:
+
+`type`
+  string to indicate the sensor group
+
+`sensor-group-id`
+  Uniquely identifies a sensor group.
+
+`ibm,chip-id`
+  This property is added if the sensor group is chip specific
+
+.. code-block:: dts
+
+   ibm,opal {
+     sensor-groups {
+
+        occ-csm at 1c00020 {
+                name = "occ-csm"
+                type = "csm"
+                sensor-group-id = <0x01c00020>
+                ibm,chip-id = <0x00000008>
+        };
+     };
+    };
diff --git a/doc/opal-api/opal-sensor-groups-clear-156.rst b/doc/opal-api/opal-sensor-groups-clear-156.rst
new file mode 100644
index 0000000..031cf8a
--- /dev/null
+++ b/doc/opal-api/opal-sensor-groups-clear-156.rst
@@ -0,0 +1,42 @@
+.. _opal-sensor-groups-clear:
+
+OPAL_SENSOR_GROUPS_CLEAR
+==============================
+OPAL call to clear the sensor groups data using a handle to identify
+the type of sensor group which is exported via DT.
+
+The call can be asynchronus, where the token parameter is used to wait
+for the completion.
+
+Parameters
+----------
+::
+        u32 handle
+        int token
+
+Returns
+-------
+OPAL_SUCCESS
+  Success
+
+OPAL_UNSUPPORTED
+  No support for clearing the sensor group
+
+OPAL_HARDWARE
+  Unable to procced due to the current hardware state
+
+OPAL_PERMISSION
+  Hardware cannot take the request
+
+OPAL_ASYNC_COMPLETION
+  Request was sent and an async completion message will be sent with
+  token and status of the request.
+
+OPAL_BUSY
+  Previous request in progress
+
+OPAL_INTERNAL_ERROR
+  Error in request response
+
+OPAL_TIMEOUT
+  Timeout in request completion
diff --git a/hw/occ-sensor.c b/hw/occ-sensor.c
index 15b6031..bf9f3f4 100644
--- a/hw/occ-sensor.c
+++ b/hw/occ-sensor.c
@@ -610,4 +610,5 @@ void occ_sensors_init(void)
 		}
 		occ_num++;
 	}
+	occ_add_sensor_groups();
 }
diff --git a/hw/occ.c b/hw/occ.c
index 162b453..c88e914 100644
--- a/hw/occ.c
+++ b/hw/occ.c
@@ -30,6 +30,7 @@
 #include <i2c.h>
 #include <powercap.h>
 #include <psr.h>
+#include <sensor.h>
 
 /* OCC Communication Area for PStates */
 
@@ -1455,6 +1456,86 @@ static void occ_add_psr_sensors(struct dt_node *power_mgt)
 	}
 }
 
+/* OCC clear sensor limits CSM/Profiler/Job-scheduler */
+
+enum occ_sensor_limit_group {
+	OCC_SENSOR_LIMIT_GROUP_CSM		= 0x10,
+	OCC_SENSOR_LIMIT_GROUP_PROFILER		= 0x20,
+	OCC_SENSOR_LIMIT_GROUP_JOB_SCHED	= 0x40,
+};
+
+static u32 sensor_limit;
+static struct opal_occ_cmd_data slimit_data = {
+	.data		= (u8 *)&sensor_limit,
+	.cmd		= OCC_CMD_CLEAR_SENSOR_DATA,
+};
+
+int occ_sensor_groups_clear(u32 group_hndl, int token)
+{
+	u32 limit = sensor_get_rid(group_hndl);
+	u8 i = sensor_get_attr(group_hndl);
+
+	if (i > nr_occs)
+		return OPAL_UNSUPPORTED;
+
+	switch (limit) {
+	case OCC_SENSOR_LIMIT_GROUP_CSM:
+	case OCC_SENSOR_LIMIT_GROUP_PROFILER:
+	case OCC_SENSOR_LIMIT_GROUP_JOB_SCHED:
+		break;
+	default:
+		return OPAL_UNSUPPORTED;
+	}
+
+	if (!(*chips[i].valid))
+		return OPAL_HARDWARE;
+
+	sensor_limit = limit << 24;
+	return opal_occ_command(&chips[i], token, &slimit_data);
+}
+
+void occ_add_sensor_groups(void)
+{
+	struct dt_node *sg;
+	struct limit_group_info {
+		int limit;
+		const char *str;
+	} limits[] = {
+		{ OCC_SENSOR_LIMIT_GROUP_CSM, "csm" },
+		{ OCC_SENSOR_LIMIT_GROUP_PROFILER, "profiler" },
+		{ OCC_SENSOR_LIMIT_GROUP_JOB_SCHED, "js" },
+	};
+	int i, j;
+
+	sg = dt_new(opal_node, "sensor-groups");
+	if (!sg) {
+		prerror("OCC: Failed to create sensor groups node\n");
+		return;
+	}
+	dt_add_property_string(sg, "compatible", "ibm,opal-occ-sensor-group");
+
+	for (i = 0; i < nr_occs; i++)
+		for (j = 0; j < ARRAY_SIZE(limits); j++) {
+			struct dt_node *node;
+			char name[20];
+			u32 handle;
+
+			snprintf(name, 20, "occ-%s", limits[j].str);
+			handle = sensor_make_handler(SENSOR_OCC, 0,
+						     limits[j].limit, i);
+			node = dt_new_addr(sg, name, handle);
+			if (!node) {
+				prerror("Failed to create sensor group nodes\n");
+				return;
+			}
+
+			dt_add_property_cells(node, "sensor-group-id", handle);
+			dt_add_property_string(node, "type", limits[j].str);
+			dt_add_property_cells(node, "ibm,chip-id",
+					      chips[i].chip_id);
+		}
+}
+
 /* CPU-OCC PState init */
 /* Called after OCC init on P8 and P9 */
 void occ_pstates_init(void)
diff --git a/include/opal-api.h b/include/opal-api.h
index 2717a0d..ae26edd 100644
--- a/include/opal-api.h
+++ b/include/opal-api.h
@@ -212,7 +212,8 @@
 #define OPAL_SET_POWERCAP			153
 #define OPAL_GET_PSR				154
 #define OPAL_SET_PSR				155
-#define OPAL_LAST				155
+#define OPAL_SENSOR_GROUPS_CLEAR		156
+#define OPAL_LAST				156
 
 /* Device tree flags */
 
diff --git a/include/skiboot.h b/include/skiboot.h
index db4ca36..bed2ce7 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -313,5 +313,7 @@ extern int fake_nvram_write(uint32_t offset, void *src, uint32_t size);
 /* OCC Inband Sensors */
 extern void occ_sensors_init(void);
 extern int occ_sensor_read(u32 handle, u32 *data);
+extern int occ_sensor_groups_clear(u32 group_hndl, int token);
+extern void occ_add_sensor_groups(void);
 
 #endif /* __SKIBOOT_H */
-- 
1.8.3.1



More information about the Skiboot mailing list