[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [RFC PATCH 25/31] xen/arm: Use non-blocking mode for SCPI protocol



From: Oleksandr Tyshchenko <oleksandr_tyshchenko@xxxxxxxx>

Don't block until data is transmitted.
As we are limited to use only two methods TXDONE_BY_IRQ and TXDONE_BY_ACK,
there are two possible scenario:
- If the mailbox controller has TX-done irq it definitely knows when
  transmitted data has been sent and it is responsible for calling
  mbox_chan_txdone() to signal framework about TX-done.
- If controller can't generate TX-Done irq the client has to signal
  TX-done by itself.

So, in case of "ARM SMC mailbox" we explicitly tick the TX state machine
by calling mbox_client_txdone().

Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@xxxxxxxx>
CC: Stefano Stabellini <sstabellini@xxxxxxxxxx>
CC: Julien Grall <julien.grall@xxxxxxxxxx>
---
 xen/arch/arm/cpufreq/arm_scpi.c | 30 +++++++++++++++++++++++-------
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/xen/arch/arm/cpufreq/arm_scpi.c b/xen/arch/arm/cpufreq/arm_scpi.c
index 553a516..51a9742 100644
--- a/xen/arch/arm/cpufreq/arm_scpi.c
+++ b/xen/arch/arm/cpufreq/arm_scpi.c
@@ -530,7 +530,7 @@ static void put_scpi_xfer(struct scpi_xfer *t, struct 
scpi_chan *ch)
 static int scpi_send_message(u8 idx, void *tx_buf, unsigned int tx_len,
                             void *rx_buf, unsigned int rx_len)
 {
-       int ret;
+       int ret, ret2;
        u8 chan;
        u8 cmd;
        struct scpi_xfer *msg;
@@ -566,21 +566,37 @@ static int scpi_send_message(u8 idx, void *tx_buf, 
unsigned int tx_len,
        reinit_completion(&msg->done);
 
        ret = mbox_send_message(scpi_chan->chan, msg);
-       if (ret < 0 || !rx_buf)
+       if (ret < 0 || !rx_buf) {
+               /* mbox_send_message returns non-negative value on success */
+               ret2 = ret < 0 ? ret : 0;
                goto out;
+       }
 
        if (!wait_for_completion_timeout(&msg->done, MAX_RX_TIMEOUT))
                ret = -ETIMEDOUT;
        else
                /* first status word */
                ret = msg->status;
+
+       /* SCPI error codes > 0, translate them to Linux scale */
+       ret2 = ret > 0 ? scpi_to_linux_errno(ret) : ret;
+
+       /*
+        * If the mailbox controller has TX-done irq it definitely knows when
+        * transmitted data has been sent and it is responsible for calling
+        * mbox_chan_txdone() to signal framework about TX-done.
+        * If controller can't generate TX-Done irq the client has to signal
+        * TX-done by itself.
+        */
+       if (!scpi_chan->chan->mbox->txdone_irq)
+               mbox_client_txdone(scpi_chan->chan, ret2);
+
 out:
        if (ret < 0 && rx_buf) /* remove entry from the list if timed-out */
                scpi_process_cmd(scpi_chan, msg->cmd);
 
        put_scpi_xfer(msg, scpi_chan);
-       /* SCPI error codes > 0, translate them to Linux scale*/
-       return ret > 0 ? scpi_to_linux_errno(ret) : ret;
+       return ret2;
 }
 
 static u32 scpi_get_version(void)
@@ -1026,9 +1042,9 @@ static int scpi_probe(struct platform_device *pdev)
                cl->dev = dev;
                cl->rx_callback = scpi_handle_remote_msg;
                cl->tx_prepare = scpi_tx_prepare;
-               cl->tx_block = true;
-               cl->tx_tout = 20;
-               cl->knows_txdone = false; /* controller can't ack */
+               /* Use non-blocking mode for client */
+               cl->tx_block = false;
+               cl->knows_txdone = true;
 
                INIT_LIST_HEAD(&pchan->rx_pending);
                INIT_LIST_HEAD(&pchan->xfers_list);
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.