[V2,1/4] sensors: Support reading u64 sensor values

Message ID 1513322463-24801-2-git-send-email-shilpa.bhat@linux.vnet.ibm.com
State Accepted
Headers show
Series
  • sensors: occ: Add energy counter and fixes for parsing sensors
Related show

Commit Message

Shilpasri G Bhat Dec. 15, 2017, 7:21 a.m.
This patch adds support to read u64 sensor values. This also adds
changes to the core and the backend implementation code to make this
API as the base call. Host can use this new API to read sensors
upto 64bits.

This adds a list to store the pointer to the kernel u32 buffer, for
older kernels making async sensor u32 reads.

Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>
---
 core/sensor.c                             | 78 ++++++++++++++++++++++++++++++-
 doc/opal-api/opal-sensor-read-u64-158.rst | 16 +++++++
 hw/dts.c                                  |  9 ++--
 hw/fsp/fsp-sensor.c                       |  7 +--
 hw/occ-sensor.c                           |  2 +-
 include/cpu.h                             |  2 +-
 include/dts.h                             |  2 +-
 include/fsp.h                             |  2 +-
 include/opal-api.h                        |  3 +-
 include/platform.h                        |  2 +-
 include/sensor.h                          |  1 +
 include/skiboot.h                         |  2 +-
 platforms/ibm-fsp/common.c                |  2 +-
 platforms/ibm-fsp/ibm-fsp.h               |  2 +-
 14 files changed, 112 insertions(+), 18 deletions(-)
 create mode 100644 doc/opal-api/opal-sensor-read-u64-158.rst

Patch

diff --git a/core/sensor.c b/core/sensor.c
index ff72636..b128964 100644
--- a/core/sensor.c
+++ b/core/sensor.c
@@ -20,11 +20,63 @@ 
 #include <device.h>
 #include <opal.h>
 #include <dts.h>
+#include <lock.h>
 
 struct dt_node *sensor_node;
 
