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

firmware: arm_scmi: Add SCMI v3.1 SENSOR_AXIS_NAME_GET support

Add support for SCMI v3.1 SENSOR_AXIS_NAME_GET multi-part command using the
common iterator protocol helpers.

Link: https://lore.kernel.org/r/20220330150551.2573938-16-cristian.marussi@arm.com
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>

authored by

Cristian Marussi and committed by
Sudeep Holla
802b0bed 7cab5377

+77 -7
+77 -7
drivers/firmware/arm_scmi/sensors.c
··· 28 28 SENSOR_CONFIG_SET = 0xA, 29 29 SENSOR_CONTINUOUS_UPDATE_NOTIFY = 0xB, 30 30 SENSOR_NAME_GET = 0xC, 31 + SENSOR_AXIS_NAME_GET = 0xD, 31 32 }; 32 33 33 34 struct scmi_msg_resp_sensor_attributes { ··· 118 117 struct scmi_axis_descriptor { 119 118 __le32 id; 120 119 __le32 attributes_low; 120 + #define SUPPORTS_EXTENDED_AXIS_NAMES(x) FIELD_GET(BIT(9), (x)) 121 121 __le32 attributes_high; 122 - u8 name[SCMI_MAX_STR_SIZE]; 122 + u8 name[SCMI_SHORT_NAME_MAX_SIZE]; 123 123 __le32 resolution; 124 124 struct scmi_msg_resp_attrs attrs; 125 + } desc[]; 126 + }; 127 + 128 + struct scmi_msg_resp_sensor_axis_names_description { 129 + __le32 num_axis_flags; 130 + struct scmi_sensor_axis_name_descriptor { 131 + __le32 axis_id; 132 + u8 name[SCMI_MAX_STR_SIZE]; 125 133 } desc[]; 126 134 }; 127 135 ··· 403 393 a->extended_attrs = SUPPORTS_EXTEND_ATTRS(attrl); 404 394 405 395 attrh = le32_to_cpu(adesc->attributes_high); 406 - 407 396 a->scale = S32_EXT(SENSOR_SCALE(attrh)); 408 397 a->type = SENSOR_TYPE(attrh); 409 398 strscpy(a->name, adesc->name, SCMI_MAX_STR_SIZE); ··· 417 408 scmi_parse_range_attrs(&a->attrs, &adesc->attrs); 418 409 dsize += sizeof(adesc->attrs); 419 410 } 420 - 421 411 st->priv = ((u8 *)adesc + dsize); 422 412 423 413 return 0; 424 414 } 425 415 426 - static int scmi_sensor_axis_description(const struct scmi_protocol_handle *ph, 427 - struct scmi_sensor_info *s) 416 + static int 417 + iter_axes_extended_name_update_state(struct scmi_iterator_state *st, 418 + const void *response, void *priv) 428 419 { 420 + u32 flags; 421 + const struct scmi_msg_resp_sensor_axis_names_description *r = response; 422 + 423 + flags = le32_to_cpu(r->num_axis_flags); 424 + st->num_returned = NUM_AXIS_RETURNED(flags); 425 + st->num_remaining = NUM_AXIS_REMAINING(flags); 426 + st->priv = (void *)&r->desc[0]; 427 + 428 + return 0; 429 + } 430 + 431 + static int 432 + iter_axes_extended_name_process_response(const struct scmi_protocol_handle *ph, 433 + const void *response, 434 + struct scmi_iterator_state *st, 435 + void *priv) 436 + { 437 + struct scmi_sensor_axis_info *a; 438 + const struct scmi_sensor_info *s = priv; 439 + struct scmi_sensor_axis_name_descriptor *adesc = st->priv; 440 + 441 + a = &s->axis[st->desc_index + st->loop_idx]; 442 + strscpy(a->name, adesc->name, SCMI_MAX_STR_SIZE); 443 + st->priv = ++adesc; 444 + 445 + return 0; 446 + } 447 + 448 + static int 449 + scmi_sensor_axis_extended_names_get(const struct scmi_protocol_handle *ph, 450 + struct scmi_sensor_info *s) 451 + { 452 + void *iter; 453 + struct scmi_msg_sensor_axis_description_get *msg; 454 + struct scmi_iterator_ops ops = { 455 + .prepare_message = iter_axes_desc_prepare_message, 456 + .update_state = iter_axes_extended_name_update_state, 457 + .process_response = iter_axes_extended_name_process_response, 458 + }; 459 + 460 + iter = ph->hops->iter_response_init(ph, &ops, s->num_axis, 461 + SENSOR_AXIS_NAME_GET, 462 + sizeof(*msg), s); 463 + if (IS_ERR(iter)) 464 + return PTR_ERR(iter); 465 + 466 + return ph->hops->iter_response_run(iter); 467 + } 468 + 469 + static int scmi_sensor_axis_description(const struct scmi_protocol_handle *ph, 470 + struct scmi_sensor_info *s, 471 + u32 version) 472 + { 473 + int ret; 429 474 void *iter; 430 475 struct scmi_msg_sensor_axis_description_get *msg; 431 476 struct scmi_iterator_ops ops = { ··· 499 436 if (IS_ERR(iter)) 500 437 return PTR_ERR(iter); 501 438 502 - return ph->hops->iter_response_run(iter); 439 + ret = ph->hops->iter_response_run(iter); 440 + if (ret) 441 + return ret; 442 + 443 + if (PROTOCOL_REV_MAJOR(version) >= 0x3) 444 + ret = scmi_sensor_axis_extended_names_get(ph, s); 445 + 446 + return ret; 503 447 } 504 448 505 449 static void iter_sens_descr_prepare_message(void *message, ··· 629 559 } 630 560 631 561 if (s->num_axis > 0) 632 - ret = scmi_sensor_axis_description(ph, s); 562 + ret = scmi_sensor_axis_description(ph, s, si->version); 633 563 634 564 st->priv = ((u8 *)sdesc + dsize); 635 565