mailbox: bcm-pdc: streamline rx code
authorRob Rice <rob.rice@broadcom.com>
Mon, 14 Nov 2016 18:25:59 +0000 (13:25 -0500)
committerJassi Brar <jaswinder.singh@linaro.org>
Mon, 19 Dec 2016 14:40:20 +0000 (20:10 +0530)
Remove the unnecessary rmb() from the receive path.

If the rx ring has multiple messages ready, avoid reading
last_rx_curr multiple times from the register.

Signed-off-by: Rob Rice <rob.rice@broadcom.com>
Reviewed-by: Andy Gospodarek <gospo@broadcom.com>
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
drivers/mailbox/bcm-pdc-mailbox.c

index fa3f484d37713e86b327aab972e89c66e08688b6..21957609ea916ad9aa5e6cd57351091f7a5981bc 100644 (file)
@@ -570,27 +570,23 @@ pdc_build_txd(struct pdc_state *pdcs, dma_addr_t dma_addr, u32 buf_len,
 }
 
 /**
- * pdc_receive() - Receive a response message from a given SPU.
+ * pdc_receive_one() - Receive a response message from a given SPU.
  * @pdcs:    PDC state for the SPU to receive from
- * @mssg:    mailbox message to be returned to client
  *
  * When the return code indicates success, the response message is available in
  * the receive buffers provided prior to submission of the request.
  *
- * Input:
- *   pdcs - PDC state structure for the SPU to be polled
- *   mssg - mailbox message to be returned to client. This function sets the
- *         context pointer on the message to help the client associate the
- *         response with a request.
- *
  * Return:  PDC_SUCCESS if one or more receive descriptors was processed
  *          -EAGAIN indicates that no response message is available
  *          -EIO an error occurred
  */
 static int
