diff options
author | Olof Johansson <olof@lixom.net> | 2018-09-25 14:31:00 -0400 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2018-09-25 14:31:00 -0400 |
commit | 5bc45db5d2a7bf6eac577174e3634f58f867bb2f (patch) | |
tree | aed32922648353b536f6a919f1f584d430b12e0e | |
parent | cdddeefc39cc26b2d429f8f7ea3c35bf8cb8c6a1 (diff) | |
parent | 1a63fe9a2b1f47af5b2b7436b41824b14999c17a (diff) |
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>
-rw-r--r-- | drivers/firmware/arm_scmi/base.c | 2 | ||||
-rw-r--r-- | drivers/firmware/arm_scmi/clock.c | 2 | ||||
-rw-r--r-- | drivers/firmware/arm_scmi/perf.c | 30 | ||||
-rw-r--r-- | drivers/firmware/arm_scmi/power.c | 2 | ||||
-rw-r--r-- | drivers/firmware/arm_scmi/sensors.c | 2 | ||||
-rw-r--r-- | include/linux/scmi_protocol.h | 4 |
6 files changed, 37 insertions, 5 deletions
diff --git a/drivers/firmware/arm_scmi/base.c b/drivers/firmware/arm_scmi/base.c index 9dff33ea6416..204390297f4b 100644 --- a/drivers/firmware/arm_scmi/base.c +++ b/drivers/firmware/arm_scmi/base.c | |||
@@ -208,7 +208,7 @@ static int scmi_base_discover_agent_get(const struct scmi_handle *handle, | |||
208 | 208 | ||
209 | ret = scmi_do_xfer(handle, t); | 209 | ret = scmi_do_xfer(handle, t); |
210 | if (!ret) | 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 | scmi_xfer_put(handle, t); | 213 | scmi_xfer_put(handle, t); |
214 | 214 | ||
diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c index e4119eb34986..30fc04e28431 100644 --- a/drivers/firmware/arm_scmi/clock.c +++ b/drivers/firmware/arm_scmi/clock.c | |||
@@ -111,7 +111,7 @@ static int scmi_clock_attributes_get(const struct scmi_handle *handle, | |||
111 | 111 | ||
112 | ret = scmi_do_xfer(handle, t); | 112 | ret = scmi_do_xfer(handle, t); |
113 | if (!ret) | 113 | if (!ret) |
114 | memcpy(clk->name, attr->name, SCMI_MAX_STR_SIZE); | 114 | strlcpy(clk->name, attr->name, SCMI_MAX_STR_SIZE); |
115 | else | 115 | else |
116 | clk->name[0] = '\0'; | 116 | clk->name[0] = '\0'; |
117 | 117 | ||
diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c index 64342944d917..3c8ae7cc35de 100644 --- a/drivers/firmware/arm_scmi/perf.c +++ b/drivers/firmware/arm_scmi/perf.c | |||
@@ -174,7 +174,7 @@ scmi_perf_domain_attributes_get(const struct scmi_handle *handle, u32 domain, | |||
174 | dom_info->mult_factor = | 174 | dom_info->mult_factor = |
175 | (dom_info->sustained_freq_khz * 1000) / | 175 | (dom_info->sustained_freq_khz * 1000) / |
176 | dom_info->sustained_perf_level; | 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 | scmi_xfer_put(handle, t); | 180 | scmi_xfer_put(handle, t); |
@@ -427,6 +427,33 @@ static int scmi_dvfs_freq_get(const struct scmi_handle *handle, u32 domain, | |||
427 | return ret; | 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 | static struct scmi_perf_ops perf_ops = { | 457 | static struct scmi_perf_ops perf_ops = { |
431 | .limits_set = scmi_perf_limits_set, | 458 | .limits_set = scmi_perf_limits_set, |
432 | .limits_get = scmi_perf_limits_get, | 459 | .limits_get = scmi_perf_limits_get, |
@@ -437,6 +464,7 @@ static struct scmi_perf_ops perf_ops = { | |||
437 | .device_opps_add = scmi_dvfs_device_opps_add, | 464 | .device_opps_add = scmi_dvfs_device_opps_add, |
438 | .freq_set = scmi_dvfs_freq_set, | 465 | .freq_set = scmi_dvfs_freq_set, |
439 | .freq_get = scmi_dvfs_freq_get, | 466 | .freq_get = scmi_dvfs_freq_get, |
467 | .est_power_get = scmi_dvfs_est_power_get, | ||
440 | }; | 468 | }; |
441 | 469 | ||
442 | static int scmi_perf_protocol_init(struct scmi_handle *handle) | 470 | static int scmi_perf_protocol_init(struct scmi_handle *handle) |
diff --git a/drivers/firmware/arm_scmi/power.c b/drivers/firmware/arm_scmi/power.c index cfa033b05aed..62f3401a1f01 100644 --- a/drivers/firmware/arm_scmi/power.c +++ b/drivers/firmware/arm_scmi/power.c | |||
@@ -106,7 +106,7 @@ scmi_power_domain_attributes_get(const struct scmi_handle *handle, u32 domain, | |||
106 | dom_info->state_set_notify = SUPPORTS_STATE_SET_NOTIFY(flags); | 106 | dom_info->state_set_notify = SUPPORTS_STATE_SET_NOTIFY(flags); |
107 | dom_info->state_set_async = SUPPORTS_STATE_SET_ASYNC(flags); | 107 | dom_info->state_set_async = SUPPORTS_STATE_SET_ASYNC(flags); |
108 | dom_info->state_set_sync = SUPPORTS_STATE_SET_SYNC(flags); | 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 | scmi_xfer_put(handle, t); | 112 | scmi_xfer_put(handle, t); |
diff --git a/drivers/firmware/arm_scmi/sensors.c b/drivers/firmware/arm_scmi/sensors.c index 27f2092b9882..b53d5cc9c9f6 100644 --- a/drivers/firmware/arm_scmi/sensors.c +++ b/drivers/firmware/arm_scmi/sensors.c | |||
@@ -140,7 +140,7 @@ static int scmi_sensor_description_get(const struct scmi_handle *handle, | |||
140 | s = &si->sensors[desc_index + cnt]; | 140 | s = &si->sensors[desc_index + cnt]; |
141 | s->id = le32_to_cpu(buf->desc[cnt].id); | 141 | s->id = le32_to_cpu(buf->desc[cnt].id); |
142 | s->type = SENSOR_TYPE(attrh); | 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 | desc_index += num_returned; | 146 | desc_index += num_returned; |
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h index f4c9fc0fc755..3105055c00a7 100644 --- a/include/linux/scmi_protocol.h +++ b/include/linux/scmi_protocol.h | |||
@@ -91,6 +91,8 @@ struct scmi_clk_ops { | |||
91 | * to sustained performance level mapping | 91 | * to sustained performance level mapping |
92 | * @freq_get: gets the frequency for a given device using sustained frequency | 92 | * @freq_get: gets the frequency for a given device using sustained frequency |
93 | * to sustained performance level mapping | 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 | struct scmi_perf_ops { | 97 | struct scmi_perf_ops { |
96 | int (*limits_set)(const struct scmi_handle *handle, u32 domain, | 98 | int (*limits_set)(const struct scmi_handle *handle, u32 domain, |
@@ -110,6 +112,8 @@ struct scmi_perf_ops { | |||
110 | unsigned long rate, bool poll); | 112 | unsigned long rate, bool poll); |
111 | int (*freq_get)(const struct scmi_handle *handle, u32 domain, | 113 | int (*freq_get)(const struct scmi_handle *handle, u32 domain, |
112 | unsigned long *rate, bool poll); | 114 | unsigned long *rate, bool poll); |
115 | int (*est_power_get)(const struct scmi_handle *handle, u32 domain, | ||
116 | unsigned long *rate, unsigned long *power); | ||
113 | }; | 117 | }; |
114 | 118 | ||
115 | /** | 119 | /** |