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

Merge tag 'scmi-updates-4.20' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into next/drivers

SCMI updates for v4.20

1. Addition of interface to fetch estimated power from the firmware
corresponding to each OPP of a device

2. Cleanup using strlcpy to ensure NULL-terminated strings for name
strings instead of relying on the firmware to do the same

* tag 'scmi-updates-4.20' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux:
firmware: arm_scmi: add a getter for power of performance states
firmware: arm_scmi: use strlcpy to ensure NULL-terminated strings

Signed-off-by: Olof Johansson <olof@lixom.net>

+37 -5
+1 -1
drivers/firmware/arm_scmi/base.c
··· 208 208 209 209 ret = scmi_do_xfer(handle, t); 210 210 if (!ret) 211 - memcpy(name, t->rx.buf, SCMI_MAX_STR_SIZE); 211 + strlcpy(name, t->rx.buf, SCMI_MAX_STR_SIZE); 212 212 213 213 scmi_xfer_put(handle, t); 214 214
+1 -1
drivers/firmware/arm_scmi/clock.c
··· 111 111 112 112 ret = scmi_do_xfer(handle, t); 113 113 if (!ret) 114 - memcpy(clk->name, attr->name, SCMI_MAX_STR_SIZE); 114 + strlcpy(clk->name, attr->name, SCMI_MAX_STR_SIZE); 115 115 else 116 116 clk->name[0] = '\0'; 117 117
+29 -1
drivers/firmware/arm_scmi/perf.c
··· 174 174 dom_info->mult_factor = 175 175 (dom_info->sustained_freq_khz * 1000) / 176 176 dom_info->sustained_perf_level; 177 - memcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE); 177 + strlcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE); 178 178 } 179 179 180 180 scmi_xfer_put(handle, t); ··· 427 427 return ret; 428 428 } 429 429 430 + static int scmi_dvfs_est_power_get(const struct scmi_handle *handle, u32 domain, 431 + unsigned long *freq, unsigned long *power) 432 + { 433 + struct scmi_perf_info *pi = handle->perf_priv; 434 + struct perf_dom_info *dom; 435 + unsigned long opp_freq; 436 + int idx, ret = -EINVAL; 437 + struct scmi_opp *opp; 438 + 439 + dom = pi->dom_info + domain; 440 + if (!dom) 441 + return -EIO; 442 + 443 + for (opp = dom->opp, idx = 0; idx < dom->opp_count; idx++, opp++) { 444 + opp_freq = opp->perf * dom->mult_factor; 445 + if (opp_freq < *freq) 446 + continue; 447 + 448 + *freq = opp_freq; 449 + *power = opp->power; 450 + ret = 0; 451 + break; 452 + } 453 + 454 + return ret; 455 + } 456 + 430 457 static struct scmi_perf_ops perf_ops = { 431 458 .limits_set = scmi_perf_limits_set, 432 459 .limits_get = scmi_perf_limits_get, ··· 464 437 .device_opps_add = scmi_dvfs_device_opps_add, 465 438 .freq_set = scmi_dvfs_freq_set, 466 439 .freq_get = scmi_dvfs_freq_get, 440 + .est_power_get = scmi_dvfs_est_power_get, 467 441 }; 468 442 469 443 static int scmi_perf_protocol_init(struct scmi_handle *handle)
+1 -1
drivers/firmware/arm_scmi/power.c
··· 106 106 dom_info->state_set_notify = SUPPORTS_STATE_SET_NOTIFY(flags); 107 107 dom_info->state_set_async = SUPPORTS_STATE_SET_ASYNC(flags); 108 108 dom_info->state_set_sync = SUPPORTS_STATE_SET_SYNC(flags); 109 - memcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE); 109 + strlcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE); 110 110 } 111 111 112 112 scmi_xfer_put(handle, t);
+1 -1
drivers/firmware/arm_scmi/sensors.c
··· 140 140 s = &si->sensors[desc_index + cnt]; 141 141 s->id = le32_to_cpu(buf->desc[cnt].id); 142 142 s->type = SENSOR_TYPE(attrh); 143 - memcpy(s->name, buf->desc[cnt].name, SCMI_MAX_STR_SIZE); 143 + strlcpy(s->name, buf->desc[cnt].name, SCMI_MAX_STR_SIZE); 144 144 } 145 145 146 146 desc_index += num_returned;
+4
include/linux/scmi_protocol.h
··· 91 91 * to sustained performance level mapping 92 92 * @freq_get: gets the frequency for a given device using sustained frequency 93 93 * to sustained performance level mapping 94 + * @est_power_get: gets the estimated power cost for a given performance domain 95 + * at a given frequency 94 96 */ 95 97 struct scmi_perf_ops { 96 98 int (*limits_set)(const struct scmi_handle *handle, u32 domain, ··· 112 110 unsigned long rate, bool poll); 113 111 int (*freq_get)(const struct scmi_handle *handle, u32 domain, 114 112 unsigned long *rate, bool poll); 113 + int (*est_power_get)(const struct scmi_handle *handle, u32 domain, 114 + unsigned long *rate, unsigned long *power); 115 115 }; 116 116 117 117 /**