|
|
@@ -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);
|
|
|
@@ -55,6 +52,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
|
|
|
*
|
|
|
@@ -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);
|
|
|
}
|
|
|
}
|
|
|
|