aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/slimbus/messaging.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/slimbus/messaging.c')
-rw-r--r--drivers/slimbus/messaging.c74
1 files changed, 52 insertions, 22 deletions
diff --git a/drivers/slimbus/messaging.c b/drivers/slimbus/messaging.c
index e3605ed1c459..d5879142dbef 100644
--- a/drivers/slimbus/messaging.c
+++ b/drivers/slimbus/messaging.c
@@ -29,22 +29,19 @@ void slim_msg_response(struct slim_controller *ctrl, u8 *reply, u8 tid, u8 len)
spin_lock_irqsave(&ctrl->txn_lock, flags);
txn = idr_find(&ctrl->tid_idr, tid);
- if (txn == NULL) {
- spin_unlock_irqrestore(&ctrl->txn_lock, flags);
+ spin_unlock_irqrestore(&ctrl->txn_lock, flags);
+
+ if (txn == NULL)
return;
- }
msg = txn->msg;
if (msg == NULL || msg->rbuf == NULL) {
dev_err(ctrl->dev, "Got response to invalid TID:%d, len:%d\n",
tid, len);
- spin_unlock_irqrestore(&ctrl->txn_lock, flags);
return;
}
- idr_remove(&ctrl->tid_idr, tid);
- spin_unlock_irqrestore(&ctrl->txn_lock, flags);
-
+ slim_free_txn_tid(ctrl, txn);
memcpy(msg->rbuf, reply, len);
if (txn->comp)
complete(txn->comp);
@@ -56,6 +53,48 @@ void slim_msg_response(struct slim_controller *ctrl, u8 *reply, u8 tid, u8 len)
EXPORT_SYMBOL_GPL(slim_msg_response);
/**
+ * slim_alloc_txn_tid() - Allocate a tid to txn
+ *
+ * @ctrl: Controller handle
+ * @txn: transaction to be allocated with tid.
+ *
+ * Return: zero on success with valid txn->tid and error code on failures.
+ */
+int slim_alloc_txn_tid(struct slim_controller *ctrl, struct slim_msg_txn *txn)
+{
+ unsigned long flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&ctrl->txn_lock, flags);
+ ret = idr_alloc_cyclic(&ctrl->tid_idr, txn, 0,
+ SLIM_MAX_TIDS, GFP_ATOMIC);
+ if (ret < 0) {
+ spin_unlock_irqrestore(&ctrl->txn_lock, flags);
+ return ret;
+ }
+ txn->tid = ret;
+ spin_unlock_irqrestore(&ctrl->txn_lock, flags);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(slim_alloc_txn_tid);
+
+/**
+ * slim_free_txn_tid() - Freee tid of txn
+ *
+ * @ctrl: Controller handle
+ * @txn: transaction whose tid should be freed
+ */
+void slim_free_txn_tid(struct slim_controller *ctrl, struct slim_msg_txn *txn)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctrl->txn_lock, flags);
+ idr_remove(&ctrl->tid_idr, txn->tid);
+ spin_unlock_irqrestore(&ctrl->txn_lock, flags);
+}
+EXPORT_SYMBOL_GPL(slim_free_txn_tid);
+
+/**
* slim_do_transfer() - Process a SLIMbus-messaging transaction
*
* @ctrl: Controller handle
@@ -72,8 +111,7 @@ int slim_do_transfer(struct slim_controller *ctrl, struct slim_msg_txn *txn)
{
DECLARE_COMPLETION_ONSTACK(done);
bool need_tid = false, clk_pause_msg = false;
- unsigned long flags;
- int ret, tid, timeout;
+ int ret, timeout;
/*
* do not vote for runtime-PM if the transactions are part of clock
@@ -97,34 +135,26 @@ int slim_do_transfer(struct slim_controller *ctrl, struct slim_msg_txn *txn)
need_tid = slim_tid_txn(txn->mt, txn->mc);
if (need_tid) {
- spin_lock_irqsave(&ctrl->txn_lock, flags);
- tid = idr_alloc(&ctrl->tid_idr, txn, 0,
- SLIM_MAX_TIDS, GFP_ATOMIC);
- txn->tid = tid;
+ ret = slim_alloc_txn_tid(ctrl, txn);
+ if (ret)
+ return ret;
if (!txn->msg->comp)
txn->comp = &done;
else
txn->comp = txn->comp;
-
- spin_unlock_irqrestore(&ctrl->txn_lock, flags);
-
- if (tid < 0)
- return tid;
}
ret = ctrl->xfer_msg(ctrl, txn);
- if (ret && need_tid && !txn->msg->comp) {
+ if (!ret && need_tid && !txn->msg->comp) {
unsigned long ms = txn->rl + HZ;
timeout = wait_for_completion_timeout(txn->comp,
msecs_to_jiffies(ms));
if (!timeout) {
ret = -ETIMEDOUT;
- spin_lock_irqsave(&ctrl->txn_lock, flags);
- idr_remove(&ctrl->tid_idr, tid);
- spin_unlock_irqrestore(&ctrl->txn_lock, flags);
+ slim_free_txn_tid(ctrl, txn);
}
}