080-spi-introduce-accelerated-read-support-for-spi-flash.patch 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. From 556351f14e74db4cd3ddde386457edce7bf0b27f Mon Sep 17 00:00:00 2001
  2. From: Vignesh R <vigneshr@ti.com>
  3. Date: Fri, 11 Dec 2015 09:39:56 +0530
  4. Subject: [PATCH] spi: introduce accelerated read support for spi flash devices
  5. In addition to providing direct access to SPI bus, some spi controller
  6. hardwares (like ti-qspi) provide special port (like memory mapped port)
  7. that are optimized to improve SPI flash read performance.
  8. This means the controller can automatically send the SPI signals
  9. required to read data from the SPI flash device.
  10. For this, SPI controller needs to know flash specific information like
  11. read command to use, dummy bytes and address width.
  12. Introduce spi_flash_read() interface to support accelerated read
  13. over SPI flash devices. SPI master drivers can implement this callback to
  14. support interfaces such as memory mapped read etc. m25p80 flash driver
  15. and other flash drivers can call this make use of such interfaces. The
  16. interface should only be used with SPI flashes and cannot be used with
  17. other SPI devices.
  18. Signed-off-by: Vignesh R <vigneshr@ti.com>
  19. Signed-off-by: Mark Brown <broonie@kernel.org>
  20. ---
  21. --- a/drivers/spi/spi.c
  22. +++ b/drivers/spi/spi.c
  23. @@ -1143,6 +1143,7 @@ static void __spi_pump_messages(struct s
  24. }
  25. }
  26. + mutex_lock(&master->bus_lock_mutex);
  27. trace_spi_message_start(master->cur_msg);
  28. if (master->prepare_message) {
  29. @@ -1152,6 +1153,7 @@ static void __spi_pump_messages(struct s
  30. "failed to prepare message: %d\n", ret);
  31. master->cur_msg->status = ret;
  32. spi_finalize_current_message(master);
  33. + mutex_unlock(&master->bus_lock_mutex);
  34. return;
  35. }
  36. master->cur_msg_prepared = true;
  37. @@ -1161,6 +1163,7 @@ static void __spi_pump_messages(struct s
  38. if (ret) {
  39. master->cur_msg->status = ret;
  40. spi_finalize_current_message(master);
  41. + mutex_unlock(&master->bus_lock_mutex);
  42. return;
  43. }
  44. @@ -1168,8 +1171,10 @@ static void __spi_pump_messages(struct s
  45. if (ret) {
  46. dev_err(&master->dev,
  47. "failed to transfer one message from queue\n");
  48. + mutex_unlock(&master->bus_lock_mutex);
  49. return;
  50. }
  51. + mutex_unlock(&master->bus_lock_mutex);
  52. }
  53. /**
  54. @@ -2337,6 +2342,46 @@ int spi_async_locked(struct spi_device *
  55. EXPORT_SYMBOL_GPL(spi_async_locked);
  56. +int spi_flash_read(struct spi_device *spi,
  57. + struct spi_flash_read_message *msg)
  58. +
  59. +{
  60. + struct spi_master *master = spi->master;
  61. + int ret;
  62. +
  63. + if ((msg->opcode_nbits == SPI_NBITS_DUAL ||
  64. + msg->addr_nbits == SPI_NBITS_DUAL) &&
  65. + !(spi->mode & (SPI_TX_DUAL | SPI_TX_QUAD)))
  66. + return -EINVAL;
  67. + if ((msg->opcode_nbits == SPI_NBITS_QUAD ||
  68. + msg->addr_nbits == SPI_NBITS_QUAD) &&
  69. + !(spi->mode & SPI_TX_QUAD))
  70. + return -EINVAL;
  71. + if (msg->data_nbits == SPI_NBITS_DUAL &&
  72. + !(spi->mode & (SPI_RX_DUAL | SPI_RX_QUAD)))
  73. + return -EINVAL;
  74. + if (msg->data_nbits == SPI_NBITS_QUAD &&
  75. + !(spi->mode & SPI_RX_QUAD))
  76. + return -EINVAL;
  77. +
  78. + if (master->auto_runtime_pm) {
  79. + ret = pm_runtime_get_sync(master->dev.parent);
  80. + if (ret < 0) {
  81. + dev_err(&master->dev, "Failed to power device: %d\n",
  82. + ret);
  83. + return ret;
  84. + }
  85. + }
  86. + mutex_lock(&master->bus_lock_mutex);
  87. + ret = master->spi_flash_read(spi, msg);
  88. + mutex_unlock(&master->bus_lock_mutex);
  89. + if (master->auto_runtime_pm)
  90. + pm_runtime_put(master->dev.parent);
  91. +
  92. + return ret;
  93. +}
  94. +EXPORT_SYMBOL_GPL(spi_flash_read);
  95. +
  96. /*-------------------------------------------------------------------------*/
  97. /* Utility methods for SPI master protocol drivers, layered on
  98. --- a/include/linux/spi/spi.h
  99. +++ b/include/linux/spi/spi.h
  100. @@ -25,6 +25,7 @@
  101. struct dma_chan;
  102. struct spi_master;
  103. struct spi_transfer;
  104. +struct spi_flash_read_message;
  105. /*
  106. * INTERFACES between SPI master-side drivers and SPI infrastructure.
  107. @@ -361,6 +362,8 @@ static inline void spi_unregister_driver
  108. * @handle_err: the subsystem calls the driver to handle an error that occurs
  109. * in the generic implementation of transfer_one_message().
  110. * @unprepare_message: undo any work done by prepare_message().
  111. + * @spi_flash_read: to support spi-controller hardwares that provide
  112. + * accelerated interface to read from flash devices.
  113. * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS
  114. * number. Any individual value may be -ENOENT for CS lines that
  115. * are not GPIOs (driven by the SPI controller itself).
  116. @@ -507,6 +510,8 @@ struct spi_master {
  117. struct spi_message *message);
  118. int (*unprepare_message)(struct spi_master *master,
  119. struct spi_message *message);
  120. + int (*spi_flash_read)(struct spi_device *spi,
  121. + struct spi_flash_read_message *msg);
  122. /*
  123. * These hooks are for drivers that use a generic implementation
  124. @@ -999,6 +1004,42 @@ static inline ssize_t spi_w8r16be(struct
  125. return be16_to_cpu(result);
  126. }
  127. +/**
  128. + * struct spi_flash_read_message - flash specific information for
  129. + * spi-masters that provide accelerated flash read interfaces
  130. + * @buf: buffer to read data
  131. + * @from: offset within the flash from where data is to be read
  132. + * @len: length of data to be read
  133. + * @retlen: actual length of data read
  134. + * @read_opcode: read_opcode to be used to communicate with flash
  135. + * @addr_width: number of address bytes
  136. + * @dummy_bytes: number of dummy bytes
  137. + * @opcode_nbits: number of lines to send opcode
  138. + * @addr_nbits: number of lines to send address
  139. + * @data_nbits: number of lines for data
  140. + */
  141. +struct spi_flash_read_message {
  142. + void *buf;
  143. + loff_t from;
  144. + size_t len;
  145. + size_t retlen;
  146. + u8 read_opcode;
  147. + u8 addr_width;
  148. + u8 dummy_bytes;
  149. + u8 opcode_nbits;
  150. + u8 addr_nbits;
  151. + u8 data_nbits;
  152. +};
  153. +
  154. +/* SPI core interface for flash read support */
  155. +static inline bool spi_flash_read_supported(struct spi_device *spi)
  156. +{
  157. + return spi->master->spi_flash_read ? true : false;
  158. +}
  159. +
  160. +int spi_flash_read(struct spi_device *spi,
  161. + struct spi_flash_read_message *msg);
  162. +
  163. /*---------------------------------------------------------------------------*/
  164. /*