-static int64_t opal_sensor_read(uint32_t sensor_hndl, int token,
-		uint32_t *sensor_data)
+static struct lock async_read_list_lock = LOCK_UNLOCKED;
+static LIST_HEAD(async_read_list);
+
+struct sensor_async_read {
+	struct list_node link;
+	u64 *sensor_data64;
+	u32 *sensor_data32;
+	int token;
+};
+
+static int add_to_async_read_list(int token, u32 *data32, u64 *data64)
+{
+	struct sensor_async_read *req;
+
+	req = zalloc(sizeof(*req));
+	if (!req)
+		return OPAL_NO_MEM;
+
+	req->token = token;
+	req->sensor_data64 = data64;
+	req->sensor_data32 = data32;
+
+	lock(&async_read_list_lock);
+	list_add_tail(&async_read_list, &req->link);
+	unlock(&async_read_list_lock);
+
+	return OPAL_ASYNC_COMPLETION;
+}
+
+void check_sensor_read(int token)
+{
+	struct sensor_async_read *req = NULL;
+
+	lock(&async_read_list_lock);
+	if (list_empty(&async_read_list))
+		goto out;
+
+	list_for_each(&async_read_list, req, link) {
+		if (req->token == token)
+			break;
+	}
+	if (!req)
+		goto out;
+
+	*req->sensor_data32 = *req->sensor_data64;
+	free(req->sensor_data64);
+	list_del(&req->link);
+	free(req);
+out:
+	unlock(&async_read_list_lock);
+}
+
+static s64 opal_sensor_read_u64(u32 sensor_hndl, int token, u64 *sensor_data)
 {
 	switch (sensor_get_family(sensor_hndl)) {
 	case SENSOR_DTS:
@@ -41,6 +93,27 @@  static int64_t opal_sensor_read(uint32_t sensor_hndl, int token,
 	return OPAL_UNSUPPORTED;
 }
 
+static int64_t opal_sensor_read(uint32_t sensor_hndl, int token,
+				uint32_t *sensor_data)
+{
+	u64 *val;
+	s64 ret;
+
+	val = zalloc(sizeof(*val));
+	if (!val)
+		return OPAL_NO_MEM;
+
+	ret = opal_sensor_read_u64(sensor_hndl, token, val);
+	if (!ret) {
+		*sensor_data = *val;
+		free(val);
+	} else if (ret == OPAL_ASYNC_COMPLETION) {
+		ret = add_to_async_read_list(token, sensor_data, val);
+	}
+
+	return ret;
+}
+
 static int opal_sensor_group_clear(u32 group_hndl, int token)
 {
 	switch (sensor_get_family(group_hndl)) {
@@ -65,4 +138,5 @@  void sensor_init(void)
 	/* Register OPAL interface */
 	opal_register(OPAL_SENSOR_READ, opal_sensor_read, 3);
 	opal_register(OPAL_SENSOR_GROUP_CLEAR, opal_sensor_group_clear, 2);
+	opal_register(OPAL_SENSOR_READ_U64, opal_sensor_read_u64, 3);
 }
diff --git a/doc/opal-api/opal-sensor-read-u64-158.rst b/doc/opal-api/opal-sensor-read-u64-158.rst
new file mode 100644
index 0000000..b75bcbc
--- /dev/null
+++ b/doc/opal-api/opal-sensor-read-u64-158.rst
@@ -0,0 +1,16 @@ 
+OPAL_SENSOR_READ_U64
+====================
+
+The OPAL sensor call to read sensor data of type u64. Unlike
+opal_sensor_read which reads upto u32 this call can be used to
+read values of sensors upto 64bits. The calling conventions and
+return values are same as OPAL_SENSOR_READ.
+(ref: doc/opal-api/opal-sensor-read-88.rst)
+
+Parameters
+----------
+::
+
+	u32 sensor_handler
+	int	 token
+	u64 *sensor_data
diff --git a/hw/dts.c b/hw/dts.c
index 881d66e..ecfe847 100644
--- a/hw/dts.c
+++ b/hw/dts.c
@@ -276,14 +276,15 @@  static void dts_async_read_temp(struct timer *t __unused, void *data,
 	rc = dts_read_core_temp_p9(cpu->pir, &dts);
 	if (!rc) {
 		if (cpu->sensor_attr == SENSOR_DTS_ATTR_TEMP_MAX)
-			*(u32 *)cpu->sensor_data = dts.temp;
+			*cpu->sensor_data = dts.temp;
 		else if (cpu->sensor_attr == SENSOR_DTS_ATTR_TEMP_TRIP)
-			*(u32 *)cpu->sensor_data = dts.trip;
+			*cpu->sensor_data = dts.trip;
 	}
 
 	if (!swkup_rc)
 		dctl_clear_special_wakeup(cpu);
 
+	check_sensor_read(cpu->token);
 	rc = opal_queue_msg(OPAL_MSG_ASYNC_COMP, NULL, NULL, cpu->token, rc);
 	if (rc)
 		prerror("Failed to queue async message\n");
@@ -292,7 +293,7 @@  static void dts_async_read_temp(struct timer *t __unused, void *data,
 }
 
 static int dts_read_core_temp(u32 pir, struct dts *dts, u8 attr,
-			      int token, u32 *sensor_data)
+			      int token, u64 *sensor_data)
 {
 	struct cpu_thread *cpu;
 	int rc;
@@ -390,7 +391,7 @@  enum sensor_dts_class {
  */
 #define centaur_get_id(rid) (0x80000000 | ((rid) & 0x3ff))
 
-int64_t dts_sensor_read(u32 sensor_hndl, int token, u32 *sensor_data)
+int64_t dts_sensor_read(u32 sensor_hndl, int token, u64 *sensor_data)
 {
 	uint8_t	attr = sensor_get_attr(sensor_hndl);
 	uint32_t rid = sensor_get_rid(sensor_hndl);
diff --git a/hw/fsp/fsp-sensor.c b/hw/fsp/fsp-sensor.c
index 6363530..eff5d21 100644
--- a/hw/fsp/fsp-sensor.c
+++ b/hw/fsp/fsp-sensor.c
@@ -87,7 +87,7 @@  enum spcn_attr {
 /* Parsed sensor attributes, passed through OPAL */
 struct opal_sensor_data {
 	uint64_t	async_token;	/* Asynchronous token */
-	uint32_t	*sensor_data;	/* Kernel pointer to copy data */
+	uint64_t	*sensor_data;	/* Kernel pointer to copy data */
 	enum spcn_attr	spcn_attr;	/* Modifier attribute */
 	uint16_t	rid;		/* Sensor RID */
 	uint8_t		frc;		/* Sensor resource class */
@@ -306,8 +306,9 @@  static int fsp_sensor_process_read(struct fsp_msg *resp_msg)
 
 static void queue_msg_for_delivery(int rc, struct opal_sensor_data *attr)
 {
-	prlog(PR_INSANE, "%s: rc:%d, data:%d\n",
+	prlog(PR_INSANE, "%s: rc:%d, data:%lld\n",
 	      __func__, rc, *(attr->sensor_data));
+	check_sensor_read(attr->async_token);
 	opal_queue_msg(OPAL_MSG_ASYNC_COMP, NULL, NULL,
 			attr->async_token, rc);
 	spcn_mod_data[attr->mod_index].entry_count = 0;
@@ -512,7 +513,7 @@  static int64_t parse_sensor_id(uint32_t handler, struct opal_sensor_data *attr)
 
 
 int64_t fsp_opal_read_sensor(uint32_t sensor_hndl, int token,
-		uint32_t *sensor_data)
+		uint64_t *sensor_data)
 {
 	struct opal_sensor_data *attr;
 	int64_t rc;
diff --git a/hw/occ-sensor.c b/hw/occ-sensor.c
index cb05f7c..11a45c9 100644
--- a/hw/occ-sensor.c
+++ b/hw/occ-sensor.c
@@ -322,7 +322,7 @@  static inline u32 sensor_handler(int occ_num, int sensor_id, int attr)
 	return sensor_make_handler(SENSOR_OCC, occ_num, sensor_id, attr);
 }
 
-int occ_sensor_read(u32 handle, u32 *data)
+int occ_sensor_read(u32 handle, u64 *data)
 {
 	struct occ_sensor_data_header *hb;
 	struct occ_sensor_name *md;
diff --git a/include/cpu.h b/include/cpu.h
index 2804105..805e01b 100644
--- a/include/cpu.h
+++ b/include/cpu.h
@@ -111,7 +111,7 @@  struct cpu_thread {
 	 */
 	struct lock			dts_lock;
 	struct timer			dts_timer;
-	void				*sensor_data;
+	u64				*sensor_data;
 	u32				sensor_attr;
 	u32				token;
 	bool				dts_read_in_progress;
diff --git a/include/dts.h b/include/dts.h
index 17e2e15..30188ac 100644
--- a/include/dts.h
+++ b/include/dts.h
@@ -19,7 +19,7 @@ 
 
 #include <stdint.h>
 
-extern int64_t dts_sensor_read(u32 sensor_hndl, int token, u32 *sensor_data);
+extern int64_t dts_sensor_read(u32 sensor_hndl, int token, u64 *sensor_data);
 extern bool dts_sensor_create_nodes(struct dt_node *sensors);
 
 #endif /* __DTS_H */
diff --git a/include/fsp.h b/include/fsp.h
index c34a518..9b96d5d 100644
--- a/include/fsp.h
+++ b/include/fsp.h
@@ -822,7 +822,7 @@  extern void fsp_memory_err_init(void);
 /* Sensor */
 extern void fsp_init_sensor(void);
 extern int64_t fsp_opal_read_sensor(uint32_t sensor_hndl, int token,
-			uint32_t *sensor_data);
+			uint64_t *sensor_data);
 
 /* Diagnostic */
 extern void fsp_init_diag(void);
diff --git a/include/opal-api.h b/include/opal-api.h
index 1c1b9cc..7c7a23f 100644
--- a/include/opal-api.h
+++ b/include/opal-api.h
@@ -215,7 +215,8 @@ 
 #define OPAL_SENSOR_GROUP_CLEAR			156
 #define OPAL_PCI_SET_P2P			157
 #define OPAL_QUIESCE				158
-#define OPAL_LAST				158
+#define OPAL_SENSOR_READ_U64			159
+#define OPAL_LAST				159
 
 #define QUIESCE_HOLD			1 /* Spin all calls at entry */
 #define QUIESCE_REJECT			2 /* Fail all calls with OPAL_BUSY */
diff --git a/include/platform.h b/include/platform.h
index f3af390..e6ece27 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -183,7 +183,7 @@  struct platform {
 	 * Read a sensor value
 	 */
 	int64_t		(*sensor_read)(uint32_t sensor_hndl, int token,
-				       uint32_t *sensor_data);
+				       uint64_t *sensor_data);
 	/*
 	 * Return the heartbeat time
 	 */
diff --git a/include/sensor.h b/include/sensor.h
index 445a6bc..40b275a 100644
--- a/include/sensor.h
+++ b/include/sensor.h
@@ -63,5 +63,6 @@  enum {
 extern struct dt_node *sensor_node;
 
 extern void sensor_init(void);
+extern void check_sensor_read(int token);
 
 #endif /* __SENSOR_H */
diff --git a/include/skiboot.h b/include/skiboot.h
index db91325..298ea0d 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -328,7 +328,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_read(u32 handle, u64 *data);
 extern int occ_sensor_group_clear(u32 group_hndl, int token);
 extern void occ_add_sensor_groups(struct dt_node *sg, u32  *phandles,
 				  int nr_phandles, int chipid);
diff --git a/platforms/ibm-fsp/common.c b/platforms/ibm-fsp/common.c
index e916c39..87afbb6 100644
--- a/platforms/ibm-fsp/common.c
+++ b/platforms/ibm-fsp/common.c
@@ -230,7 +230,7 @@  int64_t ibm_fsp_cec_power_down(uint64_t request)
 }
 
 int64_t ibm_fsp_sensor_read(uint32_t sensor_hndl, int token,
-				uint32_t *sensor_data)
+				uint64_t *sensor_data)
 {
 	return fsp_opal_read_sensor(sensor_hndl, token, sensor_data);
 }
diff --git a/platforms/ibm-fsp/ibm-fsp.h b/platforms/ibm-fsp/ibm-fsp.h
index 3f6e9c5..6c19978 100644
--- a/platforms/ibm-fsp/ibm-fsp.h
+++ b/platforms/ibm-fsp/ibm-fsp.h
@@ -28,7 +28,7 @@  struct errorlog;
 extern int elog_fsp_commit(struct errorlog *buf);
 
 extern int64_t ibm_fsp_sensor_read(uint32_t sensor_hndl, int token,
-				uint32_t *sensor_data);
+				uint64_t *sensor_data);
 
 /* Apollo PCI support */
 extern void apollo_pci_setup_phb(struct phb *phb,