Lines Matching +full:tcs +full:- +full:wait
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
19 #include <linux/wait.h>
23 #include "rpmh-internal.h"
59 * struct batch_cache_req - An entry in our batch catch
74 struct rsc_drv *drv = dev_get_drvdata(dev->parent); in get_rpmh_ctrlr()
76 return &drv->client; in get_rpmh_ctrlr()
83 struct completion *compl = rpm_msg->completion; in rpmh_tx_done()
84 bool free = rpm_msg->needs_free; in rpmh_tx_done()
86 rpm_msg->err = r; in rpmh_tx_done()
89 dev_err(rpm_msg->dev, "RPMH TX fail in msg addr=%#x, err=%d\n", in rpmh_tx_done()
90 rpm_msg->msg.cmds[0].addr, r); in rpmh_tx_done()
107 list_for_each_entry(p, &ctrlr->cache, list) { in __find_req()
108 if (p->addr == addr) { in __find_req()
125 spin_lock_irqsave(&ctrlr->cache_lock, flags); in cache_rpm_request()
126 req = __find_req(ctrlr, cmd->addr); in cache_rpm_request()
132 req = ERR_PTR(-ENOMEM); in cache_rpm_request()
136 req->addr = cmd->addr; in cache_rpm_request()
137 req->sleep_val = req->wake_val = UINT_MAX; in cache_rpm_request()
138 list_add_tail(&req->list, &ctrlr->cache); in cache_rpm_request()
141 old_sleep_val = req->sleep_val; in cache_rpm_request()
142 old_wake_val = req->wake_val; in cache_rpm_request()
147 req->wake_val = cmd->data; in cache_rpm_request()
150 req->sleep_val = cmd->data; in cache_rpm_request()
154 ctrlr->dirty |= (req->sleep_val != old_sleep_val || in cache_rpm_request()
155 req->wake_val != old_wake_val) && in cache_rpm_request()
156 req->sleep_val != UINT_MAX && in cache_rpm_request()
157 req->wake_val != UINT_MAX; in cache_rpm_request()
160 spin_unlock_irqrestore(&ctrlr->cache_lock, flags); in cache_rpm_request()
180 int ret = -EINVAL; in __rpmh_write()
184 rpm_msg->msg.state = state; in __rpmh_write()
187 for (i = 0; i < rpm_msg->msg.num_cmds; i++) { in __rpmh_write()
188 req = cache_rpm_request(ctrlr, state, &rpm_msg->msg.cmds[i]); in __rpmh_write()
193 rpm_msg->msg.state = state; in __rpmh_write()
197 ret = rpmh_rsc_send_data(ctrlr_to_drv(ctrlr), &rpm_msg->msg); in __rpmh_write()
201 rpmh_tx_done(&rpm_msg->msg, ret); in __rpmh_write()
211 return -EINVAL; in __fill_rpmh_msg()
213 memcpy(req->cmd, cmd, n * sizeof(*cmd)); in __fill_rpmh_msg()
215 req->msg.state = state; in __fill_rpmh_msg()
216 req->msg.cmds = req->cmd; in __fill_rpmh_msg()
217 req->msg.num_cmds = n; in __fill_rpmh_msg()
241 return -ENOMEM; in rpmh_write_async()
242 rpm_msg->needs_free = true; in rpmh_write_async()
272 return -EINVAL; in rpmh_write()
283 return (ret > 0) ? 0 : -ETIMEDOUT; in rpmh_write()
291 spin_lock_irqsave(&ctrlr->cache_lock, flags); in cache_batch()
292 list_add_tail(&req->list, &ctrlr->batch_cache); in cache_batch()
293 ctrlr->dirty = true; in cache_batch()
294 spin_unlock_irqrestore(&ctrlr->cache_lock, flags); in cache_batch()
305 list_for_each_entry(req, &ctrlr->batch_cache, list) { in flush_batch()
306 for (i = 0; i < req->count; i++) { in flush_batch()
307 rpm_msg = req->rpm_msgs + i; in flush_batch()
309 &rpm_msg->msg); in flush_batch()
319 * rpmh_write_batch: Write multiple sets of RPMH commands and wait for the
331 * request is sent as fire-n-forget and no ack is expected.
348 return -EINVAL; in rpmh_write_batch()
353 return -EINVAL; in rpmh_write_batch()
356 count * (sizeof(req->rpm_msgs[0]) + sizeof(*compls)), in rpmh_write_batch()
359 return -ENOMEM; in rpmh_write_batch()
364 req->count = count; in rpmh_write_batch()
365 rpm_msgs = req->rpm_msgs; in rpmh_write_batch()
391 while (i--) { in rpmh_write_batch()
400 ret = -ETIMEDOUT; in rpmh_write_batch()
414 return (req->sleep_val != UINT_MAX && in is_req_valid()
415 req->wake_val != UINT_MAX && in is_req_valid()
416 req->sleep_val != req->wake_val); in is_req_valid()
434 * rpmh_flush() - Flushes the buffered sleep and wake sets to TCSes
439 * * 0 - Success
440 * * Error code - Otherwise
454 if (!spin_trylock(&ctrlr->cache_lock)) in rpmh_flush()
455 return -EBUSY; in rpmh_flush()
457 if (!ctrlr->dirty) { in rpmh_flush()
458 pr_debug("Skipping flush, TCS has latest data.\n"); in rpmh_flush()
470 list_for_each_entry(p, &ctrlr->cache, list) { in rpmh_flush()
473 __func__, p->addr, p->sleep_val, p->wake_val); in rpmh_flush()
476 ret = send_single(ctrlr, RPMH_SLEEP_STATE, p->addr, in rpmh_flush()
477 p->sleep_val); in rpmh_flush()
480 ret = send_single(ctrlr, RPMH_WAKE_ONLY_STATE, p->addr, in rpmh_flush()
481 p->wake_val); in rpmh_flush()
486 ctrlr->dirty = false; in rpmh_flush()
489 spin_unlock(&ctrlr->cache_lock); in rpmh_flush()
506 spin_lock_irqsave(&ctrlr->cache_lock, flags); in rpmh_invalidate()
507 list_for_each_entry_safe(req, tmp, &ctrlr->batch_cache, list) in rpmh_invalidate()
509 INIT_LIST_HEAD(&ctrlr->batch_cache); in rpmh_invalidate()
510 ctrlr->dirty = true; in rpmh_invalidate()
511 spin_unlock_irqrestore(&ctrlr->cache_lock, flags); in rpmh_invalidate()