|
34 | 34 | .cmd = { { 0 } }, \ |
35 | 35 | .completion = q, \ |
36 | 36 | .dev = dev, \ |
| 37 | + .needs_free = false, \ |
37 | 38 | } |
38 | 39 |
|
39 | 40 | #define ctrlr_to_drv(ctrlr) container_of(ctrlr, struct rsc_drv, client) |
@@ -75,6 +76,9 @@ void rpmh_tx_done(const struct tcs_request *msg, int r) |
75 | 76 | /* Signal the blocking thread we are done */ |
76 | 77 | if (compl) |
77 | 78 | complete(compl); |
| 79 | + |
| 80 | + if (rpm_msg->needs_free) |
| 81 | + kfree(rpm_msg); |
78 | 82 | } |
79 | 83 |
|
80 | 84 | static struct cache_req *__find_req(struct rpmh_ctrlr *ctrlr, u32 addr) |
@@ -180,6 +184,53 @@ static int __rpmh_write(const struct device *dev, enum rpmh_state state, |
180 | 184 | return ret; |
181 | 185 | } |
182 | 186 |
|
| 187 | +static int __fill_rpmh_msg(struct rpmh_request *req, enum rpmh_state state, |
| 188 | + const struct tcs_cmd *cmd, u32 n) |
| 189 | +{ |
| 190 | + if (!cmd || !n || n > MAX_RPMH_PAYLOAD) |
| 191 | + return -EINVAL; |
| 192 | + |
| 193 | + memcpy(req->cmd, cmd, n * sizeof(*cmd)); |
| 194 | + |
| 195 | + req->msg.state = state; |
| 196 | + req->msg.cmds = req->cmd; |
| 197 | + req->msg.num_cmds = n; |
| 198 | + |
| 199 | + return 0; |
| 200 | +} |
| 201 | + |
| 202 | +/** |
| 203 | + * rpmh_write_async: Write a set of RPMH commands |
| 204 | + * |
| 205 | + * @dev: The device making the request |
| 206 | + * @state: Active/sleep set |
| 207 | + * @cmd: The payload data |
| 208 | + * @n: The number of elements in payload |
| 209 | + * |
| 210 | + * Write a set of RPMH commands, the order of commands is maintained |
| 211 | + * and will be sent as a single shot. |
| 212 | + */ |
| 213 | +int rpmh_write_async(const struct device *dev, enum rpmh_state state, |
| 214 | + const struct tcs_cmd *cmd, u32 n) |
| 215 | +{ |
| 216 | + struct rpmh_request *rpm_msg; |
| 217 | + int ret; |
| 218 | + |
| 219 | + rpm_msg = kzalloc(sizeof(*rpm_msg), GFP_ATOMIC); |
| 220 | + if (!rpm_msg) |
| 221 | + return -ENOMEM; |
| 222 | + rpm_msg->needs_free = true; |
| 223 | + |
| 224 | + ret = __fill_rpmh_msg(rpm_msg, state, cmd, n); |
| 225 | + if (ret) { |
| 226 | + kfree(rpm_msg); |
| 227 | + return ret; |
| 228 | + } |
| 229 | + |
| 230 | + return __rpmh_write(dev, state, rpm_msg); |
| 231 | +} |
| 232 | +EXPORT_SYMBOL(rpmh_write_async); |
| 233 | + |
183 | 234 | /** |
184 | 235 | * rpmh_write: Write a set of RPMH commands and block until response |
185 | 236 | * |
|
0 commit comments