Skip to content

Commit 556351f

Browse files
r-vigneshbroonie
authored andcommitted
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>
1 parent 92e963f commit 556351f

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-0
lines changed

drivers/spi/spi.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,6 +1152,7 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread)
11521152
}
11531153
}
11541154

1155+
mutex_lock(&master->bus_lock_mutex);
11551156
trace_spi_message_start(master->cur_msg);
11561157

11571158
if (master->prepare_message) {
@@ -1161,6 +1162,7 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread)
11611162
"failed to prepare message: %d\n", ret);
11621163
master->cur_msg->status = ret;
11631164
spi_finalize_current_message(master);
1165+
mutex_unlock(&master->bus_lock_mutex);
11641166
return;
11651167
}
11661168
master->cur_msg_prepared = true;
@@ -1170,15 +1172,18 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread)
11701172
if (ret) {
11711173
master->cur_msg->status = ret;
11721174
spi_finalize_current_message(master);
1175+
mutex_unlock(&master->bus_lock_mutex);
11731176
return;
11741177
}
11751178

11761179
ret = master->transfer_one_message(master, master->cur_msg);
11771180
if (ret) {
11781181
dev_err(&master->dev,
11791182
"failed to transfer one message from queue\n");
1183+
mutex_unlock(&master->bus_lock_mutex);
11801184
return;
11811185
}
1186+
mutex_unlock(&master->bus_lock_mutex);
11821187
}
11831188

11841189
/**
@@ -2351,6 +2356,46 @@ int spi_async_locked(struct spi_device *spi, struct spi_message *message)
23512356
EXPORT_SYMBOL_GPL(spi_async_locked);
23522357

23532358

2359+
int 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+
}
2397+
EXPORT_SYMBOL_GPL(spi_flash_read);
2398+
23542399
/*-------------------------------------------------------------------------*/
23552400

23562401
/* Utility methods for SPI master protocol drivers, layered on

include/linux/spi/spi.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
struct dma_chan;
2626
struct spi_master;
2727
struct spi_transfer;
28+
struct spi_flash_read_message;
2829

2930
/*
3031
* INTERFACES between SPI master-side drivers and SPI infrastructure.
@@ -361,6 +362,8 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
361362
* @handle_err: the subsystem calls the driver to handle an error that occurs
362363
* in the generic implementation of transfer_one_message().
363364
* @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.
364367
* @cs_gpios: Array of GPIOs to use as chip select lines; one per CS
365368
* number. Any individual value may be -ENOENT for CS lines that
366369
* are not GPIOs (driven by the SPI controller itself).
@@ -513,6 +516,8 @@ struct spi_master {
513516
struct spi_message *message);
514517
int (*unprepare_message)(struct spi_master *master,
515518
struct spi_message *message);
519+
int (*spi_flash_read)(struct spi_device *spi,
520+
struct spi_flash_read_message *msg);
516521

517522
/*
518523
* 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)
10191024
return be16_to_cpu(result);
10201025
}
10211026

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+
10221063
/*---------------------------------------------------------------------------*/
10231064

10241065
/*

0 commit comments

Comments
 (0)