diff options
| -rw-r--r-- | drivers/spi/spi.c | 48 | ||||
| -rw-r--r-- | include/linux/spi/spi.h | 41 |
2 files changed, 89 insertions, 0 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 47eff8012a77..0b2bbf144460 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
| @@ -1152,6 +1152,7 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread) | |||
| 1152 | } | 1152 | } |
| 1153 | } | 1153 | } |
| 1154 | 1154 | ||
| 1155 | mutex_lock(&master->bus_lock_mutex); | ||
| 1155 | trace_spi_message_start(master->cur_msg); | 1156 | trace_spi_message_start(master->cur_msg); |
| 1156 | 1157 | ||
| 1157 | if (master->prepare_message) { | 1158 | if (master->prepare_message) { |
| @@ -1161,6 +1162,7 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread) | |||
| 1161 | "failed to prepare message: %d\n", ret); | 1162 | "failed to prepare message: %d\n", ret); |
| 1162 | master->cur_msg->status = ret; | 1163 | master->cur_msg->status = ret; |
| 1163 | spi_finalize_current_message(master); | 1164 | spi_finalize_current_message(master); |
| 1165 | mutex_unlock(&master->bus_lock_mutex); | ||
| 1164 | return; | 1166 | return; |
| 1165 | } | 1167 | } |
| 1166 | master->cur_msg_prepared = true; | 1168 | master->cur_msg_prepared = true; |
| @@ -1170,6 +1172,7 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread) | |||
| 1170 | if (ret) { | 1172 | if (ret) { |
| 1171 | master->cur_msg->status = ret; | 1173 | master->cur_msg->status = ret; |
| 1172 | spi_finalize_current_message(master); | 1174 | spi_finalize_current_message(master); |
| 1175 | mutex_unlock(&master->bus_lock_mutex); | ||
| 1173 | return; | 1176 | return; |
| 1174 | } | 1177 | } |
| 1175 | 1178 | ||
| @@ -1177,8 +1180,13 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread) | |||
| 1177 | if (ret) { | 1180 | if (ret) { |
| 1178 | dev_err(&master->dev, | 1181 | dev_err(&master->dev, |
| 1179 | "failed to transfer one message from queue\n"); | 1182 | "failed to transfer one message from queue\n"); |
| 1183 | mutex_unlock(&master->bus_lock_mutex); | ||
| 1180 | return; | 1184 | return; |
| 1181 | } | 1185 | } |
| 1186 | mutex_unlock(&master->bus_lock_mutex); | ||
| 1187 | |||
| 1188 | /* Prod the scheduler in case transfer_one() was busy waiting */ | ||
| 1189 | cond_resched(); | ||
| 1182 | } | 1190 | } |
| 1183 | 1191 | ||
| 1184 | /** | 1192 | /** |
| @@ -2351,6 +2359,46 @@ int spi_async_locked(struct spi_device *spi, struct spi_message *message) | |||
| 2351 | EXPORT_SYMBOL_GPL(spi_async_locked); | 2359 | EXPORT_SYMBOL_GPL(spi_async_locked); |
| 2352 | 2360 | ||
| 2353 | 2361 | ||
| 2362 | int spi_flash_read(struct spi_device *spi, | ||
| 2363 | struct spi_flash_read_message *msg) | ||
| 2364 | |||
| 2365 | { | ||
| 2366 | struct spi_master *master = spi->master; | ||
| 2367 | int ret; | ||
| 2368 | |||
| 2369 | if ((msg->opcode_nbits == SPI_NBITS_DUAL || | ||
| 2370 | msg->addr_nbits == SPI_NBITS_DUAL) && | ||
| 2371 | !(spi->mode & (SPI_TX_DUAL | SPI_TX_QUAD))) | ||
| 2372 | return -EINVAL; | ||
| 2373 | if ((msg->opcode_nbits == SPI_NBITS_QUAD || | ||
| 2374 | msg->addr_nbits == SPI_NBITS_QUAD) && | ||
| 2375 | !(spi->mode & SPI_TX_QUAD)) | ||
| 2376 | return -EINVAL; | ||
| 2377 | if (msg->data_nbits == SPI_NBITS_DUAL && | ||
| 2378 | !(spi->mode & (SPI_RX_DUAL | SPI_RX_QUAD))) | ||
| 2379 | return -EINVAL; | ||
| 2380 | if (msg->data_nbits == SPI_NBITS_QUAD && | ||
| 2381 | !(spi->mode & SPI_RX_QUAD)) | ||
| 2382 | return -EINVAL; | ||
| 2383 | |||
| 2384 | if (master->auto_runtime_pm) { | ||
| 2385 | ret = pm_runtime_get_sync(master->dev.parent); | ||
| 2386 | if (ret < 0) { | ||
| 2387 | dev_err(&master->dev, "Failed to power device: %d\n", | ||
| 2388 | ret); | ||
| 2389 | return ret; | ||
| 2390 | } | ||
| 2391 | } | ||
| 2392 | mutex_lock(&master->bus_lock_mutex); | ||
| 2393 | ret = master->spi_flash_read(spi, msg); | ||
| 2394 | mutex_unlock(&master->bus_lock_mutex); | ||
| 2395 | if (master->auto_runtime_pm) | ||
| 2396 | pm_runtime_put(master->dev.parent); | ||
| 2397 | |||
| 2398 | return ret; | ||
| 2399 | } | ||
| 2400 | EXPORT_SYMBOL_GPL(spi_flash_read); | ||
| 2401 | |||
| 2354 | /*-------------------------------------------------------------------------*/ | 2402 | /*-------------------------------------------------------------------------*/ |
| 2355 | 2403 | ||
| 2356 | /* Utility methods for SPI master protocol drivers, layered on | 2404 | /* Utility methods for SPI master protocol drivers, layered on |
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 53be3a4c60cb..ba0dee9d05a3 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | struct dma_chan; | 25 | struct dma_chan; |
| 26 | struct spi_master; | 26 | struct spi_master; |
| 27 | struct spi_transfer; | 27 | struct spi_transfer; |
| 28 | struct spi_flash_read_message; | ||
| 28 | 29 | ||
| 29 | /* | 30 | /* |
| 30 | * INTERFACES between SPI master-side drivers and SPI infrastructure. | 31 | * INTERFACES between SPI master-side drivers and SPI infrastructure. |
| @@ -361,6 +362,8 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) | |||
| 361 | * @handle_err: the subsystem calls the driver to handle an error that occurs | 362 | * @handle_err: the subsystem calls the driver to handle an error that occurs |
| 362 | * in the generic implementation of transfer_one_message(). | 363 | * in the generic implementation of transfer_one_message(). |
| 363 | * @unprepare_message: undo any work done by prepare_message(). | 364 | * @unprepare_message: undo any work done by prepare_message(). |
| 365 | * @spi_flash_read: to support spi-controller hardwares that provide | ||
| 366 | * accelerated interface to read from flash devices. | ||
| 364 | * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS | 367 | * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS |
| 365 | * number. Any individual value may be -ENOENT for CS lines that | 368 | * number. Any individual value may be -ENOENT for CS lines that |
| 366 | * are not GPIOs (driven by the SPI controller itself). | 369 | * are not GPIOs (driven by the SPI controller itself). |
| @@ -513,6 +516,8 @@ struct spi_master { | |||
| 513 | struct spi_message *message); | 516 | struct spi_message *message); |
| 514 | int (*unprepare_message)(struct spi_master *master, | 517 | int (*unprepare_message)(struct spi_master *master, |
| 515 | struct spi_message *message); | 518 | struct spi_message *message); |
| 519 | int (*spi_flash_read)(struct spi_device *spi, | ||
| 520 | struct spi_flash_read_message *msg); | ||
| 516 | 521 | ||
| 517 | /* | 522 | /* |
| 518 | * These hooks are for drivers that use a generic implementation | 523 | * These hooks are for drivers that use a generic implementation |
| @@ -1019,6 +1024,42 @@ static inline ssize_t spi_w8r16be(struct spi_device *spi, u8 cmd) | |||
| 1019 | return be16_to_cpu(result); | 1024 | return be16_to_cpu(result); |
| 1020 | } | 1025 | } |
| 1021 | 1026 | ||
| 1027 | /** | ||
| 1028 | * struct spi_flash_read_message - flash specific information for | ||
| 1029 | * spi-masters that provide accelerated flash read interfaces | ||
| 1030 | * @buf: buffer to read data | ||
| 1031 | * @from: offset within the flash from where data is to be read | ||
| 1032 | * @len: length of data to be read | ||
| 1033 | * @retlen: actual length of data read | ||
| 1034 | * @read_opcode: read_opcode to be used to communicate with flash | ||
| 1035 | * @addr_width: number of address bytes | ||
| 1036 | * @dummy_bytes: number of dummy bytes | ||
| 1037 | * @opcode_nbits: number of lines to send opcode | ||
| 1038 | * @addr_nbits: number of lines to send address | ||
| 1039 | * @data_nbits: number of lines for data | ||
| 1040 | */ | ||
| 1041 | struct spi_flash_read_message { | ||
| 1042 | void *buf; | ||
| 1043 | loff_t from; | ||
| 1044 | size_t len; | ||
| 1045 | size_t retlen; | ||
| 1046 | u8 read_opcode; | ||
| 1047 | u8 addr_width; | ||
| 1048 | u8 dummy_bytes; | ||
| 1049 | u8 opcode_nbits; | ||
| 1050 | u8 addr_nbits; | ||
| 1051 | u8 data_nbits; | ||
| 1052 | }; | ||
| 1053 | |||
| 1054 | /* SPI core interface for flash read support */ | ||
| 1055 | static inline bool spi_flash_read_supported(struct spi_device *spi) | ||
| 1056 | { | ||
| 1057 | return spi->master->spi_flash_read ? true : false; | ||
| 1058 | } | ||
| 1059 | |||
| 1060 | int spi_flash_read(struct spi_device *spi, | ||
| 1061 | struct spi_flash_read_message *msg); | ||
| 1062 | |||
| 1022 | /*---------------------------------------------------------------------------*/ | 1063 | /*---------------------------------------------------------------------------*/ |
| 1023 | 1064 | ||
| 1024 | /* | 1065 | /* |
