diff options
| -rw-r--r-- | drivers/soc/qcom/rpmh.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c index 9fb25e627698..035091fd44b8 100644 --- a/drivers/soc/qcom/rpmh.c +++ b/drivers/soc/qcom/rpmh.c | |||
| @@ -80,6 +80,7 @@ void rpmh_tx_done(const struct tcs_request *msg, int r) | |||
| 80 | struct rpmh_request *rpm_msg = container_of(msg, struct rpmh_request, | 80 | struct rpmh_request *rpm_msg = container_of(msg, struct rpmh_request, |
| 81 | msg); | 81 | msg); |
| 82 | struct completion *compl = rpm_msg->completion; | 82 | struct completion *compl = rpm_msg->completion; |
| 83 | bool free = rpm_msg->needs_free; | ||
| 83 | 84 | ||
| 84 | rpm_msg->err = r; | 85 | rpm_msg->err = r; |
| 85 | 86 | ||
| @@ -94,7 +95,7 @@ void rpmh_tx_done(const struct tcs_request *msg, int r) | |||
| 94 | complete(compl); | 95 | complete(compl); |
| 95 | 96 | ||
| 96 | exit: | 97 | exit: |
| 97 | if (rpm_msg->needs_free) | 98 | if (free) |
| 98 | kfree(rpm_msg); | 99 | kfree(rpm_msg); |
| 99 | } | 100 | } |
| 100 | 101 | ||
| @@ -347,11 +348,12 @@ int rpmh_write_batch(const struct device *dev, enum rpmh_state state, | |||
| 347 | { | 348 | { |
| 348 | struct batch_cache_req *req; | 349 | struct batch_cache_req *req; |
| 349 | struct rpmh_request *rpm_msgs; | 350 | struct rpmh_request *rpm_msgs; |
| 350 | DECLARE_COMPLETION_ONSTACK(compl); | 351 | struct completion *compls; |
| 351 | struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev); | 352 | struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev); |
| 352 | unsigned long time_left; | 353 | unsigned long time_left; |
| 353 | int count = 0; | 354 | int count = 0; |
| 354 | int ret, i, j; | 355 | int ret, i; |
| 356 | void *ptr; | ||
| 355 | 357 | ||
| 356 | if (!cmd || !n) | 358 | if (!cmd || !n) |
| 357 | return -EINVAL; | 359 | return -EINVAL; |
| @@ -361,10 +363,15 @@ int rpmh_write_batch(const struct device *dev, enum rpmh_state state, | |||
| 361 | if (!count) | 363 | if (!count) |
| 362 | return -EINVAL; | 364 | return -EINVAL; |
| 363 | 365 | ||
| 364 | req = kzalloc(sizeof(*req) + count * sizeof(req->rpm_msgs[0]), | 366 | ptr = kzalloc(sizeof(*req) + |
| 367 | count * (sizeof(req->rpm_msgs[0]) + sizeof(*compls)), | ||
| 365 | GFP_ATOMIC); | 368 | GFP_ATOMIC); |
| 366 | if (!req) | 369 | if (!ptr) |
| 367 | return -ENOMEM; | 370 | return -ENOMEM; |
| 371 | |||
| 372 | req = ptr; | ||
| 373 | compls = ptr + sizeof(*req) + count * sizeof(*rpm_msgs); | ||
| 374 | |||
| 368 | req->count = count; | 375 | req->count = count; |
| 369 | rpm_msgs = req->rpm_msgs; | 376 | rpm_msgs = req->rpm_msgs; |
| 370 | 377 | ||
| @@ -379,25 +386,26 @@ int rpmh_write_batch(const struct device *dev, enum rpmh_state state, | |||
| 379 | } | 386 | } |
| 380 | 387 | ||
| 381 | for (i = 0; i < count; i++) { | 388 | for (i = 0; i < count; i++) { |
| 382 | rpm_msgs[i].completion = &compl; | 389 | struct completion *compl = &compls[i]; |
| 390 | |||
| 391 | init_completion(compl); | ||
| 392 | rpm_msgs[i].completion = compl; | ||
| 383 | ret = rpmh_rsc_send_data(ctrlr_to_drv(ctrlr), &rpm_msgs[i].msg); | 393 | ret = rpmh_rsc_send_data(ctrlr_to_drv(ctrlr), &rpm_msgs[i].msg); |
| 384 | if (ret) { | 394 | if (ret) { |
| 385 | pr_err("Error(%d) sending RPMH message addr=%#x\n", | 395 | pr_err("Error(%d) sending RPMH message addr=%#x\n", |
| 386 | ret, rpm_msgs[i].msg.cmds[0].addr); | 396 | ret, rpm_msgs[i].msg.cmds[0].addr); |
| 387 | for (j = i; j < count; j++) | ||
| 388 | rpmh_tx_done(&rpm_msgs[j].msg, ret); | ||
| 389 | break; | 397 | break; |
| 390 | } | 398 | } |
| 391 | } | 399 | } |
| 392 | 400 | ||
| 393 | time_left = RPMH_TIMEOUT_MS; | 401 | time_left = RPMH_TIMEOUT_MS; |
| 394 | for (i = 0; i < count; i++) { | 402 | while (i--) { |
| 395 | time_left = wait_for_completion_timeout(&compl, time_left); | 403 | time_left = wait_for_completion_timeout(&compls[i], time_left); |
| 396 | if (!time_left) { | 404 | if (!time_left) { |
| 397 | /* | 405 | /* |
| 398 | * Better hope they never finish because they'll signal | 406 | * Better hope they never finish because they'll signal |
| 399 | * the completion on our stack and that's bad once | 407 | * the completion that we're going to free once |
| 400 | * we've returned from the function. | 408 | * we've returned from this function. |
| 401 | */ | 409 | */ |
| 402 | WARN_ON(1); | 410 | WARN_ON(1); |
| 403 | ret = -ETIMEDOUT; | 411 | ret = -ETIMEDOUT; |
| @@ -406,7 +414,7 @@ int rpmh_write_batch(const struct device *dev, enum rpmh_state state, | |||
| 406 | } | 414 | } |
| 407 | 415 | ||
| 408 | exit: | 416 | exit: |
| 409 | kfree(req); | 417 | kfree(ptr); |
| 410 | 418 | ||
| 411 | return ret; | 419 | return ret; |
| 412 | } | 420 | } |
