Skip to content

Commit cced7fd

Browse files
Tomasz BursztykaAnas Nashif
authored andcommitted
api/spi: Change transceive functions signature
Instead of NULL terminated buffer arrays, let's add a parameter for each that tells the number of spi_buf in it. It adds a little bit more complexity in driver's side (spi_context.h) but not on user side (bufer one has to take care of providing the NULL pointer at the end of the array, now he requires to give the count). This will saves a significant amount of bytes in more complex setup than the current dumb spi driver sample. Fix and Use size_t everywhere (spi_context.h was using u32_t). Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
1 parent 7d13261 commit cced7fd

File tree

4 files changed

+189
-131
lines changed

4 files changed

+189
-131
lines changed

drivers/spi/spi_context.h

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,15 @@ struct spi_context {
2929
struct k_poll_signal *signal;
3030
bool asynchronous;
3131
#endif
32-
const struct spi_buf **current_tx;
33-
struct spi_buf **current_rx;
32+
const struct spi_buf *current_tx;
33+
size_t tx_count;
34+
struct spi_buf *current_rx;
35+
size_t rx_count;
3436

3537
void *tx_buf;
36-
u32_t tx_len;
38+
size_t tx_len;
3739
void *rx_buf;
38-
u32_t rx_len;
40+
size_t rx_len;
3941
};
4042

4143
#define SPI_CONTEXT_INIT_LOCK(_data, _ctx_name) \
@@ -144,36 +146,40 @@ static inline void spi_context_cs_control(struct spi_context *ctx, bool on)
144146
}
145147

