@@ -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);
}
new file mode 100644
@@ -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);
@@ -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;
@@ -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;
@@ -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;
@@ -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 */
@@ -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);
@@ -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 */
@@ -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
*/
@@ -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 */
@@ -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);
@@ -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);
}
@@ -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,
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