summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorShilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>2017-12-15 12:51:00 +0530
committerStewart Smith <stewart@linux.vnet.ibm.com>2018-02-21 11:58:19 +1100
commitfa3494602a3e3effe9f222193453d67ccc0c0606 (patch)
tree730c36fc14fb245578927ca98f11287a16833cde /core
parent7f4c8e8ce0b78ca046643d7f4f63d81f4fd11746 (diff)
downloadtalos-skiboot-fa3494602a3e3effe9f222193453d67ccc0c0606.tar.gz
talos-skiboot-fa3494602a3e3effe9f222193453d67ccc0c0606.zip
sensors: Support reading u64 sensor values
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> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core')
-rw-r--r--core/sensor.c78
1 files changed, 76 insertions, 2 deletions
diff --git a/core/sensor.c b/core/sensor.c
index ff726365..b1289648 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);
}
OpenPOWER on IntegriCloud