diff options
author | Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com> | 2017-12-15 12:51:00 +0530 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2018-02-21 11:58:19 +1100 |
commit | fa3494602a3e3effe9f222193453d67ccc0c0606 (patch) | |
tree | 730c36fc14fb245578927ca98f11287a16833cde /core | |
parent | 7f4c8e8ce0b78ca046643d7f4f63d81f4fd11746 (diff) | |
download | talos-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.c | 78 |
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); } |