Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

firmware: arm_scmi: Add asynchronous sensor read if it supports

SENSOR_DESCRIPTION_GET provides attributes to indicate if the sensor
supports asynchronous read. We can read that flag and use asynchronous
reads for any sensors with that attribute set.

Let's use the new scmi_do_xfer_with_response to support asynchronous
sensor reads.

Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>

+24 -8
+22 -8
drivers/firmware/arm_scmi/sensors.c
··· 136 136 } 137 137 138 138 for (cnt = 0; cnt < num_returned; cnt++) { 139 - u32 attrh; 139 + u32 attrh, attrl; 140 140 struct scmi_sensor_info *s; 141 141 142 + attrl = le32_to_cpu(buf->desc[cnt].attributes_low); 142 143 attrh = le32_to_cpu(buf->desc[cnt].attributes_high); 143 144 s = &si->sensors[desc_index + cnt]; 144 145 s->id = le32_to_cpu(buf->desc[cnt].id); ··· 148 147 /* Sign extend to a full s8 */ 149 148 if (s->scale & SENSOR_SCALE_SIGN) 150 149 s->scale |= SENSOR_SCALE_EXTEND; 150 + s->async = SUPPORTS_ASYNC_READ(attrl); 151 + s->num_trip_points = NUM_TRIP_POINTS(attrl); 151 152 strlcpy(s->name, buf->desc[cnt].name, SCMI_MAX_STR_SIZE); 152 153 } 153 154 ··· 217 214 u32 sensor_id, u64 *value) 218 215 { 219 216 int ret; 217 + __le32 *pval; 220 218 struct scmi_xfer *t; 221 219 struct scmi_msg_sensor_reading_get *sensor; 220 + struct sensors_info *si = handle->sensor_priv; 221 + struct scmi_sensor_info *s = si->sensors + sensor_id; 222 222 223 223 ret = scmi_xfer_get_init(handle, SENSOR_READING_GET, 224 224 SCMI_PROTOCOL_SENSOR, sizeof(*sensor), ··· 229 223 if (ret) 230 224 return ret; 231 225 226 + pval = t->rx.buf; 232 227 sensor = t->tx.buf; 233 228 sensor->id = cpu_to_le32(sensor_id); 234 - sensor->flags = cpu_to_le32(0); 235 229 236 - ret = scmi_do_xfer(handle, t); 237 - if (!ret) { 238 - __le32 *pval = t->rx.buf; 239 - 240 - *value = le32_to_cpu(*pval); 241 - *value |= (u64)le32_to_cpu(*(pval + 1)) << 32; 230 + if (s->async) { 231 + sensor->flags = cpu_to_le32(SENSOR_READ_ASYNC); 232 + ret = scmi_do_xfer_with_response(handle, t); 233 + if (!ret) { 234 + *value = le32_to_cpu(*(pval + 1)); 235 + *value |= (u64)le32_to_cpu(*(pval + 2)) << 32; 236 + } 237 + } else { 238 + sensor->flags = cpu_to_le32(0); 239 + ret = scmi_do_xfer(handle, t); 240 + if (!ret) { 241 + *value = le32_to_cpu(*pval); 242 + *value |= (u64)le32_to_cpu(*(pval + 1)) << 32; 243 + } 242 244 } 243 245 244 246 scmi_xfer_put(handle, t);
+2
include/linux/scmi_protocol.h
··· 145 145 u32 id; 146 146 u8 type; 147 147 s8 scale; 148 + u8 num_trip_points; 149 + bool async; 148 150 char name[SCMI_MAX_STR_SIZE]; 149 151 }; 150 152