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