diff options
-rw-r--r-- | core/sensor.c | 78 | ||||
-rw-r--r-- | doc/opal-api/opal-sensor-read-u64-158.rst | 16 | ||||
-rw-r--r-- | hw/dts.c | 9 | ||||
-rw-r--r-- | hw/fsp/fsp-sensor.c | 7 | ||||
-rw-r--r-- | hw/occ-sensor.c | 2 | ||||
-rw-r--r-- | include/cpu.h | 2 | ||||
-rw-r--r-- | include/dts.h | 2 | ||||
-rw-r--r-- | include/fsp.h | 2 | ||||
-rw-r--r-- | include/opal-api.h | 3 | ||||
-rw-r--r-- | include/platform.h | 2 | ||||
-rw-r--r-- | include/sensor.h | 1 | ||||
-rw-r--r-- | include/skiboot.h | 2 | ||||
-rw-r--r-- | platforms/ibm-fsp/common.c | 2 | ||||
-rw-r--r-- | platforms/ibm-fsp/ibm-fsp.h | 2 |
14 files changed, 112 insertions, 18 deletions
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 @@ -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 1e103cb..4a25a9b 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 bec4b03..2ec6f03 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -116,7 +116,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 0bd5f17..05fe767 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 2f81a05..d140ab2 100644 --- a/include/skiboot.h +++ b/include/skiboot.h @@ -352,7 +352,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, |