aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVignesh R <vigneshr@ti.com>2015-12-10 23:09:56 -0500
committerMark Brown <broonie@kernel.org>2016-02-09 14:34:02 -0500
commit556351f14e74db4cd3ddde386457edce7bf0b27f (patch)
treed0f00feb603a841a6bd44929941cb1d7da1eabef
parent92e963f50fc74041b5e9e744c330dca48e04f08d (diff)
spi: introduce accelerated read support for spi flash devices
In addition to providing direct access to SPI bus, some spi controller hardwares (like ti-qspi) provide special port (like memory mapped port) that are optimized to improve SPI flash read performance. This means the controller can automatically send the SPI signals required to read data from the SPI flash device. For this, SPI controller needs to know flash specific information like read command to use, dummy bytes and address width. Introduce spi_flash_read() interface to support accelerated read over SPI flash devices. SPI master drivers can implement this callback to support interfaces such as memory mapped read etc. m25p80 flash driver and other flash drivers can call this make use of such interfaces. The interface should only be used with SPI flashes and cannot be used with other SPI devices. Signed-off-by: Vignesh R <vigneshr@ti.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/spi/spi.c45
-rw-r--r--include/linux/spi/spi.h41
2 files changed, 86 insertions, 0 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 47eff8012a77..dcc6f6e92668 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,10 @@ 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);
1182} 1187}
1183 1188
1184/** 1189/**
@@ -2351,6 +2356,46 @@ int spi_async_locked(struct spi_device *spi, struct spi_message *message)
2351EXPORT_SYMBOL_GPL(spi_async_locked); 2356EXPORT_SYMBOL_GPL(spi_async_locked);
2352 2357
2353 2358
2359int spi_flash_read(struct spi_device *spi,
2360 struct spi_flash_read_message *msg)
2361
2362{
2363 struct spi_master *master = spi->master;
2364 int ret;
2365
2366 if ((msg->opcode_nbits == SPI_NBITS_DUAL ||
2367 msg->addr_nbits == SPI_NBITS_DUAL) &&
2368 !(spi->mode & (SPI_TX_DUAL | SPI_TX_QUAD)))
2369 return -EINVAL;
2370 if ((msg->opcode_nbits == SPI_NBITS_QUAD ||
2371 msg->addr_nbits == SPI_NBITS_QUAD) &&
2372 !(spi->mode & SPI_TX_QUAD))
2373 return -EINVAL;
2374 if (msg->data_nbits == SPI_NBITS_DUAL &&
2375 !(spi->mode & (SPI_RX_DUAL | SPI_RX_QUAD)))
2376 return -EINVAL;
2377 if (msg->data_nbits == SPI_NBITS_QUAD &&
2378 !(spi->mode & SPI_RX_QUAD))
2379 return -EINVAL;
2380
2381 if (master->auto_runtime_pm) {
2382 ret = pm_runtime_get_sync(master->dev.parent);
2383 if (ret < 0) {
2384 dev_err(&master->dev, "Failed to power device: %d\n",
2385 ret);
2386 return ret;
2387 }
2388 }
2389 mutex_lock(&master->bus_lock_mutex);
2390 ret = master->spi_flash_read(spi, msg);
2391 mutex_unlock(&master->bus_lock_mutex);
2392 if (master->auto_runtime_pm)
2393 pm_runtime_put(master->dev.parent);
2394
2395 return ret;
2396}
2397EXPORT_SYMBOL_GPL(spi_flash_read);
2398
2354/*-------------------------------------------------------------------------*/ 2399/*-------------------------------------------------------------------------*/
2355 2400
2356/* Utility methods for SPI master protocol drivers, layered on 2401/* 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 @@
25struct dma_chan; 25struct dma_chan;
26struct spi_master; 26struct spi_master;
27struct spi_transfer; 27struct spi_transfer;
28struct 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 */
1041struct 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 */
1055static inline bool spi_flash_read_supported(struct spi_device *spi)
1056{
1057 return spi->master->spi_flash_read ? true : false;
1058}
1059
1060int spi_flash_read(struct spi_device *spi,
1061 struct spi_flash_read_message *msg);
1062
1022/*---------------------------------------------------------------------------*/ 1063/*---------------------------------------------------------------------------*/
1023 1064
1024/* 1065/*