146148
static inline void spi_context_buffers_setup(struct spi_context *ctx,
147-
const struct spi_buf **tx_bufs,
148-
struct spi_buf **rx_bufs,
149+
const struct spi_buf *tx_bufs,
150+
size_t tx_count,
151+
struct spi_buf *rx_bufs,
152+
size_t rx_count,
149153
uint8_t dfs)
150154
{
151-
SYS_LOG_DBG("tx_bufs %p (%p) - rx_bufs %p (%p) - %u",
152-
tx_bufs, tx_bufs ? *tx_bufs : NULL,
153-
rx_bufs, rx_bufs ? *rx_bufs : NULL, dfs);
155+
SYS_LOG_DBG("tx_bufs %p (%zu) - rx_bufs %p (%zu) - %u",
156+
tx_bufs, tx_count, rx_bufs, rx_count, dfs);
154157

155158
ctx->current_tx = tx_bufs;
159+
ctx->tx_count = tx_count;
156160
ctx->current_rx = rx_bufs;
161+
ctx->rx_count = rx_count;
157162

158-
if (*tx_bufs) {
159-
ctx->tx_buf = (*tx_bufs)->buf;
160-
ctx->tx_len = (*tx_bufs)->len/dfs;
163+
if (tx_bufs) {
164+
ctx->tx_buf = tx_bufs->buf;
165+
ctx->tx_len = tx_bufs->len / dfs;
161166
} else {
162167
ctx->tx_buf = NULL;
163168
ctx->tx_len = 0;
164169
}
165170

166-
if (*rx_bufs) {
167-
ctx->rx_buf = (*rx_bufs)->buf;
168-
ctx->rx_len = (*rx_bufs)->len/dfs;
171+
if (rx_bufs) {
172+
ctx->rx_buf = rx_bufs->buf;
173+
ctx->rx_len = rx_bufs->len / dfs;
169174
} else {
170175
ctx->rx_buf = NULL;
171176
ctx->rx_len = 0;
172177
}
173178

174-
SYS_LOG_DBG("current_tx %p, current_rx %p,"
175-
" tx buf/len %p/%u, rx buf/len %p/%u",
176-
ctx->current_tx, ctx->current_rx,
179+
SYS_LOG_DBG("current_tx %p (%zu), current_rx %p (%zu),"
180+
" tx buf/len %p/%zu, rx buf/len %p/%zu",
181+
ctx->current_tx, ctx->tx_count,
182+
ctx->current_rx, ctx->rx_count,
177183
ctx->tx_buf, ctx->tx_len, ctx->rx_buf, ctx->rx_len);
178184
}
179185

@@ -187,17 +193,19 @@ void spi_context_update_tx(struct spi_context *ctx, uint8_t dfs)
187193
ctx->tx_len--;
188194
if (!ctx->tx_len) {
189195
ctx->current_tx++;
190-
if (*ctx->current_tx) {
191-
ctx->tx_buf = (*ctx->current_tx)->buf;
192-
ctx->tx_len = (*ctx->current_tx)->len/dfs;
196+
ctx->tx_count--;
197+
198+
if (ctx->tx_count) {
199+
ctx->tx_buf = ctx->current_tx->buf;
200+
ctx->tx_len = ctx->current_tx->len / dfs;
193201
} else {
194202
ctx->tx_buf = NULL;
195203
}
196204
} else if (ctx->tx_buf) {
197205
ctx->tx_buf += dfs;
198206
}
199207

200-
SYS_LOG_DBG("tx buf/len %p/%u", ctx->tx_buf, ctx->tx_len);
208+
SYS_LOG_DBG("tx buf/len %p/%zu", ctx->tx_buf, ctx->tx_len);
201209
}
202210

203211
static ALWAYS_INLINE
@@ -216,17 +224,19 @@ void spi_context_update_rx(struct spi_context *ctx, uint8_t dfs)
216224
ctx->rx_len--;
217225
if (!ctx->rx_len) {
218226
ctx->current_rx++;
219-
if (*ctx->current_rx) {
220-
ctx->rx_buf = (*ctx->current_rx)->buf;
221-
ctx->rx_len = (*ctx->current_rx)->len/dfs;
227+
ctx->rx_count--;
228+
229+
if (ctx->rx_count) {
230+
ctx->rx_buf = ctx->current_rx->buf;
231+
ctx->rx_len = ctx->current_rx->len / dfs;
222232
} else {
223233
ctx->rx_buf = NULL;
224234
}
225235
} else if (ctx->rx_buf) {
226236
ctx->rx_buf += dfs;
227237
}
228238

229-
SYS_LOG_DBG("rx buf/len %p/%u", ctx->rx_buf, ctx->rx_len);
239+
SYS_LOG_DBG("rx buf/len %p/%zu", ctx->rx_buf, ctx->rx_len);
230240
}
231241

232242
static ALWAYS_INLINE

drivers/spi/spi_dw.c

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,10 @@ static int spi_dw_configure(const struct spi_dw_config *info,
251251
}
252252

253253
static int transceive(struct spi_config *config,
254-
const struct spi_buf **tx_bufs,
255-
struct spi_buf **rx_bufs,
254+
const struct spi_buf *tx_bufs,
255+
size_t tx_count,
256+
struct spi_buf *rx_bufs,
257+
size_t rx_count,
256258
bool asynchronous,
257259
struct k_poll_signal *signal)
258260
{
@@ -277,7 +279,8 @@ static int transceive(struct spi_config *config,
277279
}
278280

279281
/* Set buffers info */
280-
spi_context_buffers_setup(&spi->ctx, tx_bufs, rx_bufs, spi->dfs);
282+
spi_context_buffers_setup(&spi->ctx, tx_bufs, tx_count,
283+
rx_bufs, rx_count, spi->dfs);
281284

282285
spi->fifo_diff = 0;
283286

@@ -317,23 +320,31 @@ static int transceive(struct spi_config *config,
317320
}
318321

319322
static int spi_dw_transceive(struct spi_config *config,
320-
const struct spi_buf **tx_bufs,
321-
struct spi_buf **rx_bufs)
323+
const struct spi_buf *tx_bufs,
324+
size_t tx_count,
325+
struct spi_buf *rx_bufs,
326+
size_t rx_count)
322327
{
323-
SYS_LOG_DBG("%p, %p, %p", config->dev, tx_bufs, rx_bufs);
328+
SYS_LOG_DBG("%p, %p (%zu), %p (%zu)",
329+
config->dev, tx_bufs, tx_count, rx_bufs, rx_count);
324330

325-
return transceive(config, tx_bufs, rx_bufs, false, NULL);
331+
return transceive(config, tx_bufs, tx_count,
332+
rx_bufs, rx_count, false, NULL);
326333
}
327334

328335
#ifdef CONFIG_POLL
329336
static int spi_dw_transceive_async(struct spi_config *config,
330-
const struct spi_buf **tx_bufs,
331-
struct spi_buf **rx_bufs,
337+
const struct spi_buf *tx_bufs,
338+
size_t tx_count,
339+
struct spi_buf *rx_bufs,
340+
size_t rx_count,
332341
struct k_poll_signal *async)
333342
{
334-
SYS_LOG_DBG("%p, %p, %p, %p", config->dev, tx_bufs, rx_bufs, async);
343+
SYS_LOG_DBG("%p, %p (%zu), %p (%zu), %p",
344+
config->dev, tx_bufs, tx_count, rx_bufs, rx_count, async);
335345

336-
return transceive(config, tx_bufs, rx_bufs, true, async);
346+
return transceive(config, tx_bufs, tx_count,
347+
rx_bufs, rx_count, true, async);
337348
}
338349
#endif /* CONFIG_POLL */
339350

include/spi.h

Lines changed: 53 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -190,17 +190,21 @@ struct spi_buf {
190190
* See spi_transceive() for argument descriptions
191191
*/
192192
typedef int (*spi_api_io)(struct spi_config *config,
193-
const struct spi_buf **tx_bufs,
194-
struct spi_buf **rx_bufs);
193+
const struct spi_buf *tx_bufs,
194+
size_t tx_count,
195+
struct spi_buf *rx_bufs,
196+
size_t rx_count);
195197

196198
/**
197199
* @typedef spi_api_io
198200
* @brief Callback API for asynchronous I/O
199201
* See spi_transceive_async() for argument descriptions
200202
*/
201203
typedef int (*spi_api_io_async)(struct spi_config *config,
202-
const struct spi_buf **tx_bufs,
203-
struct spi_buf **rx_bufs,
204+
const struct spi_buf *tx_bufs,
205+
size_t tx_count,
206+
struct spi_buf *rx_bufs,
207+
size_t rx_count,
204208
struct k_poll_signal *async);
205209

206210
/**
@@ -229,20 +233,24 @@ struct spi_driver_api {
229233
* Note: This function is synchronous.
230234
*
231235
* @param config Pointer to a valid spi_config structure instance.
232-
* @param tx_bufs NULL terminated buffer array where data to be sent
233-
* originates from, or NULL if none.
234-
* @param rx_bufs NULL terminated buffer array where data to be read
235-
* will be written to, or NULL if none.
236+
* @param tx_bufs Buffer array where data to be sent originates from,
237+
* or NULL if none.
238+
* @param tx_count Number of element in the tx_bufs array.
239+
* @param rx_bufs Buffer array where data to be read will be written to,
240+
* or NULL if none.
241+
* @param rx_count Number of element in the rx_bufs array.
236242
*
237243
* @retval 0 If successful, negative errno code otherwise.
238244
*/
239245
static inline int spi_transceive(struct spi_config *config,
240-
const struct spi_buf **tx_bufs,
241-
struct spi_buf **rx_bufs)
246+
const struct spi_buf *tx_bufs,
247+
size_t tx_count,
248+
struct spi_buf *rx_bufs,
249+
size_t rx_count)
242250
{
243251
const struct spi_driver_api *api = config->dev->driver_api;
244252

245-
return api->transceive(config, tx_bufs, rx_bufs);
253+
return api->transceive(config, tx_bufs, tx_count, rx_bufs, rx_count);
246254
}
247255

248256
/**
@@ -251,17 +259,18 @@ static inline int spi_transceive(struct spi_config *config,
251259
* Note: This function is synchronous.
252260
*
253261
* @param config Pointer to a valid spi_config structure instance.
254-
* @param rx_bufs NULL terminated buffer array where data to be read
255-
* will be written to.
262+
* @param rx_bufs Buffer array where data to be read will be written to.
263+
* @param rx_count Number of element in the rx_bufs array.
256264
*
257265
* @retval 0 If successful, negative errno code otherwise.
258266
*/
259267
static inline int spi_read(struct spi_config *config,
260-
struct spi_buf **rx_bufs)
268+
struct spi_buf *rx_bufs,
269+
size_t rx_count)
261270
{
262271
const struct spi_driver_api *api = config->dev->driver_api;
263272

264-
return api->transceive(config, NULL, rx_bufs);
273+
return api->transceive(config, NULL, 0, rx_bufs, rx_count);
265274
}
266275

267276
/**
@@ -270,17 +279,18 @@ static inline int spi_read(struct spi_config *config,
270279
* Note: This function is synchronous.
271280
*
272281
* @param config Pointer to a valid spi_config structure instance.
273-
* @param tx_bufs NULL terminated buffer array where data to be sent
274-
* originates from.
282+
* @param tx_bufs Buffer array where data to be sent originates from.
283+
* @param tx_count Number of element in the tx_bufs array.
275284
*
276285
* @retval 0 If successful, negative errno code otherwise.
277286
*/
278287
static inline int spi_write(struct spi_config *config,
279-
const struct spi_buf **tx_bufs)
288+
const struct spi_buf *tx_bufs,
289+
size_t tx_count)
280290
{
281291
const struct spi_driver_api *api = config->dev->driver_api;
282292

283-
return api->transceive(config, tx_bufs, NULL);
293+
return api->transceive(config, tx_bufs, tx_count, NULL, 0);
284294
}
285295