-pdc_receive(struct pdc_state *pdcs, struct brcm_message *mssg)
+pdc_receive_one(struct pdc_state *pdcs)
 {
        struct device *dev = &pdcs->pdev->dev;
+       struct mbox_controller *mbc;
+       struct mbox_chan *chan;
+       struct brcm_message mssg;
        u32 len, rx_status;
        u32 num_frags;
        int i;
@@ -599,29 +595,23 @@ pdc_receive(struct pdc_state *pdcs, struct brcm_message *mssg)
        u32 rx_idx;      /* ring index of start of receive frame */
        dma_addr_t resp_hdr_daddr;
 
+       mbc = &pdcs->mbc;
+       chan = &mbc->chans[0];
+       mssg.type = BRCM_MESSAGE_SPU;
+
        /*
         * return if a complete response message is not yet ready.
         * rxin_numd[rxin] is the number of fragments in the next msg
         * to read.
         */
        frags_rdy = NRXDACTIVE(pdcs->rxin, pdcs->last_rx_curr, pdcs->nrxpost);
-       if ((frags_rdy == 0) || (frags_rdy < pdcs->rxin_numd[pdcs->rxin])) {
-               /* See if the hw has written more fragments than we know */
-               pdcs->last_rx_curr =
-                   (ioread32((void *)&pdcs->rxregs_64->status0) &
-                    CRYPTO_D64_RS0_CD_MASK) / RING_ENTRY_SIZE;
-               frags_rdy = NRXDACTIVE(pdcs->rxin, pdcs->last_rx_curr,
-                                      pdcs->nrxpost);
-               if ((frags_rdy == 0) ||
-                   (frags_rdy < pdcs->rxin_numd[pdcs->rxin])) {
-                       /* No response ready */
-                       return -EAGAIN;
-               }
-               /* can't read descriptors/data until write index is read */
-               rmb();
-       }
+       if ((frags_rdy == 0) || (frags_rdy < pdcs->rxin_numd[pdcs->rxin]))
+               /* No response ready */
+               return -EAGAIN;
 
        num_frags = pdcs->txin_numd[pdcs->txin];
+       WARN_ON(num_frags == 0);
+
        dma_unmap_sg(dev, pdcs->src_sg[pdcs->txin],
                     sg_nents(pdcs->src_sg[pdcs->txin]), DMA_TO_DEVICE);
 
@@ -634,7 +624,7 @@ pdc_receive(struct pdc_state *pdcs, struct brcm_message *mssg)
        rx_idx = pdcs->rxin;
        num_frags = pdcs->rxin_numd[rx_idx];
        /* Return opaque context with result */
-       mssg->ctx = pdcs->rxp_ctx[rx_idx];
+       mssg.ctx = pdcs->rxp_ctx[rx_idx];
        pdcs->rxp_ctx[rx_idx] = NULL;
        resp_hdr = pdcs->resp_hdr[rx_idx];
        resp_hdr_daddr = pdcs->resp_hdr_daddr[rx_idx];
@@ -674,12 +664,35 @@ pdc_receive(struct pdc_state *pdcs, struct brcm_message *mssg)
 
        dma_pool_free(pdcs->rx_buf_pool, resp_hdr, resp_hdr_daddr);
 
+       mbox_chan_received_data(chan, &mssg);
+
        pdcs->pdc_replies++;
-       /* if we read one or more rx descriptors, claim success */
-       if (num_frags > 0)
-               return PDC_SUCCESS;
-       else
-               return -EIO;
+       return PDC_SUCCESS;
+}
+
+/**
+ * pdc_receive() - Process as many responses as are available in the rx ring.
+ * @pdcs:  PDC state
+ *
+ * Called within the hard IRQ.
+ * Return:
+ */
+static int
+pdc_receive(struct pdc_state *pdcs)
+{
+       int rx_status;
+
+       /* read last_rx_curr from register once */
+       pdcs->last_rx_curr =
+           (ioread32((void *)&pdcs->rxregs_64->status0) &
+            CRYPTO_D64_RS0_CD_MASK) / RING_ENTRY_SIZE;
+
+       do {
+               /* Could be many frames ready */
+               rx_status = pdc_receive_one(pdcs);
+       } while (rx_status == PDC_SUCCESS);
+
+       return 0;
 }
 
 /**
@@ -946,14 +959,13 @@ static irqreturn_t pdc_irq_handler(int irq, void *cookie)
 }
 
 /**
- * pdc_irq_thread() - Function invoked on deferred thread when a DMA tx has
- * completed or data is available to receive.
+ * pdc_irq_thread() - Function invoked on deferred thread when data is available
+ * to receive.
  * @irq:    Interrupt number
  * @cookie: PDC state for PDC that generated the interrupt
  *
- * On DMA tx complete, notify the mailbox client. On DMA rx complete, process
- * as many SPU response messages as are available and send each to the mailbox
- * client.
+ * On DMA rx complete, process as many SPU response messages as are available
+ * and send each to the mailbox client.
  *
  * Return: IRQ_HANDLED if we recognized and handled the interrupt
  *         IRQ_NONE otherwise
@@ -961,39 +973,15 @@ static irqreturn_t pdc_irq_handler(int irq, void *cookie)
 static irqreturn_t pdc_irq_thread(int irq, void *cookie)
 {
        struct pdc_state *pdcs = cookie;
-       struct mbox_controller *mbc;
-       struct mbox_chan *chan;
        bool rx_int;
-       int rx_status;
-       struct brcm_message mssg;
 
        rx_int = test_and_clear_bit(PDC_RCVINT_0, &pdcs->intstatus);
-
        if (pdcs && rx_int) {
                dev_dbg(&pdcs->pdev->dev,
                        "%s() got irq %d with rx_int %s",
                        __func__, irq, rx_int ? "set" : "clear");
 
-               mbc = &pdcs->mbc;
-               chan = &mbc->chans[0];
-
-               while (1) {
-                       /* Could be many frames ready */
-                       memset(&mssg, 0, sizeof(mssg));
-                       mssg.type = BRCM_MESSAGE_SPU;
-                       rx_status = pdc_receive(pdcs, &mssg);
-                       if (rx_status >= 0) {
-                               dev_dbg(&pdcs->pdev->dev,
-                                       "%s(): invoking client rx cb",
-                                       __func__);
-                               mbox_chan_received_data(chan, &mssg);
-                       } else {
-                               dev_dbg(&pdcs->pdev->dev,
-                                       "%s(): no SPU response available",
-                                       __func__);
-                               break;
-                       }
-               }
+               pdc_receive(pdcs);
                return IRQ_HANDLED;
        }
        return IRQ_NONE;