}
        }
 
+       mutex_lock(&master->bus_lock_mutex);
        trace_spi_message_start(master->cur_msg);
 
        if (master->prepare_message) {
                                "failed to prepare message: %d\n", ret);
                        master->cur_msg->status = ret;
                        spi_finalize_current_message(master);
+                       mutex_unlock(&master->bus_lock_mutex);
                        return;
                }
                master->cur_msg_prepared = true;
        if (ret) {
                master->cur_msg->status = ret;
                spi_finalize_current_message(master);
+               mutex_unlock(&master->bus_lock_mutex);
                return;
        }
 
        if (ret) {
                dev_err(&master->dev,
                        "failed to transfer one message from queue\n");
+               mutex_unlock(&master->bus_lock_mutex);
                return;
        }
+       mutex_unlock(&master->bus_lock_mutex);
 }
 
 /**
 EXPORT_SYMBOL_GPL(spi_async_locked);
 
 
+int spi_flash_read(struct spi_device *spi,
+                  struct spi_flash_read_message *msg)
+
+{
+       struct spi_master *master = spi->master;
+       int ret;
+
+       if ((msg->opcode_nbits == SPI_NBITS_DUAL ||
+            msg->addr_nbits == SPI_NBITS_DUAL) &&
+           !(spi->mode & (SPI_TX_DUAL | SPI_TX_QUAD)))
+               return -EINVAL;
+       if ((msg->opcode_nbits == SPI_NBITS_QUAD ||
+            msg->addr_nbits == SPI_NBITS_QUAD) &&
+           !(spi->mode & SPI_TX_QUAD))
+               return -EINVAL;
+       if (msg->data_nbits == SPI_NBITS_DUAL &&
+           !(spi->mode & (SPI_RX_DUAL | SPI_RX_QUAD)))
+               return -EINVAL;
+       if (msg->data_nbits == SPI_NBITS_QUAD &&
+           !(spi->mode &  SPI_RX_QUAD))
+               return -EINVAL;
+
+       if (master->auto_runtime_pm) {
+               ret = pm_runtime_get_sync(master->dev.parent);
+               if (ret < 0) {
+                       dev_err(&master->dev, "Failed to power device: %d\n",
+                               ret);
+                       return ret;
+               }
+       }
+       mutex_lock(&master->bus_lock_mutex);
+       ret = master->spi_flash_read(spi, msg);
+       mutex_unlock(&master->bus_lock_mutex);
+       if (master->auto_runtime_pm)
+               pm_runtime_put(master->dev.parent);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(spi_flash_read);
+
 /*-------------------------------------------------------------------------*/
 
 /* Utility methods for SPI master protocol drivers, layered on
 
 struct dma_chan;
 struct spi_master;
 struct spi_transfer;
+struct spi_flash_read_message;
 
 /*
  * INTERFACES between SPI master-side drivers and SPI infrastructure.
  * @handle_err: the subsystem calls the driver to handle an error that occurs
  *             in the generic implementation of transfer_one_message().
  * @unprepare_message: undo any work done by prepare_message().
+ * @spi_flash_read: to support spi-controller hardwares that provide
+ *                  accelerated interface to read from flash devices.
  * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS
  *     number. Any individual value may be -ENOENT for CS lines that
  *     are not GPIOs (driven by the SPI controller itself).
                               struct spi_message *message);
        int (*unprepare_message)(struct spi_master *master,
                                 struct spi_message *message);
+       int (*spi_flash_read)(struct  spi_device *spi,
+                             struct spi_flash_read_message *msg);
 
        /*
         * These hooks are for drivers that use a generic implementation
        return be16_to_cpu(result);
 }
 
+/**
+ * struct spi_flash_read_message - flash specific information for
+ * spi-masters that provide accelerated flash read interfaces
+ * @buf: buffer to read data
+ * @from: offset within the flash from where data is to be read
+ * @len: length of data to be read
+ * @retlen: actual length of data read
+ * @read_opcode: read_opcode to be used to communicate with flash
+ * @addr_width: number of address bytes
+ * @dummy_bytes: number of dummy bytes
+ * @opcode_nbits: number of lines to send opcode
+ * @addr_nbits: number of lines to send address
+ * @data_nbits: number of lines for data
+ */
+struct spi_flash_read_message {
+       void *buf;
+       loff_t from;
+       size_t len;
+       size_t retlen;
+       u8 read_opcode;
+       u8 addr_width;
+       u8 dummy_bytes;
+       u8 opcode_nbits;
+       u8 addr_nbits;
+       u8 data_nbits;
+};
+
+/* SPI core interface for flash read support */
+static inline bool spi_flash_read_supported(struct spi_device *spi)
+{
+       return spi->master->spi_flash_read ? true : false;
+}
+
+int spi_flash_read(struct spi_device *spi,
+                  struct spi_flash_read_message *msg);
+
 /*---------------------------------------------------------------------------*/
 
 /*