}
        }
 
+       /*
+        * Drivers implementation of transfer_one_message() must arrange for
+        * spi_finalize_current_message() to get called. Most drivers will do
+        * this in the calling context, but some don't. For those cases, a
+        * completion is used to guarantee that this function does not return
+        * until spi_finalize_current_message() is done accessing
+        * ctlr->cur_msg.
+        * Use of the following two flags enable to opportunistically skip the
+        * use of the completion since its use involves expensive spin locks.
+        * In case of a race with the context that calls
+        * spi_finalize_current_message() the completion will always be used,
+        * due to strict ordering of these flags using barriers.
+        */
+       WRITE_ONCE(ctlr->cur_msg_incomplete, true);
+       WRITE_ONCE(ctlr->cur_msg_need_completion, false);
        reinit_completion(&ctlr->cur_msg_completion);
+       smp_wmb(); /* make these available to spi_finalize_current_message */
+
        ret = ctlr->transfer_one_message(ctlr, msg);
        if (ret) {
                dev_err(&ctlr->dev,
                        "failed to transfer one message from queue\n");
                return ret;
        } else {
-               wait_for_completion(&ctlr->cur_msg_completion);
+               WRITE_ONCE(ctlr->cur_msg_need_completion, true);
+               smp_mb(); /* see spi_finalize_current_message()... */
+               if (READ_ONCE(ctlr->cur_msg_incomplete))
+                       wait_for_completion(&ctlr->cur_msg_completion);
        }
 
        return 0;
 
        mesg->prepared = false;
 
-       complete(&ctlr->cur_msg_completion);
+       WRITE_ONCE(ctlr->cur_msg_incomplete, false);
+       smp_mb(); /* See __spi_pump_transfer_message()... */
+       if (READ_ONCE(ctlr->cur_msg_need_completion))
+               complete(&ctlr->cur_msg_completion);
 
        trace_spi_message_done(mesg);
 
 
  * @queue: message queue
  * @cur_msg: the currently in-flight message
  * @cur_msg_completion: a completion for the current in-flight message
+ * @cur_msg_incomplete: Flag used internally to opportunistically skip
+ *     the @cur_msg_completion. This flag is used to check if the driver has
+ *     already called spi_finalize_current_message().
+ * @cur_msg_need_completion: Flag used internally to opportunistically skip
+ *     the @cur_msg_completion. This flag is used to signal the context that
+ *     is running spi_finalize_current_message() that it needs to complete()
  * @cur_msg_mapped: message has been mapped for DMA
  * @last_cs: the last chip_select that is recorded by set_cs, -1 on non chip
  *           selected
        struct list_head                queue;
        struct spi_message              *cur_msg;
        struct completion               cur_msg_completion;
+       bool                            cur_msg_incomplete;
+       bool                            cur_msg_need_completion;
        bool                            busy;
        bool                            running;
        bool                            rt;