286296
#ifdef CONFIG_POLL
@@ -290,10 +300,12 @@ static inline int spi_write(struct spi_config *config,
290300
* Note: This function is asynchronous.
291301
*
292302
* @param config Pointer to a valid spi_config structure instance.
293-
* @param tx_bufs NULL terminated buffer array where data to be sent
294-
* originates from, or NULL if none.
295-
* @param rx_bufs NULL terminated buffer array where data to be read
296-
* will be written to, or NULL if none.
303+
* @param tx_bufs Buffer array where data to be sent originates from,
304+
* or NULL if none.
305+
* @param tx_count Number of element in the tx_bufs array.
306+
* @param rx_bufs Buffer array where data to be read will be written to,
307+
* or NULL if none.
308+
* @param rx_count Number of element in the rx_bufs array.
297309
* @param async A pointer to a valid and ready to be signaled
298310
* struct k_poll_signal. (Note: if NULL this function will not
299311
* notify the end of the transaction, and whether it went
@@ -302,13 +314,16 @@ static inline int spi_write(struct spi_config *config,
302314
* @retval 0 If successful, negative errno code otherwise.
303315
*/
304316
static inline int spi_transceive_async(struct spi_config *config,
305-
const struct spi_buf **tx_bufs,
306-
struct spi_buf **rx_bufs,
317+
const struct spi_buf *tx_bufs,
318+
size_t tx_count,
319+
struct spi_buf *rx_bufs,
320+
size_t rx_count,
307321
struct k_poll_signal *async)
308322
{
309323
const struct spi_driver_api *api = config->dev->driver_api;
310324

311-
return api->transceive_async(config, tx_bufs, rx_bufs, async);
325+
return api->transceive_async(config, tx_bufs, tx_count,
326+
rx_bufs, rx_count, async);
312327
}
313328

314329
/**
@@ -317,8 +332,8 @@ static inline int spi_transceive_async(struct spi_config *config,
317332
* Note: This function is asynchronous.
318333
*
319334
* @param config Pointer to a valid spi_config structure instance.
320-
* @param rx_bufs NULL terminated buffer array where data to be read
321-
* will be written to.
335+
* @param rx_bufs Buffer array where data to be read will be written to.
336+
* @param rx_count Number of element in the rx_bufs array.
322337
* @param async A pointer to a valid and ready to be signaled
323338
* struct k_poll_signal. (Note: if NULL this function will not
324339
* notify the end of the transaction, and whether it went
@@ -327,12 +342,14 @@ static inline int spi_transceive_async(struct spi_config *config,
327342
* @retval 0 If successful, negative errno code otherwise.
328343
*/
329344
static inline int spi_read_async(struct spi_config *config,
330-
struct spi_buf **rx_bufs,
345+
struct spi_buf *rx_bufs,
346+
size_t rx_count,
331347
struct k_poll_signal *async)
332348
{
333349
const struct spi_driver_api *api = config->dev->driver_api;
334350

335-
return api->transceive_async(config, NULL, rx_bufs, async);
351+
return api->transceive_async(config, NULL, 0,
352+
rx_bufs, rx_count, async);
336353
}
337354

338355
/**
@@ -341,8 +358,8 @@ static inline int spi_read_async(struct spi_config *config,
341358
* Note: This function is asynchronous.
342359
*
343360
* @param config Pointer to a valid spi_config structure instance.
344-
* @param tx_bufs NULL terminated buffer array where data to be sent
345-
* originates from.
361+
* @param tx_bufs Buffer array where data to be sent originates from.
362+
* @param tx_count Number of element in the tx_bufs array.
346363
* @param async A pointer to a valid and ready to be signaled
347364
* struct k_poll_signal. (Note: if NULL this function will not
348365
* notify the end of the transaction, and whether it went
@@ -351,12 +368,14 @@ static inline int spi_read_async(struct spi_config *config,
351368
* @retval 0 If successful, negative errno code otherwise.
352369
*/
353370
static inline int spi_write_async(struct spi_config *config,
354-
const struct spi_buf **tx_bufs,
371+
const struct spi_buf *tx_bufs,
372+
size_t tx_count,
355373
struct k_poll_signal *async)
356374
{
357375
const struct spi_driver_api *api = config->dev->driver_api;
358376

359-
return api->transceive_async(config, tx_bufs, NULL, async);
377+
return api->transceive_async(config, tx_bufs, tx_count,
378+
NULL, 0, async);
360379
}
361380
#endif /* CONFIG_POLL */
362381

0 commit comments

Comments
 (0)